Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    204

Everything posted by Aristos Queue

  1. Exactly. For a "variable" to be thread safe, we have to know all the places that are going to use it. We (LV R&D) could create a named thingamajig that is usable only on the current diagram, and only allows a single writer but many readers, and thus get knowledge of all the places it is used, but the representation that is most effective for saying "this data, generated here, is used there, there, and there" is a wire which visually shows all its branches. The "local variable" is for communication back to the front panel. Throw a "Sequence Structure" around the section and lock that structure. Remove these structures when you're done cleaning the diagram. Yes. Use "View>>Tools Palette" to show the tools palette and then select the paint brush tool to paint the background of structure nodes. When you're done, click on the green LED to turn the autotool back on so you can continue doing selection, wiring, etc. There are some other specialized tools in that palette for other less common actions.
  2. LabVIEW 2009 has the "Clean Up Diagram" button -- shortcut key is ctrl+u. It is designed to help solve inherited code problems like the one you describe. You do create performance overhead with the copies of the nodes. Each property read makes a copy of the data in the property. For many properties, like "height" for example, this isn't a big deal. But if it is something like "Value" and the value is a large array, you might be duplicating a significant amount of data. Also, every property node has to switch to the UI thread where as computations can be done in the VI execution threads. The more times you go back to the UI thread, the less LV's compiler can help improve performance because all the parallelism is lost to serialization in the UI thread. In short, running a wire from the read of the property to all the places that need it is the most efficient and preferred solution. But if that diagram becomes completely unreadable as a result, sanity and code correctness are often worth more than a marginal performance improvement.
  3. That's a coercion dot. It's the same dot you see when you connect an integer wire to a double terminal. Just indicates that type is being converted automatically. It is sometimes important to be aware of them --- some can create performance problems or loss of precision or indicate a place where your type definition has been lost. But most of the time they're just informational. The coding conventions of LAVA require that you have an explicit cast for all type conversions and no coercion dots, but such a high bar standard is unnecessary in most day-to-day programming. If you're going to be producing a final product it's a fairly good practice.
  4. Write a custom probe for a VI Refnum type. In the diagram of that custom probe, put an Open FP method call. Then probe the wire coming out of your Open VI Reference call. If you have scripting knowledge, you can go further and have the custom probe open the panel and open the diagram and put a breakpoint on the top-level diagram, or some other point within the diagram of your choosing, so that when the VI actually gets called to run, it'll trip the breakpoint.
  5. No, and as much as I'd like to, I really don't see it happening. Writing ths requires a large block of unbroken time and it keeps getting trumped by other things.
  6. No known CARs on something like this. I'm going to be more than a bit distracted for the next couple weeks, so if you do get a repro case, post it to ni.com so an AE can percolate it up... I may not notice if you just post to LAVA.
  7. Did you modify the VI or did you overwrite the VI? If you modified the VI, it should work. If you overwrote the VI, the VI isn't going to think of itself as part of the library and thus will have the wrong qualified name and so when LV goes looking for a template by the fully qualified name, this one won't match. Is that possible? The only other scenario I can think of is that the file on disk is from a future version of LV that the current version cannot load -- happens to me all the time. :-) Other than those, your guess is as good as mine.
  8. If you are reporting a bug against LabVIEW (or any other product, for that matter) and you're using Windows 7, today I learned about a feature that might be helpful. Windows 7 includes a built-in mechanism for recording every mouse click/keystroke and screenshot that you do while recording. The feature is called the "Problem Steps Recorder." I was going to write about it, but I found this blog post online that walks through the details better than I could. http://www.istarteds...r-miracle-tool/ If you've got a particularly hard to reproduce bug, rather than typing out all the steps to reproduce, and maybe forgetting something subtle but important, you can use the Problem Steps Recorder to create an mhtml file and submit that file as part of your bug report. That gives developers who evaluate your bug report an exact play-by-play of what you did and how the bug was created. Although probably overkill for most bug reports, I figure this might help some of the more complex situations. It's also useful for creating tutorials.
  9. If you use an autopopulating folder anywhere then all the contents of that folder will be included in your project. If an item is in a library (class/statechart/xctl/plain library), the item will be listed under the library, even if it is part of an autopopulating folder. This can lead to the autopopulating folder saying an item cannot leave the project but the item isn't listed under the folder, so you don't recognize this fact, because the item is under its owning library.
  10. The bug does not exist in LV 8.6. It was, as Norm guessed, introduced with the type propagation changes for data value references in LV 2009. The bug was hunted down and fixed for LV 2010 yesterday. Short answer: Using the Type Cast node to change a refnum from one type to another is generally a bad idea. Rarely, it works, but more often LabVIEW beats you with an iron skillet and says, "No!" Long answer: I don't know. My guess is there's something bad about it, but that's just because of the short answer -- probability is not in your favor when you do this. In fact, after seeing it crop up in another user's code last week, I asked Darren N to add a test to the VI Analyzer suite to check for such typecasting and warn about it. You can play around with the casting and let everyone else know what is safe and what isn't. Assuming LV R&D has done its job correctly, there are exactly two situations that I know of where LabVIEW might crash and it's not a bug we can fix. The first is using a DLL node to call out to 3rd party code which does something abusive to the system. The second is using Type Cast on a refnum to a type that it isn't and then using that refnum. Some parts of the code have some guards to protect against this, but most don't for performance reasons (the compiler checks types, so having runtime checks just slows things down and the only reason for having the runtime checks is people using Type Cast to do things that can't ever work anyway). You might ask, if its such a problem, why Type Cast even works on refnums. Answer: because sometimes it is useful. The entire GOOP Toolkit was built by using such tricks. When we added the new queue API in LV 6.1, we maintained the old queue API by using Type Cast. Casting a refnum to an int32 makes a great database lookup key, and then you cast that int32 back to the original refnum to use it. You can use Type Cast to add/remove typedef to a refnum wire to eliminate a coercion dot. Then there's some really weird scripting tricks that work, like casting the refnum of a string constant to a string control in order to set bold face. But it is always a crap shoot. If you'll notice, the new data value references don't allow most types of casting with Type Cast. All the "legitimate" casts are taken care of by To More Specific and To More Generic. If you want to abuse a DVR, you have to cast to int32 first and then cast to another type. So go, play, see what you find, but check it out thoroughly before you use it in production code.
  11. I didn't notice what was going on. When I tried a couple of situations, they didn't allow the cast (notice, for example, it depends upon the order that wires are connected to the Build Array node whether it allows the bad behavior or not). I wasn't really delving into this whole thread because I expected the "you can't cast them" to kill the experiment. When it kept going, I thought, "That's strange, what did they find that I missed?" It wasn't until Norm explicitly called out what was happening that I realized what was up. LV will likely crash. Eventually. If you're lucky, and only if you're lucky, you'll hit some emergency shutdown code that cleans up quickly. If you're unlucky, LV will do a lot of work messing up a lot of stuff before the problem gets detected or leads to a crash. Consider: If I can get parent data onto a child wire, then I can get a LabVIEW Object onto a child wire, which, since any class is a valid value of a LabVIEW Object, then I can get *any* class onto *any* wire (you can pretty quickly adapt my queue example of the bug to demonstrate this). The first time that that screwed up object goes to an Unbundle or Bundle node, LabVIEW will be indexing who-knows-what piece of memory and crash hard, or overwrite something important, or interpret the first four bytes of some string as a voltage, etc. etc. etc. :-)
  12. OH NO. This is VERY BAD. That's going to have to be fixed in LV2010. That's a severe bug and I had no idea it existed until today. The ONLY reference on which it is safe -- and by safe I mean "won't cause a crash" -- is the DVRs. Take a look:
  13. The Endevo UML tool integrates fully with LabVIEW, does do code generation and code extraction (generate the UML from a VI hierarchy), and is the recommended tool by National Instruments for G developers who need UML support.
  14. For those who don't know, hovering your mouse over an XKCD comic provides a tip strip that is additional humor or commentary. In this case the tip strip says, "Pool on the leak must've sprung a leak." ;-)
  15. Post a copy of the VI you've got so far -- some folks here might be able to recognize your bug just by glancing at your diagram.
  16. The only DLL calls I've had to make to C++ all involved a C interface where I just needed to pass the pointer to the class (which LV can easily hold onto in a uInt32 or a uInt64 as long as LV isn't expected to access the data of the object directly). I'm sure there is a solution if the interface is actually a C++ exported function, but I don't know what it is. This may be a question better posted on NI.com/forums pages. The AEs there get questions about DLL calls all the time and may have a ready answer for you. No promises, but I'd suggest trying it.
  17. I never did get around to updating the white paper, but I typed this up today: http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Have-Dynamic-Dispatching-terminals-except-Data-Value-references/idc-p/1054548#C3855
  18. If you dynamically registered for an event that you had never included in your code, there would be no frame of the event structure that would handle that event. The Event Structure has to have a frame for handling an event of type XYZ. You can change which particular event of type XYZ you're registered for (one coming from VI X or one coming from VI Y or a different user event of the same type) but you have to have a frame to handle whatever that event happens to be. To register for a truly new event, one that isn't in the event structure, you'd need to supply not only an event refnum but also a VI refnum of the VI to be invoked when the event is fired. That VI would need to have 1+M inputs and 1+N outputs, where M is the tunnels on the border of the Event Structure plus one for the cluster of the event data itself (the node on the border of the event structure) and where N is the number of output tunnels from the Event Structure plus one for the output cluster of the event (the dispose? output if it exists... I'm not sure if there's any other event outputs). Thinking about this also made it clear to me why we cannot ever support polymorphism of the user event wires. It is the wires themselves that propagate the types to the Event Structure. Those types have to be known at *compile* time. If you upcast all the wires, it would be no different than if you had created all your events with LabVIEW Object in the first place: you'd loose all the type safety in the Event Structure, and all the events would be named the same. Now, consider this: What's the solution? (When reading this picture, pretend that Graphics.lvclass is named something like "Event.lvclass" and "Point.lvclass" is a derived class of "My Specific Event.lvclass"... doing that pretending will make it easier, I suspect, to get the idea.)
  19. These are the only ideas I can think of... a) Try upcasting your objects to LabVIEW Object. That loses your type safety but it might be acceptable in some cases. b) You can wrap them in a variant and carry around an array of variants c) The Event Registration node creates a composite event registration wire out of multiple events. Can you use that? (It's more like bundling with a cluster than building an array, so probably not much use to you.) For the record, no one has ever asked for this before and I've never thought to try this. Anyone see a reason why the polymorphism couldn't be added?
  20. Yeah... I've got a whole set of specs for this, including VIs that would define the class's behavior when wired to the ? terminal of a case structure, defining coercion dots for classes to non-class types, etc. I wanted those back in 8.2, but other things keep getting in the way. There is some limited work being done in this area today that you should see either 2010 or 2011.
  21. JAVA has a built-in serialization mechanism that can be privitized if desired. C# has a built-in "to string" but not a "from string". C++ does not have a built-in to or from string. I find that the C# system is the most common among other languages. No. That would defeat the entire purpose. It has to be a class-level decision, in the hands of whoever is deciding how much security this particular class needs to have.
  22. You need to have one of those fields at every level of inheritance -- if the child segment is non-default but the parent segment is the same as default, only the child segment will be written down.Before the smiting begins, let me lay out "how we got to why things work the way they work today". A) In LV 8.2, the first OO version, there was no XML support for objects. The only built-in persistence for objects was the Flatten To String primitive. B) When we save a VI, we save the value of diagram constants and default values for controls. To save space, we don't bother to write down those values when they are the default default value of the data type. C) LabVIEW classes are the first and only data types in LabVIEW where the default default value of the type can be changed. You can't tell LV "from now on, the default default value of an int32 is 1" but you can change the default default value of a class. This lead to a discussion of what the right decision should be about behaviors when the default default value is changed. Ultimately we settled on the behavior that a default value object should load as the default value, whatever the new default value happens to be. That decision has been criticized elsewhere on these forums, but four years later I'm comfortable that it was the right decision. D) That raised the question of representation of the flattened string. The format of an object saved into the VI and the format of the binary string didn't have to be the same, and we could have chosen different behaviors. But once we decided that objects would include their version number in their flattened representation, it made sense to have the unflattening of binary strings and the loading of saved VIs have the same rules for mutating data. Thus the default value should remain the default value. We now have two options: To not bother saving the flat data when it is default or to save the flat data and compare against the default when we load into memory. The former saves a lot of disk space AND has significant performance advantages. Thus we decided that the Flatten To String primitive, which creates a binary string of the data, should not write down the default value. E) When the XML prims were added in LV 8.6, we decided that the XML strings should again follow exactly the same mutation rules, and, again, the same performance trade-offs bent the discussion to not flatten the default value. F) XML is meant to be human readable, but, as others in this thread have noted, not necessarily human editable. If you provide an editor to your users for modifying the data, that interface will allow you to change the values without caring whether the value was written down or not. G) If you're using XML to share data between apps, you probably want to read this thread wherein I propose that you do NOT want to use the built-in LV XML primitives for XML that is going outside of LabVIEW, not because those prims are somehow flawed but rather that any built-in XML format is undesirable for data sharing (it's not a long thread if you want the arguments). H) Using XML has allowed people to write apps that circumvent the privacy protections of the object data -- flatten to xml, modify the xml, then unflatten the data again. Hiccups such as "the default value is just missing" throw a wrench into this blatant violation of app security. In retrospect, the ability to flatten to XML (and to binary string, for that matter) probably should have been restricted to member VIs by default (author of the class could remove the restriction, just like we did with Create Data Value Reference in LV 2009) so that most classes wouldn't allow this hack. I've been talking to folks about whether or not it is too late to fix this mistake.
×
×
  • Create New...

Important Information

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