-
Posts
3,183 -
Joined
-
Last visited
-
Days Won
204
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by Aristos Queue
-
bsvingen: Please keep a log of where your biggest time sinks are. The team is already aware of the gigantic sucking pit of time needed to edit icons, even if you're just doing text, and we have a way to fix some of that. Further, we know about the need for automatic (scripting) creation of get/set methods for member fields. C++ has more syntax when classes get involved than plain C. It seems like most languages have this overhead compared to their non-class counterparts. With the graphical environment, we need to log what the biggest sinks are and try to provide the needed shortcuts. Glad to hear that the LV2OO idea is working out for you. What I posted is a first attempt -- I've had the implementation for a long time, but I didn't have time to really clean it up or consider ways that it might be augmented.
-
The time is now? The place is your harddrive? Seriously though -- as much of an OOP advocate as I am, I agree. If you're building an app that isn't going to be used but once, or if you're just setting up to take a quick DAQ measurement, or any of a number of low level function VIs, you shouldn't be setting up a class. Too much work for too little return. OOP comes into play when: * the app will be maintained and revised over time * multiple developers are working concurrently on the app * one developer develops, then hands off ownership to another developer * the app is going to be bigger than some threshold, probably somewhere around 10 VIs, or whatever point it is that you can't hold the whole app in your mind simultaneously and need some structure to keep it together. That having been said... OO Programming is not the same as OO Design. And OO Design is eternal and universal.
-
I don't understand your question. What exactly is the difference between "flatten data" and whatever it is you think NI has access to? I'm not trying to be difficult, but I'm not sure what optimization you see. "This could mean that to access only one attribute, LabVIEW still have to unflatten the complete structure?" When LV unflattens a string of data, it knows the type of the data because you wire a type descriptor to the input of Unflatten From String. With LV Classes if you wire a type descriptor of Parent, the data could be of type Child. This is perfectly legitimate. If, however, Child.lvclass is not in memory, then how can LV unflatten it? LV has no idea what Child.lvclass looks like -- its a data type that a user created. In fact, there may be many Child.lvcass files on disk. Which one did you intend? So, yes, we have to have the definition of the structure in order to access any element of that structure. That's why I'm confused about post. I'm happy to address the point (and maybe update the Design Decisions document) but I'm not sure what needs addressing. Actually, it suggests the need for about a bijillion different flavors of reentrancy. Or at least a consistent view of what "reentrancy" means. ;-) And that is part of why it isn't in this release -- it turned into a deep deep pit of issues, options and conflicting use cases. Wire level reentrancy poses some serious problems. Let's take the issue of Custom Probes -- just to pick one. If the data goes down the wire, do you want a copy of your data going into the Probe (because it is going to be there after the execution continues past the probe) to be allocating new data spaces? There's some serious negatives for performance if you do, and some serious impact possible on the actual functionality of your VI if you do (because then running a custom probe would modify data). Another issue: Should the reentrant dataspaces remain in controls after the VI finishes running? That would mean that as long as there's data of the class, you couldn't edit any of the reentrant VIs. That would be a serious problem. Or do we need to save off the current run state of every member VI for every class instance every time a VI goes idle and then restore that running state (uninitialzied shift registers and all) when you hit the run button or use Value property to get that value into another running VI? Wire level reentrancy gets very icky very quickly. I don't like dumping on this idea, but it really is nearly unworkable. Once I really sat down and asked "what would it mean to have a VI dataspace associated with each object?", I ended up with many conflicting cases, which lead to unpredictable behavior. I think that wire level reentrancy is a fun idea that isn't really needed: if an object needs to store all of its data in itself, not storing it in local variables and uninitialized shift registers of member VIs, then it can initialze any shift registers that need to be "per object" whenever that method executes. Something needs to be done to support reentrancy with classes. No doubt about that. But I don't think that wire level is going to work.
-
The LV classes are completely independent of the project that you used to construct them. You can load the same classes into multiple projects simultaneously (just as you can with VIs) and you can load VIs that use those classes without opening any project at all. The project is just a listing of files and how you're using them. Unless you're using targets (FPGA, RT, etc) I don't think any information is uniquely stored in the project file. The project does store the deployment information for the targets, ie. which VIs get downloaded to which target. The storage of relationship information about the class and the definition of the class is entirely in the .lvclass file.
-
LabVOOP Design Patterns, v1.0
Aristos Queue replied to Aristos Queue's topic in Object-Oriented Programming
The PDF is what you just asked for -- name, verbal description, image, link to example code, editorial comments. it's the best I've been able to pull together thus far. The patterns I've included are reasonably sound concept wise for LV... its the implementations that are questionable. The UML component, for example, will be hard to stabilize for some time, thus I didn't even attempt it in this draft. If you're looking for discussion about each individual pattern, I didn't think it was worth, at this point, starting a separate discussion forum for each one. You can do so if you think it's worth it. -
Sounds like a good design. By the way, under the hood the queues are a very efficient circular in-memory buffer. They don't do any data copies when enqueing and dequeing unless you fork the wire to take the data elsewhere on the diagram (and even then only if the "elsewhere" is a function that will modify the value).
-
If you have LV8.2, I offer a new twist on an old idea. You've heard of LV2-style globals? If not, go search LV's online help for "functional global variables." They're very useful and dataflow safe. For everyone else: I've put together what I'm calling a LV2OO-style global*. I'm not convinced that this implementation is ideal, but I want to get some conversation going about the possibilities. Basically, I suggest that classes make it possible to build a single LV2 functional global that doesn't need to be rewritten for every use, among other advantages. :!: Download LV2OO Prototype If you download and unzip this, open the project file and then open the top VI in the project (the only one not in a folder). Comments explaining what's going on are on the FP and BD. Many of the ideas discussed in this LAVA thread about references could apply to the LV2OO-style global. I'm interested to see what comes out of the brainstorm. This is just a prototype, so there may be rough edges. * LV2OO : As in "LV2 Object-Oriented".
-
I've posted a document on my personal website on the topic of LabVOOP Design Patterns. Here's a bit from the introduction to let you decide whether you want to dive into the whole document. Feedback is welcome. Eventually I'd like to put this up on DevZone, after it has a bit of polish, but it has not been reviewed by any tech writers yet. When talking about computer programming, a design pattern is a standard correct way to organize your code. When trying to achieve some particular result, you look to the standard design patterns first to see if a solution already exists. This sounds a lot like an algorithm. An algorithm is a specific sequence of steps to take to calculate some result from a set of data. Generally algorithms can be written once in any given programming language and then reused over and over again. Design patterns are rewritten over and over again. For example, in house cleaning, consider this algorithm for vacuuming a carpet:
-
Trees, Recursion, Reentrancy & LVOOP
Aristos Queue replied to LAVA 1.0 Content's topic in Object-Oriented Programming
Ok... new idea: A variation on the "Vistior" pattern (see Gang of Four textbook) Add a method to FileSystemObject called DoTraverse.vi. This VI takes as inputs a FileSystemObject (dynamic dispatch input) and a TraverseVisitor. The TraverseVisitor object has a method "Enqueue Next Element" and a member field that is a queue refnum. A standalone VI obtains an unnamed queue and uses that queue refnum. Enqueue the root of the tree in the queue. Then in a loop the VI dequeues, calls DoTraverse, until the loop is empty. Result: You now have a generic traversal of the tree. The TraverseVisitor can be subclassed to provide different data/services to the DoTraverse.vi implementations. The parent class FileSystemObject does not have anything about "next" or "child" in its definition, only a method of what to do during the traversal. ---------------- More general note about this conversation: It's a very strange feeling. I have programmed LV, JAVA, C++ and half a dozen other languages. In all of these, I could quickly identify a hack as distinct from a good implementation. With LV and OO, I have only vague feelings about whether something is a hack or not. I've never worked with a programming system this new before. Very cool, in some ways, very odd in others. This conversation needs to be tracking two aspects: 1) the search for good implementations and cannonical patterns and 2) the holes that need new language syntax to patch over. Distinguishing what is a hole that needs to be patched from a bad idea that should be avoided is the root of the design decisions that lead to the current LabVOOP implementation, only now there's a working model to see if the theory tests out. ;-) ---------------- [Later Edit] We could simplify this purity problem you're having. In the file directory use case, you could argue that every FileSystemObject should have a GetNext function... after all a shortcut is a file that might want to traverse to its real file, or a .zip file might want to traverse to the files contained within it. "When the problems get hard, redefine the solution." -
Trees, Recursion, Reentrancy & LVOOP
Aristos Queue replied to LAVA 1.0 Content's topic in Object-Oriented Programming
Reentrancy is a nasty problem for dynamic dispatching. I won't go into the details here. There's all sorts of weird ideas kicking around the LV team on how to handle it, none of them exactly satisfactory yet. There's a couple of answers. The first answer I can offer today is the refuge of CS theory: Any function that can be written recursively *CAN* (provably) be written iteratively. The trick is figuring out how to do it for your particular algorithm, and there is no magick bullet. Most solutions use a stack data structure. Using the Queues I've managed to get several recursive algorithms implemented in G. Tree traversal tends to be easy if you want breadth first traversal -- enqueue the root, then inside the loop dequeue an element, operate on that element, then enqueue the element's children, if any. Continue looping until the queue is empty. Depth traversal is done the same way, only using Enqueue At Other End prim. This works even if your tree is implemented as an array with stored indicies for left and right children -- just enqueue indicies instead of the elements themselves. The other answer is to have a non dynamic function that is reentrant and recursive that calls a dynamic subVI. The subVI "does whatever" and returns enough information for the non-dynamic portion to decide which node to recurse on next. -
The map of things you can do with LabVOOP still has "Here There Be Dragons" on it in many places. We've set up base camp and will be exploring out from here. Pointing out which dragon's region you'd like to civilize first would be useful. But I do think that sending the list of priorities to someone on the LabVOOP development team would be more useful than sending them to Dr. T. Just my opinion. Both of those sources you cited are from me personally, so please don't hang "NI" with that rope. You don't need XControls for classes or to make useful apps with classes. So far I have four good size apps where every VI is part of a class and none of those have XControls anywhere in them. So you can do a lot of development (one might even say "full development) without XControls. I see many UI/initialization aspects of classes that can be simplified with XControls, but those aspects can be worked around. Christina Rogers' refactoring of the Getting Started Window is all about UI, but doesn't use the XControls. I try not to advocate tools that are only available in Pro as The Solution on general sites like this precisely because not everyone can get the tool (on LAVA/info-LV I'm less concerned about things not in Base package). In this case, I didn't know.
-
:headbang: ARGH. That. Is. Not. Supposed. To. Happen. I really thought that had been tested. If the VI is truly a virgin VI, then closing it should automatically remove it from the project. Now, if you've added it to a library, then it isn't virgin any more because its name has been changed and the library maintains a link to it. But if it is just New>>Project, followed by New>>VI, and then you close the VI, that's just supposed to disappear. Are you sure you didn't do *some* edit to it?
-
Share your favorite tips and shortcuts
Aristos Queue replied to m3nth's topic in Development Environment (IDE)
Ok, I have a favorite tip that I was giving out at the LAVA dinner during NI Week which it seems no one heard before. Who likes the autotool? You know, when you go to the Tools Palette and set it to automatically change your mouse cursor for you as you move over the diagram. No more Tab key! Sounds great, but a lot of people don't like it. A LOT of people. They're genuinely surprised when LV developers like me say things like, "Yeah, I always have the autotool on and I don't know any time since LV7.0 when I wanted to turn it off." How can this be? The control key. If you have the autotool on, the mouse cursor changes to "the most needed tool on this region of the screen." Sometimes that means each tool gets only a small region of the screen. I hear people want to turn the autotool off when they try to move a boolean button -- they can get the operate tool and the text tool, but they can't find the very small region to get the pointer tool. Hit the control key. If you hold down the control key, it is defined to give you "the second most needed tool on this region of the screen." The first most needed and the second most needed are both based on a lot of user feedback. The autotool was introduced in LV6.1, and the control key mods came in LV7.0. Since then it's been pretty nice. And those of you who tap the Tab key habitually can just slide your hand down the keyboard and tap the control key instead. Oh, and it works for both left and right hands. -
True. Not much I can do about that. ;-) But at least at the names level I can make sure that the common errors introduced by overloading don't happen to LV programmers the way they happen to C++ programmers. I've spent days debugging that type of error in C++.
-
That should be taken as "most programmers in any language can't use some of the features from C++ that were left out." James Gosling was the designer of JAVA. He once gave a presentation on why JAVA's design decisions were made. One thing I will never forget is why JAVA does not have operator overloading like C++ does. "People were doing dumb stuff with it... like using the left shift operator for output!" The standard template library for C++ uses the left shift operator. Gosling's inditment was that the code becomes hard to read if these symbols become so context dependent that the code is no longer generally understandable. In the case of the left shift operator, that's probably ok because very few of us actually use left shift these days -- we don't need to squeeze that bit of performance out when multiplying by two anymore. But as the + became used for add, concatenate, append to file and other things, code clarity was lost. So JAVA didn't include this feature. C++ is a masterpiece of language design in so many ways. It has capacities to express concepts beyond the dreams of most developers. It is the language for James Joyce. But most of us read Dr. Seuss. Many of C++ most advanced features are never used, and when they are, they just raise questions among a lot of other developers about "what the heck does this do?" A classic example is "class X : protected Y { };" What exactly does that do to the inheritance rules? JAVA tried to refine OO. LabVIEW aims to take it to a whole new audience. Over time, features may be added that only show up in the Pro version. But the fundamentals were rolled out in LV8.2, and these are the pieces that will be common at every level of LV expertise. It isn't so much that LV users can't use the fancy features, its that many don't want to worry over whether they should or not. LabVIEW lets you focus on the project you're working on more than the code you're writing to do that project. We constantly balance power versus interference. It is our strength. And our weakness. And, fundamentally, it is our niche in the programming world. We aim to fill it well.
-
The official NI position is this: Both GOOP classes and LabVIEW classes are useful. They serve orthogonal use cases and you may well use both types in the same application. Comparisons should be based on program requirements and choice made accordingly. The core data of your GOOP Toolkit class may be a LabVIEW class. For details on this, take a look at this thread: http://forums.lavag.org/index.php?showtopic=3788
-
LabVIEW 8.2 Queue Refnum Custom Probe Crash
Aristos Queue replied to PJM_labview's topic in LabVIEW Bugs
This was reported to R&D (# CAR ID 40LHJ4J1) for further investigation. -
Refactoring the ReferenceObject example in LV 8.2
Aristos Queue replied to Jim Kring's topic in Object-Oriented Programming
(Jim, what follows is mostly stuff I already sent to you in e-mail, but it seems useful to post here.) I am thrilled at all the different implementation mechanisms that Jim has proposed. But there's an underlying assumption that he makes: that we are searching for the One True Way to implement a reference class. I disagree. I think we're searching for all the good ways to implement references, and that there is no One True Way. Different implementations serve different use cases, and I think in time LV users will standardize around a set of reference models, not one single model. Example: Jim argued that the programmer should make "Check In.vi" and "Check Out.vi" private. That's true if and only if the programmer has created wrapper VIs for all the member VIs of the original class and replicated them on the reference class and if there is no performance gained from doing a Check Out, doing multiple function calls, and then doing a Check In. Making the check in/out functions public is a model where the data is mostly used by value and the reference is created only occassionally for a particular value. It is similar to "Index array, do a bunch of modifications, replace element in array." Making the check in/out functions private is a model where the reference model is the primary way the class is used. That model is like "Tell Array Y to do the following modifications to index X." Both implementations are valid concepts, and both are useful depending upon the architecture being implemented. Many customers have argued that NI should put forth a standard by-reference implementation so that everyone uses the same system, but I've got half a dozen "standards" that I can envision, each serving a different design goal. I'm more comfortable letting conversations like this one run for a while before NI starts putting an official standard together -- I think we need to see the full range of what develops in the world before anyone can definitively say what the standard(s) should be. Keep the ideas coming ... most folks (both inside NI and outside) don't agree with me, but I truly think that every LV developer who moves beyond a set of Express VIs on a single diagram will eventually consider classes as normal and standard as VIs. We've got to get it right in these early years. PS: Jim described his case #3 as the hands down winner. In my eyes, the "con" would be: * Reference API has to supply all possible permutations of operations for efficiency. If I have a reference to a Numeric, I need my reference class to have methods for Add and Multiply. I also need to have "Square and add another square then take the square root". Otherwise I'll have to do a check in and check out between every step of the mathematics (very inefficient). With the Check Out as a public function and the a class as the queue's type, I can check out and do a whole stream of operations, still with my class shield in place to protect the data from arbitrary changes, and only do a single check in. -
This is still true in LV8.2. The clipboard is a caller that can hold VIs in memory. A bit odd, yes, but I can see how it got this way. If the clipboard didn't hold in memory, if it just recorded name/path of VI, then doing "ctrl+X" on a diagram to remove some VIs, you might be prompted to save those subVIs. And when doing the paste, you might get a conflict with another subVI of the same name already in memory ... did you mean to paste the previous VI of that name or the one you loaded between cut and paste? It gets tricky. Suggestions? :!: [About an hour later...] I was working with a graphics program. I closed the program. It asked me if I wanted to keep the data on the clipboard when exiting. Maybe that would be a good idea for LV if you close a VI and that VI is still on the clipboard. ???
-
The Defer Decision button appears ONLY when a VI's front panel is closed and the VI *cannot* leave memory. There are fundamentally three reasons why a user VI cannot leave memory: 0) It's front panel is open 1) It is a subVI of another VI and that other VI is not leaving memory 2) There is an open VI reference to the subVI 3) A special case involving VIs in untitled libraries -- I forget the details of it -- but it basically is the same as reason #1, only instead of a caller VI, it's the owning library holding onto the subVI. When you close the front panel of a VI, that removes reason #0. If the VI has unsaved changes, that's when we prompt. And the VI is either able to leave memory (none of the other reasons apply) or it is not able to leave memory (one of the reasons does apply). If it cannot leave memory, you'll get Defer Decision. We did consider adding a Revert button to the dialog -- so you would have the option to "close and keep changes in memory" or "close and reload VI from disk so in-memory changes are lost" -- but, first, adding another button was exactly the opposite of our goal and, second, we'd have to gray out that option under a lot of conditions because the subVI was in use. If you can find a case where a VI is giving you the Defer Decision option and you know that none of the above reasons apply, I'd like to know about it. Oh, and regarding criticism of LV -- I'm the one showing up to read an independent user forum. I've gotta expect that the reality doesn't match the marketing literature. If it ever does, well, LV will be complete and I'll have to go find a new job. Just make sure to post a bit of the pleasure with the pain -- so I know what features not to tinker with. ;-)
-
The dialog whose picture you posted has 12 different versions depending upon conditions. One of those versions requires 7 buttons. Even the simple version that you posted caused many complaints about people who couldn't tell whether the VI was leaving memory or not (yes, the large block of text tells you, but for many, that text they read once and assume its the same every time). Then there was the fact that the buttons drifted around -- sometimes Save and Don't Save are vertically arranged. Other times they are side-by-side. Finally, that dialog appeared multiple times because we actually needed to ask different questions for different VIs -- a single close could result in multiple VIs closing, some staying in memory and others leaving memory. And then there was the complete lack of explanation as to why sometimes the Cancel button was grayed out. Or, if it wasn't grayed out, what exactly you were canceling. Were you cancelling Close All? or were you cancelling the close of one VI during the Close All? That dialog was the source of a huge number of complaints. Creating a UI that took all possible scenarios into account was non-trivial in the extreme.