Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/05/2009 in all areas

  1. In LV 2009... If you want to add customizations to the new VIs that are created by New>>VI For Override and New>>VI For Data Member Access, you can open and edit these three VIs. These VIs are called at the end of their respective scripting processes and you are free to include any scripting code you wish to further customize the VI in question. Some common customizations you might want include changing the VI name (use "get" and "set" instead of "read" and "write"), modifying the icon, adding additional diagram logic, etc. You cannot edit the callers of these three VIs, but these three provide the hook you need to customize your new VIs as you want them. Customizations for Override VIs: <labview>\resource\Framework\Providers\LVClassLibrary\NewAccessors\OverrideRetooler\Custom User Scripting For New Override VI.vi Customizations for basic accessor VIs: <labview>:\resource\Framework\Providers\LVClassLibrary\NewAccessors\BaseAccessorScripter\Custom User Scripting For New Simple Accessor VI.vi Customizations for 1D Array element accessor VIs: <labview>resource\Framework\Providers\LVClassLibrary\NewAccessors\ArrayElementScripter\Custom User Scripting For New Array Element Accessor VI.vi Customizations for multi-dim array element accessor VIs: <labview>\resource\Framework\Providers\LVClassLibrary\NewAccessors\MultiDimArrElemScripter\Custom User Scripting For New MultiDim Array Element Accessor VI.vi This is for the various LAVA folks who asked these scripting hooks be added.
    3 points
  2. Ton, While the ideas of OO programming are pretty straightforward, actually designing a good OO architecture is quite difficult. Newcomers (and I include myself in this group) overuse inheritance, underuse abstract classes, and tend to develop a class hierarchy that is very difficult to modify and maintain. The kind of stuff you're trying to do is why I think getting interfaces in Labview is so important to LVOOP. (And why I keep talking about them.) The hierarchy you posted isn't going to work very well. The exact design depends a lot on the requirements of the application you are building--especially with respect to what changes might be required in the future. Here's a diagram I put together that I believe will give you more flexibility. It's just a starting point; modify it to fit your requirements. [Quick UML explanation for those unfamiliar with it] Each block represents one class with the top section containing the class name in bold. The middle section is the private data contained in the class. The bottom section lists the class methods (member VIs.) Italicised names indicate an abstract class (BaseGPS) or function (SaveData). Non-italicised names indicate a concrete implementation. The arrow with the hollow triangle indicates inheritance. (Garmin inherits from BaseGPS.) The line with the solid diamond indicates composition, meaning one class contains another class as private data. (The BaseGPS class has a BaseHWComm class as a member of its private data.) [/uML explanation] Notice the linking between the three different class sets is always through the abstract classes. This helps maintain modularity and flexibility. For example, if you need to implement wireless communication in a future product, you simply derive a new child class ("802.11g") from BaseHWComm, modify BaseHWComm:CreateNew.vi to accomodate the new class, and you're good to go. (Mostly... it depends on exactly how you use the HWComm functionality in BaseGPS.) Also note that your coding is primarily done using abstract class methods, not the concrete class methods. For example, in your application all your GPS functionality is built using VIs from BaseGPS. In your Garmin and TomTom classes you use VIs from BasePersistData and BaseHWComm, not the child classes. There are drawbacks to this design: If you want to expose any of the methods from BasePersistData or BaseHWComm you essentially have to wrap a BaseGPS method around them. This is extra coding that in a perfect world wouldn't be necessary. If your class has a lot of classes as private data it can mean a lot extra VIs that clutter up the BaseGPS API. It can also potentially lead to naming confusion if more than one class uses the same name for member VIs. As it turns out, just this last weekend I prototyped a framework for LV8.6 that implements interfaces in a way that more closely matches other languages. I also have a LV2009 design on paper that comes even closer... I think it will work but I haven't implemented it yet. I'm planning on writing them up and posting it soon. I don't think this makes sense from an OO point of view. USB and Serial are used by GPS, they are not subsets of GPS. I found this link a while back and the articles really solidified my understanding of what my OO designs were missing. Especially the Dependency Inversion Principle and the Walking Through a UML Design case study. In that document the delegate pattern says, "This pattern applies best when you have a dynamic VI inherited from some ancestor and two descendent classes want to override that dynamic VI with exactly the same implementation. Delegation helps you avoid writing the implementation twice, once for each of the two classes." This is the way I see the pattern described in the article. Delegating functionality is very common in OO architectures, but the Delegate Pattern described in the article addresses the specific problem of avoiding having to duplicate code in similar child classes. That seems to me to be a different problem than the one Ton described. I recognize that the diagram I put together could be considered a slightly more complicated version of the Delgate Pattern, but it's a mighty big leap from point A to point B for us noobs. (If you ever get around to revising that article I suggest putting in some simple UML diagrams to help explain the patterns.)
    2 points
  3. I've been playing some more with LVOOP 2009 I've been working on implementing active objects into the framework I posted earlier. An active object has its own process which is spawned when its instantiated. Active objects are useful if you want your object to have time dependent characteristics such as a pump controller. You can imagine that with an ordinary pump you can turn it on or off, but what about PumpVolume? You wouldn't want your PumpVolume method to hold execution while it turns the pump on, waits and then turns it off, instead a better way is if your PumpVolume method messaged to a process that handled this operation. Attached is a demo that instantiates two pumps to demonstrate Active Objects and that each instance has its own process. LVOOP2009_ActiveObj.zip
    1 point
  4. No problem. [watch] (few other simulations included in this movie) It grew up into quite serious real time dynamics simulator with Euler integration scheme, non-linear spring equations, collision engine, independent display and calculation rates... Few details for those wanting to play little bit (performance is much better than in previous version): Only Nodes and Terminals may be movable (in terms of LV class hierarchy) - so no constants and no flat sequences Masses are proportional to object size and scaled with "Mass ratio" parameter - do not set it to 0 "force factor" scales wires elasticity Damping is applied to wires only (not to bouncing). Very high damping will make wires almost stiff Gravity is in pixels/s^2. y axis points down dt is integration step size in seconds. Fractions of seconds make sense. Smaller is (almost) always better - particularly for collisions fps is display only frame rate Have fun spring-wires2.zip
    1 point
  5. You can consider the 64 vs 32 bit application similar to building an app on Windows that will run on Mac. Essentially we would need to have the ability to cross compile VIs for a different OS (in this case bitness being the difference). I am not aware if there are plans to support building for the different OS's.
    1 point
  6. Am I the only one who thinks this is really stupid? Not because of the shortcuts themselves. They're useful. The problem is with placing them in QD. W. T. F. !. This is the kind of thing that would be ideal in something like the right-click framework - select something, operate on it. Why is it in QD? Obviously the answer is simple - someone wanted it and didn't have anywhere else to put it which would make it easily accessible, but I find this to be totally unrelated to the QD functionality and very undiscoverable.
    1 point
  7. One of the main differences is that there are very few support VIs needed (as compared to other by ref patterns) when you are using DVR LVOOP (namely you'll want a constructor and destructor for each class, including descendants). Also, prior to DVR LOOP, most patterns used LVOOP as a wrapper around a reference (e.g. Queue) to data. With DVR LVOOP, this gets flipped on its head -- you have a reference wrapper around an LVOOP object. This is the first thing that really strikes you as different and unintuitive, but once you start using it you'll see that it makes a lot of sense (and, of course, you see some areas where things still need to be further improved). Dynamic dispatch only works on by value methods, not by reference methods. It would be nice if you could pass a reference into a by value method and LabVIEW would dereference and rereference behind the scenes. So, you'll find some duplication is required if you want users of your by reference class to call into by reference methods. You'll need to decide whether you want your users to 1) dereference/rereference the data themselves and then call your class' by value methods or 2) have a by reference method in your base class that calls the by value method. Also, it would be nice if you could wire a DVR LVOOP object into a Bundle by Name and Unbundle by Name and have LabVIEW automagically dereference/rereference the data behind the scenes. Right now, when you want to just get a value of an element of a DVR LVOOP object, you have to use an Unbundle by Name inside an In Place Element Structure. This is too much work for the programmer and makes the code look unnecessarily sloppy. The programmer's tendency will be to create a non-locking Get/Preview data method, but this isn't a great idea, because it makes a complete copy of the data -- by using an IPE Structure with an Unbundle by Name inside, you only copy the element. Those are the main things I've noticed. The bottom line is that if you do by ref LVOOP this way, you're going with the grain and you'll find things to be much easier now and in the future as more native features and usability improvements get added to DVR+LVOOP. Oh, one more thing that I noticed is that edit-time performance seems much better, which is probably due to a combination of: performance improvements in the LabVIEW IDE, WRT projects/classes/etc. fewer support VIs in the by ref classes
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.