Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    202

Everything posted by Aristos Queue

  1. Please see this post http://forums.lavag.org/index.php?s=&s...ost&p=16322 for discussion of a way to do the Factory pattern with dynamic class loading even in the runtime engine. The PDF file will be updated someday.
  2. The VIs in each child do not have to have a unique name as long as there is no VI of that name in the parent class. For example: Class Parent has two children, Kid and Junior. Kid can have a static method DoStuff.vi. Junior can also have a static method DoStuff.vi. The above is true as long as Parent does *not* have a method named DoStuff.vi. If Parent does have a method named DoStuff, then it must either be dynamic (and Kid and Junior become overrides) or, if it is static, then Kid and Junior cannot have a VI with that name.
  3. An unanmed queue cannot be accessed by any other VI. It is the absolute best way to ensure no name collisions occur -- without a name, there cannot be a collision. All of the examples that ship with LV try to avoid naming queues unless there's a driving need (multiple VIs obtaining references to the same queue). That way we don't accidentally have an example that interferes with another example or, worse yet, interferes with other VIs the user is running. Giving them names does help debugging, as you point out, but I'd wrap that up so that I could turn it off in production code. A named queue is useful for client/server architectures and multiple-dynamic-VI instantiations, where you want lots of VIs to talk to the same queue, but you don't know which VI will be the last to shut down, so you want each VI to have its own reference to the queue.
  4. I'm going to answer your question on data inheritance first... I'll get to your "alternate ways to do dynamic instantiation" question in a moment. Every instance of the child has the parent's data. But although the child class carries this data around with itself, no function owned by the child is allowed to read or modify the data. You said you speak C++... so let me write some equivalent code. Ok... in the above code, is there any way for any function to ever change the value of x ? The answer is no. Every instance of Child will have two integers inside it -- x and y -- but there is absolutely no function that has the authority to change the value of one of those integers. If Child is going to have access to x, then Parent needs to supply get and set functions... like the ones shown in the red box: This same idea of get and set methods is required in LV. Make sense? I just realized there's a possible terminology collision here. I've been assuming one particular meaning, but I'm not sure that meaning is what you intend, given the other the details in your latest post. You use the phrase "dynamically creating instances of a class." Do you mean A) "Assuming a class definition is already in memory, are there any other possibilities for creating instances (objects) of that class?" or do you mean B) "Are there any other possibilities for dynamically loading a class definition into memory and then creating data of that class type?" If the answer is A: Every time you fork a wire you create a new instance of your class. Dynamic creation is anything that creates a new copy of your data -- such as Initialize Array. Now, if you need specific instances of your object that you can talk to using a reference model, then you should take a look at the ReferenceObject example that ships with LV: After you've looked at that example, you should read this discussion forum: http://forums.lavag.org/index.php?showtopic=3788 The version that ships with LV is a viable implementation of references, but it is one among many. If the answer is B: Yes, there is another way to achieve dynamic loading of classes into memory, without the enum suggestion. Any VI that uses a class will load that class into memory. You can use VI Server to load a VI into memory even in a built application. SO.... Create your classes. Let's call them Alpha, Beta and Gamma. These classes do not have to be related. Add a method named DefaultValue.vi to each of these three. This VI should have no inputs and its only output should be of type LabVIEW Object (or, if there is an inheritance relationship among your classes, any class that is a common parent to all three classes). On the block diagram of these classes, drop a constant of the class type and connect it to the output FP Terminal. Your Factory code should be changed now to use Open VI Reference. Instead of loading a class directly, it will load any of the DefaultValue.vi versions. Use a Call By Reference node to invoke the VI and get the data instance of the newly loaded class.
  5. Attributes are not lost. See attached VI. (written in LV8.2, but I am very certain this same behavior applies all the way back). Download File:post-5877-1157741008.vi
  6. It isn't new... but you probably don't want to use it before LV8.0. The variant attributes have been stored using a red/black tree for O(log(n)) lookup speeds for as far back in the code as I have checked (LV6.1). I think that's how they're originally implemented. And that's good. But until LV8.0, there was a huge block of memory reserved for each attribute, which actually made this name lookup database not feasible for anything more than a couple hundred attributes. With the revisions of LV8.0, the variants have really really improved in speed (I've never benchmarked it but it's A LOT faster), and the memory overhead has decreased to almost equal to the amount of data you're storing. Variants were tweaked with this use case specifically in mind to makes it an incredibly efficient lookup tree.
  7. Doing "save as" on a running VI has always been an thread-unsafe operation. The fact that it has worked so often in the past is the Grace of God and the fact that few users have dual CPU or multicore CPUs. With the introduction of LVClasses, we had a situtation that where runtime save as would almost always crash. Couple that with the increased number of dual core and dual CPU machines, and it was more than time to do something -- either prevent runtime "save as" or make "save as" be thread safe. The latter would be preferrable from your point of view but it turned out to be technically infeasible when a couple of developers investigated it. So the error.
  8. You've come to one of several right places. ;-) ni.com would also be a good place. I'm the lead developer for LabVOOP (my preferred acronym -- LVOOP doesn't have any clear way to pronounce it). Here are two docs that are likely to help you in some degree. Neither of these ships with LV -- they weren't finished until after the final CD was done. The LabVIEW Object-Oriented Programming FAQ http://zone.ni.com/devzone/conceptd.nsf/we...62571D800665A4D LabVIEW Object-Oriented Programming: The Decisions Behind the Design http://zone.ni.com/devzone/conceptd.nsf/we...62571CA00506D74 Hrm... that's not quite right. "How to dynamically create an instance..." You're going to want to read all the sections of the above documents dealing with "by reference vs by value" and probably several of the forum topics on this website. The solution that you came to is no more nor less effective than dropping an Initialize Array primitive and asking it to create an array of arbitrarily many objects. And you really need to read up on LV2-style globals aka functional globals aka shift-register databases. I don't have links to any of those topics off the top of my head, but search around using those keywords and you'll find good stuff.
  9. I'll try to post more later (probably later this week), but for now this might help you get started since you're familiar with objects in other languages. http://forums.lavag.org/index.php?showtopic=3845
  10. No. Just because it is simple doesn't mean it is at all a priority. Any feature takes time, refactoring features take more time, and anything affecting the GEH takes a long long time because of the number of people who use it and have objections to any change in its behavior -- internal or external. Plus all the rest of your questions are exactly the sort of thing that would have to be brainstormed. We're a long way from even committing to something like this as a good idea, much less actually doing it. You should consider any significant modifications of LV using OOP to be on more of a 10 year timespan than a 10 month timespan. The stability of the whole LabVOOP system has to be verified before LV starts relying on it generally. New features can develop and dodge around bugs. Refactoring old stuff means the new has to work flawlessly.
  11. Ah, stateless VIs. I'll add your voice to the chorus. I'd love to have that, too. ;-) Don't worry. ;-) This wouldn't affect all VIs. The idea would be a VI that you could explicitly mark as a stateless VI and thus prevents uninit shift registers, local variables, the Value property of controls and requires all controls to be a) connected to the conpane AND b) marked as requiered inputs. VIs that are stateless have some very nice properties that can be used for a variety of situations. Further the code can be optimized a lot.
  12. Worth thinking about, certainly. At this point I don't see any pitfalls. My brain is going slow this morning. How does this work? Oh, and I did find one hole in the entire solution... uninitialized shift registers. An unscrupulous programmer can connect the terminal output of one of the exposed VIs to the inside terminal of the right-hand shift register. Then the left-hand shift register, if left unwired, would be able to produce an uninitialized (in the most terribly litteral sense!) value of the class. To really enforce the pattern, I would need to force shift-registers to be wired if they cannot access the class.
  13. This was reported to R&D (# CAR 4148NNJ1) for further investigation. It is confirmed as a bug. Custom probes should have the same access as any other VI in a library (or any deriviative of library, such as class or XControl).
  14. I hadn't thought of it that way, but you're right. By embedding an Initializer in the place where we setup the queue. Then there's no way to get one of these values that hasn't been through the initialization function.
  15. So, a suggestion that's been knocking around the R&D team for a bit.... I've mentioned several times (during the beta testing, at NI Week, in various forums) that the Error Cluster would make a great class ... if only we already had classes and were introducing the error code cluster for the very first time. Mutating all existing VIs and prims in some future version of LV would be nigh on impossible (I think). But... The General Error Handler.vi takes in an error code cluster and makes it presentable ("human readable"). This VI follows a general pattern of 1) look up the code in the error code database and 2) display the source of the error with the translation. Now, several hacks have been applied in the past to embed information in the error code cluster. Specifically, the GEH.vi recognizes <append> and <err> tags. If these two tags appear in the source string then they are interpreted to mean "the source stops before this tag and everything after the tag should either be appended to the translation of the error code from the error code database or should replace the translation in the error code database (depending upon which tag is used)." When DAQmx was rolling out, the hardware teams really wanted to have an error code cluster that would produce a graph in the General Error Handler.vi. We said No Way because the GEH.vi is too big already. We really can't afford to bloat it further with specialized dialogs for particular error codes. But what if we could dynamically dispatch somehow? Then we would only have VIs in memory for those errors types that actually might occur in a system -- that means specialized dialogs wouldn't be a global expense. So the idea is to introduce an <obj> tag. Everything before the tag is the source of the error. Everything after the tag is a flattened object inheriting from ErrorDescription.lvclass or whatever name we make up. Then we could have the core of the GEH -- where the error code gets translated and put into a dialog -- be a dynamic dispatch. If no <obj> tag is encountered, construct a default error description object which does what the GEH does today. The nice aspect of this is that non-LabVOOP users would get the advantages of object dispatching and specialized error types without ever having to be aware of them. I have no idea what the performance would be like. I haven't had time to prototype the idea. But in combination with your throw/catch suggestion it might be a better way to handle errors in LV.
  16. I finally had time to rewrite the Singleton Pattern for LabVOOP. http://jabberwocky.outriangle.org/SingletonPattern.zip Here is the accompanying text: Singleton Pattern (adapted from Gang of Four
  17. Nope. That VI only controls the icons. It takes an icon set in and outputs an icon set. That being said, the functions for "add to library" etc are all available. Take a look at the VI Server meths/properties available for LVClass library files.
  18. Since you're playing with the icons, you should know that the initial icons for the private data control and the library are both set by VIs in <labview>\resource\plugins\ directory. The VIs are named something with "icon" in the name... I don't recall off hand. You can rewrite those VIs if you want different initial icons (or even create a walk through wizard for establishing those initial icons).
  19. Beautiful! "Save a bug report! Write it yourself!" I had a hard time understanding "number of lines." Is this "number of rows of pixels" or "number of lines of text"? [Yeah, I could drill into the VI and puzzle it out, but it is easier to ask.]
  20. I made the same argument. I was forced to conceed the necessity of showing all the broken VIs, though I keep hoping for a better idea to come along. Basically, when a VI is broken, you can click on the broken run arrow and see a reason why the VI is broken. Now, if the VI is broken because of a subVI, my thought was, "Well, then take me to the broken subVI... why am I messing around here?" But although sometimes you might want to fix the subVI, it was pointed out that sometimes you you may want to know which subVI node is the problem so you can delete that subVI call. With LV classes, I think 90% of the time you're in the situation of "please, just take me to the subVI." That's because so many barely related VIs break in response to a single broken VI. With LV in general, I'm not sure what percent of the time you want to fix the subVI vs change the call to that subVI. But since few developers are LabVOOP developers at this time, we stay with the current convention of scrolling the Error List Window to whatever subVI you clicked the broken run arrow on... you can scroll up to the Red Xs. I did at least get those sorted to the top of the list.
  21. No. At the current version LVClasses cannot be downloaded to any of LV's targets. They execute exclusively on the desktop platforms (Mac, Linux, Windows). They are completely portable across those platforms. The targets, well, ... R&D never promises features. But, in the words of one developer some years ago... "It would not be unreasonable to assume that we might be working on something like that."
  22. In order for any VI in Class X to run, A) every dynamic dispatch VI in the Class X must be runnable. ...because we have to build the dynamic dispatch table of compiled VI pointers in order to have runnable data on the wires. Trying to only reserve certain positions in the dispatch table turned into a nasty mess that wasn't really maintainable. When you hit the run button, we were traipsing through call hiearchies, including all possible dynamic dispatches, searching for any call that might invoke a given subVI and then figuring out which position in the dynamic dispatch table that subVI occupied and thus all classes needed to be able to reserve that position. B) X's parent class has to be runnable. ...because the child is a parent and depends upon the functionality of the parent. By induction, this implies all ancestors of X must be runable. C) all classes that are members of Class X must be runnable ...because those classes are part of the data of X. D) all classes that are children of Class X must be runnable ...because controls of Class X can contain child data and there's no way to detect when we hit the run button whether or not such data exists. E) we have to lock all members of Class X (even the static ones) so that you cannot edit them because if you were to edit a static VI to be dynamic while the classes were running, this would change the indexing of the dynamic dispatch table. This is a burden for LV that I'd like to decrease, but I would like to point out that in most languages the entire hierarchy has to be runnable for anything to work. We were able to maintain the individual runnability of VIs, but everything has to be *able* to run. I'm very concerned about these cases. A lot of stuff breaks when one VI breaks, but that one VI should be readily findable with the red X and I'd hoped that the errors there were sufficiently explicit. Was the error list window not descriptive? What were these errors? See above for why so much breaks. As for the cycles, the dependencies list is cyclic and its hard to get descriptive error messages propagated so that everything is reporting the real reason for its breaking, especially when there are multiple things really broken. Again, that's why the red X modification was so important to get in this version. There are certainly improvements that can be made in the future.
  23. AH! I found the miscommunication! "Stores" in this case means "saves on disk or transmits across TCP/IP or explicitly requested by LV's Flatten to String prim". In memory the structure is just as unflat as any other LV structure.
  24. Take a close look at the Error List Window. The items at the top (scroll to top) have a Red X next to them. These are where the real breaks are. Everything else is broken because of one of these. This is a fix that applies even to subVIs in deep hierarchies. This UI feedback should help with a lot of the "drill down the hierarchy" type problems.
×
×
  • Create New...

Important Information

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