-
Posts
3,183 -
Joined
-
Last visited
-
Days Won
204
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by Aristos Queue
-
I mentioned recently that I was posting less because my new computer at work was able to build LV much much faster, so I had less downtime for posting. This begs the question: Why is AQ posting so much this morning? Simple: I can't get off the couch without feeling really awful. I tried to play games or do some LV coding, but tracking the movements of the mouse cursor was making me nauseous. So I'm sticking to text. Text I can handle. This sickness is just a cold or flu of some sort, nothing serious. I can feel it being beaten back, and I'll probably be fine tomorrow, but that doesn't make today any better. I hate being sick.
-
QUOTE(robijn @ Oct 15 2007, 11:16 AM) Ok. That's cool. Took me a moment to see how you got from Ben to uaq, but I'm typing on my laptop, and when I stood up, it was suddenly blazingly obvious. ;-)
-
subVIs memory deallocation
Aristos Queue replied to Gavrilo's topic in Application Design & Architecture
This is a question that would be better to post to DevZone than to LAVA. The developers who would know about the Dealloc prim tend to monitor DevZone and not LAVA. There are also AEs who have played around with that prim's behavior. If you do post to DevZone, be sure to add a post here to link to the other topic. -
LV OOP override-vi & polymorphism?
Aristos Queue replied to Milchbilch's topic in Object-Oriented Programming
QUOTE(Paul_at_Lowell @ Oct 12 2007, 08:00 PM) I love customers that make suggestions like this! :-) I don't know if your idea will make it through the feature pipe anytime soon, but your comment has provided good food for thought. Curious enough ... I spent a chunk of time writing a Linked List in LV (you can read about it http://forums.lavag.org/index.php?showtopic=8914&view=findpost&p=37007' target="_blank">here) and I was trying to delete error handling from a series of VIs. Popping up on a host of VIs to remove the case structure, then delete the FP terminals, then remove the broken wires, all without accidentally wiping out the useful code. That experience is one I've had before. But having done that just yesterday, in combination with your comments about the difficulty of adding error handling to a VI, makes me wonder about better ways to tell a VI to handle errors. Don't reply to this idea here. I don't want to hijack the thread. But at some point we should have a discussion about adding code to a VI that doesn't necessarily involve modifying the diagram (like an option for an "implied" error case structure). But let the idea marinate in your mind for a few weeks. -
QUOTE(hskupin @ Oct 15 2007, 08:11 AM) And here we have contradictory requirements. See, suppose Corporation XYZ wants all dialogs to have a similar look/feel. So they create a template VI, with front panel grid spacing of 13, because they want 13 pixels between all independent controls, and a 13-pixel margin around controls always. They may also configure the VI to use Classic controls by default, etc. Now a developer creates a new VI from the template. Should we use the developer's environment settings? Or the template settings? We use the template settings because, well, that's the point of a template. Now, that's true for *user* templates. But the templates for new LVClass functions (and a host of other features in LV, like XControl functions, for example) are NI templates that we use to accelerate the creation of methods. These should use the environment settings. The foregoing thoughs have led to a huge debate within LV R&D about the nature of a template and what is appropriate behavior in a wide range of scenarios. This is much bigger than LV classes, and whatever comes out of that debate, classes will take advantage of.
-
Map, implemented with classes, for 8.5
Aristos Queue replied to Aristos Queue's topic in Object-Oriented Programming
QUOTE(Tomi Maila @ Oct 15 2007, 04:33 AM) The inplace element structure, the Always copy prim and the Swap prim, now found in the palettes. You can use these to assert "a inplace to b" and LV will compensate elsewhere in the code to make that happen. -
The decision to not allow static VIs to share names up and down the hierarchy was made for user benefit initially -- it avoids a programming error that was found to be common in C++ of forgetting to make a function "virtual" (the C++ equivalent of "dynamic dispatch") and thinking you had overriden it in the child class when in fact you had only shadowed it. Function shadowing was something we really wanted to avoid because it is simply baffling even to advanced programmers what is going on with a function. So, if you name two functions the same name, we assume you want to be doing dynamic dispatch and we break the VI until you either set the VIs to be dynamic dispatch or rename one of the VIs. So, we made that decision, and I do think it is generally a good one. It is in line with the other decision to prevent function overloading, where multiple funcitons of the same name have different conpanes. Since the parent class has already defined a function of a given name, arguably that name is already taken in the child's namespace (depending upon whether you think of inheritance as actually inheriting an API vs inheriting rights to invoke the parent's API). Having made the decision, the LV implementation has now enshrined that decision in several places, and changing it would be nigh on impossible. Not completely impossible, but sufficiently so that it would take a massively compelling reason to change it as we'd have to drop a bunch of other feature work in order to address the code. I've tried talking to multiple early adopters about this issue, and most have come off like Justin -- they don't really like it, but see enough advantages to keep the current mechanism, particularly when they see what can happen with C++ function shadowing. (Note that all of this is separate from the conversation about whether a private-scope static dispatch VI should steal from the child's namespace. I'd like to fix that bug, but there's some technical difficulties doing so; it too has become kind of enshrined, although less so).
-
Map, implemented with classes, for 8.5
Aristos Queue replied to Aristos Queue's topic in Object-Oriented Programming
QUOTE(Tomi Maila @ Aug 29 2007, 11:25 AM) Use the "Show Buffer Allocations" tool to see where copies are being made. Read up on "playing hide the dots", a game known to advanced real-time programmers in LV. Or assert the inplaceness with the new tools in LV8.5. In the worst case, post your code and ask. This really is a rarified statum of LV programming; users who need to know what it is are extreme statistical outliers. You notice that LV had been around for 20 years before we put in the inplaceness structure. That's because the vast majority do not care and do not need to care. -
how to dynamically change enum strings in private data
Aristos Queue replied to Gabi1's topic in LabVIEW General
QUOTE(TG @ Oct 14 2007, 06:04 PM) Take a look at the http://eyesonvis.blogspot.com/2006/08/code-reuse-through-classes.html' target="_blank">Eyes on VIs blog discussion of the Getting Started Window. This is the first of many discussions we've been having about how classes can replace case structures. There's also the example program that ships with LabVIEW 8.2/8.5: <labview>\examples\lvoop\BoardTesting\ That example has raised the ire of many people because it implements a test bed system once in OO and once procedurally, and it paints the procedural version in a bad light by deliberately making some bad design decisions. But that was done to highlight the change from one system to the other. One of the major refactorings in this example is the replacing of the case structure with a class hierarchy, making the system dynamically expandable and not limited by having to actually edit a case structure in order to handle a new board type. -
Trying to understand reentrant
Aristos Queue replied to HChandler's topic in Application Design & Architecture
I said that I will have a core functional global that is reentrant and then a wrapper VI that is not reentrant. Thus each wrapper VI instantiates the reentrant VI once, and thus I have multiple globals to work with. Tomi mentioned that he just uses VI Server to instantiate another reentrant clone, rather than statically allocating, as is done in my scheme. The reason that I have used my scheme, from time to time, is that the core functional global is frequently written in terms of some generic datatype (either LabVIEW Object, LV Variant or flattened strings). The outer wrapper VI is then my type-specific wrapper. So the outer VI may take a double as an input, translate it into my generic type, pass it into the functional global, and then translate the generic back into the double. It saves me from having to do the type conversion code at every call into my generic functional global. I also hate debugging reentrant clones that don't come from a specific subVI -- it's hard as nails to get to the diagram for a dynamically created clone VI and set a breakpoint before that VI executes. With static instantiation in non-reentrant wrapper VIs, I can find the specific clone I'm looking for much quicker. (PaulG, don't read this next bit until you've digested the foregoing because it may really confuse you.) Of course, my wrapper idea can be combined with Tomi's idea... have the generic functional global core be reentrant. Have the type-specific wrappers also be reentrant. Then use VI Server to instantiate type-specific instances whenever you need them. The repetition can get dizzying: wrappers around meta-layers around pointers to pointers, recursing ad infinitem... Long ago a computer scientist said, "Most problems of computer science can be solved by adding another layer of indirection." It may be true, but it can be hard to grasp all the layers at once. -
how to dynamically change enum strings in private data
Aristos Queue replied to Gabi1's topic in LabVIEW General
QUOTE(Tomi Maila @ Oct 14 2007, 03:16 PM) In the mean time, you should see if you can come up with a G tool that can autodetect unneeded case structures and script classes to replace the functionality. :thumbup: -
Map, implemented with classes, for 8.5
Aristos Queue replied to Aristos Queue's topic in Object-Oriented Programming
Earlier, I wrote this: QUOTE That statement is FALSE. I made this statement because I really believed that was what was happening in the diagram. When everyone started asking, "Where is it?" I went back to study the diagram in detail, and had to think about each and every wire branch, and I realized I was wrong. I am sorry for leading you about on a wild goose chase. I said that use of a parent class in the child class object leads to a hole in LV's dataflow safety. I now retract that statement. There's still something at the back of my head nagging at me that a hole exists, but obviously the Map class doesn't demonstrate it. For now, assume the hole doesn't exist and this was just the fevered worrying of a developer who has spent too many years staring at LV class inplaceness and has become paranoid that some data-copy-bug is actively stalking him. At the moment, we have no known issues with this. Everyone who said, "I don't see why this should be a problem" was correct. I also need to correct one other point about Always Copy primitive: This error results from my own poor understanding of a new LV feature. In the original posting of the Map class, I used some Always Copy primitives to force a copy of the constant's value before wiring it to a Swap primitive. This turns out to be unnecessary. Since the Swap prim is not something that modifies values, I thought that the swap would be inplace with the instance coming out of the constant, and thus would cause problems for the constant. Turns out that LabVIEW is smarter than that and the Swap prim will make a copy rather than stomp on the constant's value. So the Always Copy prim is not needed. The rest of my comments -- the need for the Swap prims, etc -- appear to be correct. Now, on to the rest of the questions... QUOTE(Tomi Maila @ Aug 30 2007, 03:11 AM) To proove myself right here, I attach a version of AQ's map where all the in-place tircks are removed. And it appears to work. I have decided that I didn't explain some aspects of this very well. Specifically, Tomi posted a version of the Map class with all the inplaceness tricks removed, which works fine, and he wanted to know why the inplace tricks are needed. So I have created a MUCH simpler example: the Linked List. Download File:post-5877-1192399595.zip This is a linear list of data, where it is easy to append to the start of the list without ever reallocating all the existing entries. To access items in the list, you have to traverse down the list -- there is no direct access the way there is with an array. I've gone with a very flat hierarchy for implementing this example so that the bare minimum number of VIs exist. Just as with the Map, the key bit of magic is a child class that uses its parent class in the private data cluster. In this case, the parent class is Root and the child class is Node. There are only four operations currently defined on the list: "Dump to string" allows the list to be shown as a string for debugging (so you can evaluate whether it is working right or not) "Insert at front 1" is one implementation of inserting at the front of the list "Insert at front 2" is a second implementation of inserting at the front of the list; compare the two implementations "Insert at index" walks down the list to a given index and performs an insert at that point If you open Demo.vi you will see two link lists, one being inserted using version 1, the other being inserted using version 2. Ok... so let me try to deal with a long list of questions that have been raised by the Map class. To begin with, the Swap block. Here are the block diagrams for LinkedList.lvlib:Node.lvclass:InsertAfter1.vi and LinkedList.lvlib:Node.lvclass:InsertAfter2.vi. (I used red text so you could see there was actually a difference in those two long names!) In each picture, there's a point marked "A". In version 1, at point A, we make a full copy of the entire list. The information in the cluster is being moved out of one cluster and into another cluster. So LV decides there has to be a copy made so that the two clusters aren't sharing the same data. This defeats the purpose of the LinkedList which is supposed to do inserts without duplicating the list. In version 2, at point A, we use the Swap primitive, new in LV8.5. We take a default Root object and swap it with the contents of Next. Now the contents of the Unbundle are free to be put into a new cluster without duplicating all that data. Tomi: Does that make sense? QUOTE(NormKirchner @ Sep 26 2007, 03:08 PM) I'm confused as to why it is necessary to have the map node methods if they are never used, why not just have them at the branch node level? The Map Node class is the parent for both Branch Node and Leaf Node. As such, it has to define the interface that both of the children classes must match. Map Node defines the API, and then Branch and Leaf implement it. In the simpler Linked List example, I have done away with the base case. I only have Root and Node, rather than a common parent for each of them. This decision not to have the common parent is a bad architecture decision in many cases because now if I want to have behavior on Root that does not apply to Node, I have no obvious place to put such code. As hierarchies get deeper, such decisions can lead to all sorts of weird hacks. QUOTE(NormKirchner @ Oct 1 2007, 10:46 AM) Another thing that just came up, is in the CompareKey.vi. Each of the comparison items needs to be a compare aggregates rather than elements. This needs to be changed if the data type of the key becomes anything other than a scalar. Any reason not to? If the data type changes from String to LabVIEW Object (as I intend to be able to do in the next version of LV), then Compare Elements will still work just fine -- a class is a scalar as far as any operations on the class are concerned. The fact that there is data bundled together underneath to implement that scalar is hidden away. Note: Do not take this comment as a reason to believe that we'll have class comparison working in the next version of LabVIEW. I may intend this happen, but then, I intended to have classes in 8.0, and we see what happened there... QUOTE Another item that bubble sorted to the top was the input/output array in 'In Order Fetch Keys' needs to be an array of the the key data type rather than just an array of strings. Yes. I missed that one. ------------------------ Ok. I think I'm caught up on the backlog of questions on this thread. If there are any I missed, please repost them. -
how to dynamically change enum strings in private data
Aristos Queue replied to Gabi1's topic in LabVIEW General
QUOTE(Gabi1 @ Oct 9 2007, 03:42 PM) Can't update typedefs at run time. That's an edit to the VIs, and requires the VIs to recompile. We'd have to check all case structures to make sure they cover the enum, break VIs that don't have a "default" case, etc. The string-to-number assembly code compiled into Format From String prims would need to be regenerated, etc. Enums are compile time set and are set in stone. What you *can* do with LVClasses is this: Get rid of your case structure entirely. Replace it with a dynamic dispatch subVI "DoSomething.vi" on class Parent. Then load a new child class into memory for each string you would've wanted to dynamically instantiate. Each child class would know how to interpret zero for its own uses. This gets rid of the error-prone string compare, keeps everything type safe, and allows you to expand handled cases dynamically. -
Stop LV from auto-numbering VI icons?
Aristos Queue replied to Justin Goeres's topic in Development Environment (IDE)
In LV8.5... This only affects VIs created inside libraries (.lvlib, .lvclass, .xctl, .lvsc, etc). If you just do "New>>VI" not in a library, you'll get the numbers for the first 9 VIs you create and blank thereafter. Since this has gotten good feedback, I'm probably going to change the name of this .ini token in the next LV version to just be this: UseNumbersForNewVIIcons=FALSE and it would affect all VIs, not just those in libraries. I mention this now just so people who read this aren't surprised in a future version when the current token stops working. -
Use Help>>Find Examples. Everything you asked for has an example VI in there, I believe.
-
Tag versus parameter
Aristos Queue replied to Bobillier's topic in Application Design & Architecture
QUOTE(crelf @ Oct 12 2007, 07:06 AM) Just don't try it with a shared variable. Shared variables don't respect scope settings. And if you try to CAR it you'll be told that's a design feature. Trust me... I tried to "CAR" it back at the design phase. -
Tag versus parameter
Aristos Queue replied to Bobillier's topic in Application Design & Architecture
QUOTE(crelf @ Oct 11 2007, 04:24 PM) Any other VI can read any VI's tag. So, no, they're not encapsulated globals. For the record, if you want an encapsulated global, an LV2-style global or a global VI can be made private to a library (or protected to a class) so as to restrict access to it. And if you want a "global" that is restricted to a single VI, well, that's an uninitialized shift register. -
How to get mouse and keyboard events during edit mode
Aristos Queue replied to wish's topic in LabVIEW General
QUOTE(wish @ Oct 11 2007, 05:55 AM) No such luck. You can only register for events on running VIs. You could monitor at the OS level for generic keystrokes and mouse actions and then back calculate which control had focus/which control the mouse was over. Takes a lot of work, but it is doable. -
QUOTE(robijn @ Oct 10 2007, 03:57 AM) I suggest that it would be more proper to say "LabVIEW implemented this feature." After all, I can't find any human programmer who has done this, so clearly LV has advanced to the point where it can reprogram itself to advance its own capacities. :ninja: Seriously... I really want to know how this works. We're too far from April Fools for Michael to suddenly say "just kidding."
-
"Input parameter is invalid..." on built EXE launch
Aristos Queue replied to Justin Goeres's topic in LabVIEW General
QUOTE(Justin Goeres @ Oct 8 2007, 12:16 PM) Actually, that one is my dialog. It's terrible too. It was one of the first changes I made to the LV source code years ago. But -- here's the joke -- it's actually great considering that before I changed that code, each one of those messages was, get this, a separate dialog requiring you to hit "Ok." :headbang: Perhaps someday someone should revisit that code and actually make that dialog usable... -
"LabVIEW class is not in memory" error
Aristos Queue replied to eaolson's topic in Object-Oriented Programming
QUOTE(Tomi Maila @ Oct 7 2007, 04:17 PM) Never forget ... I'm a C++ programmer professionally. I'm only a G programmer as a hobbiest. When we started this OO thing, there weren't any pro LabVOOP programmers, so my hobbiest status counted for a lot. That'll wane over time (assuming I've done my C++ work well enough ) Maybe someday LV will be finished and I can -- as some of the more senior LV architects have done -- become a G programmer professionally. PS: Tomi makes some interesting points about the utility of a separate Factory class. I'll have to think about that. -
"LabVIEW class is not in memory" error
Aristos Queue replied to eaolson's topic in Object-Oriented Programming
QUOTE(Tomi Maila @ Oct 6 2007, 07:36 PM) Actually, I may have led him to this if he's read my posts on factories in various forums. I've been asked by many people what class should properly own the factory method. I don't have a problem with the parent class owning that method. I don't see the need for a separate Factory class. I'd be curious to hear pros/cons on this point. -
"Input parameter is invalid..." on built EXE launch
Aristos Queue replied to Justin Goeres's topic in LabVIEW General
QUOTE(Michael_Aivaliotis @ Oct 3 2007, 01:36 PM) I would suggest that I do frequently admit to LV's deficiencies, but my reaction to them is too mild for your tastes. Your declarations tend to be "this is not perfect, therefore this is not usable." It's the "this is not usable" part that I usually take issue with. Generally, if it only affects the developer of LV, I'm a lot more comfortable with it than if it affects the end user of a program written in LV. Curiously enough, the parts of LV that are, to me, our greatest points of shame almost never come up in these forums. Like our lack of support for ctrl+Insert, shift+Insert and shift+Delete on the PC. That one has bugged me for years. Every other PC program supports those shortcuts (copy, cut, and paste respectively), but not LV. Or ctrl+shift+arrow keys behavior inside string controls. Those actually affect end users, not just developers. That distinction is related to the distinction I draw between "LV the programming language" and "LV the development environment." The environment can be rough as long as the end result is beautiful. If the end result has problems, that really raises my hackles. That error message is borderline, since it isn't really something you'd display to an end user, but it is nonetheless a runtime dialog. In any case, I loathe it.QUOTE(crelf @ Oct 7 2007, 03:04 PM) I've heard Stephen admit that LabVIEW isn't perfect previously, but, as my Ma says, "I'm not perfect, but I'm as close as anyone you'll ever meet." I propose a variation: "The software had a user interface that only its developer could love." -
QUOTE(mballa @ Oct 6 2007, 06:33 AM) Yeah! How did you do that?! When I put together the code for "Inputs req'd by default" for 8.5, I couldn't figure out how to get req'd outputs into the C code. So I'd love to know how you did it from G!