-
Posts
1,824 -
Joined
-
Last visited
-
Days Won
83
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by Daklu
-
Well heck, if we all vote for each other's ideas all our ideas will float to the top and LAVA will be defining the future of Labview.
-
Annoying? I'll bet you've spent more time typing up the response than it would take to implement it. It's really simple and once you set it up (taking all of 2 minutes) it's transparent during package install and uninstall. Save this vi as MoveToOsdatadir.vi to the same place as your .ogpb file. Swap the constants and save another vi as MoveFromOsdatadir.vi. On the OpenG Package Builder 'Script VIs' tab, type 'MoveToOsdatadir.vi' in the PostInstall VI path dialog box and 'MoveFromOsdatadir.vi' in the PreUninstall VI path dialog box. Done. Build the package and install it.
-
It turns out the answer is yes. The class diagram I drew up for Ton is a textbook Strategy Pattern. Apparently Strategy shares topology with the Bridge pattern, the difference being Bridge "allows you to vary the implementation and the abstraction by placing the two in separate class hierarchies." (Head First Design Patterns p.613) How does that distinction affect implementation? I have no idea. I'm willing to be enlightened if anyone has a clue. [cheek.insert(tongue)] You're thinking about this all wrong. You were subconciously applying the idea to an environment (run-time) the authors not only didn't intend, but didn't even anticipate that anyone would attempt, hence none of them ever bothered to explain it is a compile time event. You're thinking outside the box which is a sign of creativity and intelligence. (And ADD too. ) If it would have taken you 20 years to figure it out you would be super smart!
-
Joe, you're mixing namespaces with library membership. Perfectly understandable as Labview defines namespaces by library membership, but the concepts serve different purposes and hopefully the day will come when users can define their own namespaces. (I've blown the namespace horn enough I'm sure AQ is quite tired of hearning it.) Hmm... dynamic namespaces determined at run-time? Interesting concept, although I admit I don't see what problem this is attempting to solve. Allowing a vi to be exposed via multiple namespaces... I'm right there with you. That's the whole point. With user-defined namespaces collisions are less likely to happen and when they do they are easier to resolve.
-
Questions: What happens if the class can't find the xcontrol? Is the class broken? Or, since the xcontrol is essentially a window into the class data, does the fp representation default to the cube? If that's the case, considering that the xcontrol isn't a class member, doesn't it violate the classes private data? Is the intended use case for the class designer to implement and deploy xcontrols with the class or to leave that to the class users? I voted for the idea in spite of my questions; I trust AQ to take LVOOP in the right direction.
-
By popular demand1, I have reattached the Exterface Architecture example following the LAVA meltdown of 2009. The project is saved in 8.6. Be sure to review the readme files in the various project folders; they will help explain what parts of the project I consider part of the application, which parts are Exterface framework, and which parts are there simply to enable the demo to run. There is a first draft document in Word format that gives a broader explanation of what I was trying to accomplish. I also created this UML class diagram that hopefully helps explain what I did. In the months since I created this I've discovered this idea is essentially an implementation of the adapter pattern. The top diagram2 illustrates the adapter pattern. The bottom diagram shows the Exterface Architecture in the context of the adapter pattern. The blue blocks are the components I added to compensate for the lack of object references in LV8.6. I have a couple other implementations I've been working on that also enable Interface-like behavior. I don't yet have a good feel for they stack up against each other but my sense is this will be the most restrictive. With the release of object references in 2009 I suspect this model can be simplified using DVRs. Dave 1 Popular demand = 1 person 2 Model shameless copied from Head First Design Patterns and recreated in StarUML. Exterface Architecture.zip
-
I haven't worked out all the repro cases, but when I responded on this thread I had to escape the backslash characters (two backslashes) for the path to show up correctly. (I may have used the Fast Reply... I don't remember.) Not a big deal, but when I edited the post the escaped backslashes were converted into regular backslashes (one backslash) in the edit dialog box. Unless I went through and re-added the second backslash the paths wouldn't be displayed correctly in the edited post.
-
Great idea! I don't have any tested solutions to the problem--here are a couple ideas for workarounds: Typing the symbolic path directly into the Group Target Directory path box rather than using the drop down box. (I doubt this will work but it's the first thing I would try.) I believe the default <temp> directory in Vista is a subdirectory of <osdatadir>. Entering a relative path from there might work as long as your users use Vista and don't change the defaults. Have the package deploy them to <temp>\Icon Templates\[my folder structure etc...] and write a post install script that moves them to <osdatadir>\Icon Templates\[my folder structure etc...]. You'd also need a preuninstall script to move them back. This should be pretty straight forward. Since the package installation is handled by VIPM it might be possible to edit the package spec file manually to install the files to <osdatadir>.
-
There's something going on in the IDE I don't understand. Suppose I have a Base class, a Child class, a composite of the Base class, and a composite of the Child class. If I make a change in the base class that requires a recompile, such as adding a private data member, Base class and Child class objects on block diagrams are dimmed. I've always thought this essentially means Labview can't execute this code until that file is saved (or has its changes applied.) If that's not the case, what is the significance of dimmed objects? Dimming the child class suggests a tighter coupling between the Base and the Child than between the Base and the Composite Base. The reason for the question is I have packages that will expose abstract classes which other packages will use to derive their own classes and objects. I can save a lot of duplicate code if I include some functionality and private data in the abstract class, but I don't want get bogged down in package-dependent recompiles when I change its private functionality. (This applies to both the runtime engine and the IDE.) I was considering making the exposed base classes purely abstract just to make sure I wouldn't have to change it, but it sounds like there's nothing to gain by doing so. Correct?
-
LV2009 Data Value References should be used SPARINGLY
Daklu replied to Aristos Queue's topic in Object-Oriented Programming
Nope. It's all about choosing a communication method that best illustrates the idea one is presenting. The time it takes to model your idea is one of the factors in determining the best communication method. I figure maybe 10 seconds for Yair to type that in. I know I couldn't create a deadlock situation in Labview and get it uploaded to my post in 10 seconds without a lot of practice. If you also consider that illustrating a deadlock in Labview requires more ancillary stuff that complicates the model, the choice of text pseudocode is clearly the right one. What I find interesting is that his use of pseudocode struck you as interesting. Is it possible you've been enjoying NI Week a bit too much? I assume this comment is intended to spawn some discussion as I can't imagine NI removing references from Labview. No queues, no property or invoke nodes, no scripting... there would be chaos in the streets! ("Dogs and cats living together...") Anyway, I'll discuss. References do not exist in a 'pure' data flow language (as I understand the term.) Labview is not a pure data flow language; it is a language based on data flow. Data flow is great for certain types of programs but there are lots of things you can't do without violating it, such as passing information between parallel loops. Labview must expose references if NI wants its usefulness to grow. The way I see it, Labview has an extremely good high-level api. We see it in every demo where data is acquired and plotted in 10 seconds of programming. It also has a good low-level api. Lots of useful frameworks can be built using the existing references. (Queues, vi server, etc.) Where Labview suffers is in the mid-level api. That's why people have spent so much time building the various OOP frameworks or trying to figure out how to compensate for the lack of native Interfaces. Giving us the DVR is defninitely a step in the right direction. NI just obsoleted a bunch of home-rolled frameworks designed to provide the same functionality. Hopefully NI will continue to fill out the mid level api so we can focus on building applications instead of frameworks. (Although I find designing frameworks far more interesting than designing applications.) -
One of the benefits of using interfaces (or abstract classes) in code packages with text languages is that as long as you don't mess with the interface you won't have to recompile the code that depends on that package. Labview's just-in-time compiler allows us to ignore recompiles; however, hiding them under the covers also prevents me from learning how much JIT compiling impacts performance and exactly what circumstances require a recompile. In particular, the scenario I'm imagining is one with a large, multi-package reusable code base where there are various dependencies (inheritance, composition, references, etc.) between packages and the packages are released/updated on different schedules. I've run a few very simple tests, but I can't think of any way to test this at a large scale without actually building a a bunch of packages. Along these lines, I have a few questions: What's the best way to minimize the time spent doing JIT recompiles when starting an application that uses those packages? Do we know which types of dependencies are 'clean' and which are 'dirty?' For example, package A can depend on package B, but if the only interaction they have is through a string-based messages it's unlikely changing B will trigger a recompile in A. On the other hand, if package A inherits from a class in package B, changes in B are more likely to require a recompile in A. What if A contains B as data? What if A contains a reference to B as data? What if A member vis have B constants on the block diagram? What if A member vis use B member vis on their block diagram? Does JIT compiling have a practical impact on load times or am I splitting hairs? Dave
-
Sydney, I opened up your example and the first thing I read was, "Trying to figure out how to use the same type def'd enums for an FSM state enum and the tabbed pages enum." I don't think you want to do this even if you can figure out how to. It will needlessly couple your user interface to the underlying code and introduce a lot of complexity. I would address this issue in two ways. First, I would create a translator vi that accepts the FSM state as an input and outputs the tab that should be shown when in that state. This keeps all your state->tab code in one place and makes it easier to change in the future. Second, create a typedef from an empty tab control and use that typedef in your translator vi. When you add a page to the typedef all the constants inside the translator vi are automatically updated. Note the tab typedef is simply to provide a way to automatically update the constants inside the translator vi. You can't put controls on a tab inside a typedef so the UI tab control is different from the typedeffed tab control. You do have to be careful to keep your page names on the UI tab consistent with the page names on the typedeffed tab, otherwise LV can't coerce from one to the other. HTH Dave Sydney 8.6.zip
-
Yes, yes, yes, yes... and yes. Renaming the Ctl-Space hotkey combo from Quick Drop to something like 'User Hotkeys' might help. Now User Hotkeys can invoke two different types of functionalities: Quick Drop (using normal alphanumerics) and Quick Run (using a Ctl key combo.) That's what I do in my head anyway and it all makes sense to me.
-
Me too. There's nothing quite like reinventing the wheel. The thrill of the discovery followed by the realization that not only has someone already invented it, but they did it better than you did. Good point. There seems to be a lot of subtleties in the jargon. I'm becoming more and more convinced OO design is something you have to learn by doing it and experiencing all the pitfalls associated with your design decisions. Learning the patterns certainly is necessary... learning which pattern (or pattern variation) to use in certain situations requires a deeper understanding of how the pattern implementation will affect your particular application. In any event, I'm glad Ton posted the question. I wish there was more OO design related discussion here.
-
If I'm understanding you correctly, what you're describing is the same as the first diagram in my post above, which I agree uses delegation. My comment to AQ was simply to point out that the pattern as described in the article doesn't directly address Ton's problem and it's hard for OOP noobs (especially LVOOP noobs, who often have little formal programming training) to see the various ways delegation can be used to solve problems. If the article were expanded a bit in its description of that pattern it would be much more helpful. If you look at the LV example referred to in the article it uses delegation in two classes with LV:Object as the common ancestor; however, the class that is delegated to is a concrete class, not an abstract base class. It's having the implementation in the delegate child classes that provides Ton with the flexibility he needs. Does pointing to an abstract base class justify a different pattern name? <*shrug*> I dunno. Several patterns are variations of other patterns, but I'll leave that question to those smarter than me. Dave [Edit] How is a composite class different from a facade?
-
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.)
-
New QuickDrop shortcuts not working
Daklu replied to Shaun Hayward's topic in Development Environment (IDE)
Plugins? So could I create a z.vi, drop it in that directory, and create my own customized hotkey functions? -
That is much clearer. Thanks for posting Chris! (Eli too!)
-
I agree placing them as part of the quickdrop function is odd decision, but in practice I think it works really well. Right click menus are best for a small group of commonly used functions. Personally I think NI overused the right click menu. It's overcrowded and as a result uses cascading flyout menus. Navigating these require too many consecutive precise mouse movements. And if you have to use multiple functions from the same nested menu... grr... Hotkeys are faster than mouse clicks for most people. I just have a hotkey accessor method to get to the 'special' hotkeys.
-
Class references... woo hoo! (Although apparently you still can't have two classes reference each other... odd.) Friend classes... woo hoo! (Already has been much more useful than I expected.) Must override... woo hoo! (Eliminates an error message and frees up error code 5000. ) New icon builder... woo hoo! (Haven't quite figured out the templates...) Quick drop shortcuts... woo hoo! (Ctl-T to move block diagram labels to the sides, Ctl-D create and wire controls and indicators of a selected sub vi, and a few others I don't remember.) These are the main things I've discovered so far. The last two items in particular have noticably increased my coding speed. On the downside, it does seem to be somewhat less stable than 8.6. I had several crashes yesterday. Still, the new additions more than make up for that. As a side note, the splash screen was due for an update and the new one looks much more professional. Kudos to whoever designed it.
-
I was reading through one of NI's documents where they discussed code coverage. Here's a diagram from the article: How in the world does someone look at that and claim they have 50% code coverage? I look at that and see that at best you've got 40% coverage. 16% if you're measuring execution paths instead of executed code. What gives?
-
If you're willing to go rogue there are ways around group policy settings. Sometimes IT forgets they're a service and supposed to help employees get work done. A minor revolution can sometimes break the iron grip of an over-controlling AV nerd. (Power to the people!)
-
Re:Byref objects I'm shocked NI is pursuing any aspect of this, and then to learn my dreams are too limited... Re:Interfaces I didn't expect it to be released this year, but I still hold out hope that it is something you are actively developing. (And your post hints that you are.) Re:Constructors/Destructors In truth I'll settle for whatever I can get. Like the byref objects I'm surprised and excited we're getting anything here. The main changes I would like to see in namespacing are: Decoupling the namespace from the filename and allowing the library author to define its namespace. (No more name mangling!) Allowing a library to be exposed through multiple namespaces. This provides a migration path for resolving namespace conflicts in legacy code. Having the ability to nest namespaces. This helps prevent namespace conflicts in the future. Multiple libraries sharing the same namespace isn't necessary for my use case and off the top of my head I think it introduces more problems than it solves. I hope for lots of things... disappointment and I are well acquainted. Not so much that as a way to organize and avoid namespace conflicts with all the different reusable code modules that we have now and will develop in the future. That too. Think .NET namespaces. I can hardly wait for Christmas morning. Not I, but hopefully one of the Lava tweet providers will. (And maybe the presentation will be available for download afterwards?) Interfaces address the same problems multiple inheritance does, but does so in a cleaner way IMO. Based on a previous post by AQ, I'm 99% sure you won't be disappointed.
-
Excellent points on both counts and a reminder (again) that everyone has different ways of using Labview.