Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    204

Posts posted by Aristos Queue

  1. Just thought I would post this in case others have wondered how to get each instance of an xControl to preserve edit time settings such as scale ranges, control labels, etc.

    I had hoped that it would be as simple as making the changes on each instance then doing a 'make current values default' and saving the top level vi. Alas, it does not

    work that way with xControls. However you can stash away all your setting in xControl container Tags. Within any Facade case, grap a Container State Refnum and utilize the Tag.Get

    and Set methods to store anything you want within the container instance. All the tag info remains unique for each xControl instance and the aggregate gets saved within the top level vi.

    Storing this information is what the ContainerState is for. You should put all that info in the ContainerState and then it should just be there without having to muck about with tags.
  2. Lets say you have a numeric control set to the value of 1. If you set the key focus you will see that the text field in the control becomes hightlighted.

    If you repeatedly press the up arrow on the control you will notice the value incrementing 1,2,3..8,9,10, and then jump to 20,30,40 etc.

    If you use the up arrow on the keyboard then it will increment by one throughout the range. I am inclined to consider the nonuniform incrementing to be a bug since

    in my case it is undesirable and even hazardous since it can cause a system control value (gas pressure for example) to unexpectedly jump up in value.

    The solution I found is to use the NumText.SelStart and End properties to force the whole numeric field to remain selected and then the value will increment uniformly.

    Curiously enough, there was a debate just last week within R&D about whether this was a bug or not. There was no agreement, and those responsible for the differences are no longer around. You should be aware of the following arrow key behavior: It increments whichever digit the cursor is next to. So if your cursor is next to the tens digit, you'll increment by 10. Next to the hundreds digit, you'll increment by 100. In that respect, it is more flexible than the increment arrows. Desired behavior? I don't know. I found it because I changed the increment setting of the numeric to increment by 2, and yet the up arrow still incremented by one. The arrow keys are unaffected by the increment defined for the numeric.

    The behavior is what it is, and I doubt it will change because someone might want it. But I think (hope) you can build an XControl that intercepts the up and down arrow keys and applies different behavior.

  3. Yeah, I think ShaunR got it. The GetTypeInfo VI doesn't return the Info data within the variant that I wanted. It returns the overall type of data within the variant - like Enum or Array.
    All of the info in the variant's type should be accessible through the VIs in the same folder as GetTypeInfo. In fact, GetTypeInfo should have returned "int32" to you. Isn't that the info you wanted? If there's some aspect of the variant that you can't get from the VIs in that directory, I'd be surprised, since those are the type handling VIs that we in R&D created to manipulate all the types from G. They should be as rich as anything I can get access to in the C++ code.
  4. Intriuging. I must admit that I've never even tried to do that. Now I'm going to have to have a good think on why I would...

    There's only one case I know of... there's a set of VIs... all of them work on the desktop but only a subset of them work in real-time environment. So there are two different poly VIs, one in the desktop palettes, one in the RT palettes.
  5. Quoting from the Eyes On VIs blog:

    http://www.eyesonvis.com/blog/2009/10/r-in-r.html

    Please do not post comments here if you expect the developers to see them. Please post to the blog or to the pioneer website (details below).

    Note: This isn't my project. I'm just sharing the excitement and helping to broadcast the announcement to users.

    == AQ

    ============The LabVIEW Notebook Pioneer==================

    I'm so excited to be able to share with you the project that I've been working on recently! As far as I know, this is the first time LabVIEW R&D has been able to run a Pioneer program to get customer feedback on a research project.

    I'd like to emphasize that this is Research. This version of LabVIEW is a Pioneer. That could mean many things, but in this case it means that this version is not approved for production work and the features in it are not guaranteed to be in any future version of LabVIEW.

    If you see something you like or dislike in this Pioneer, please let us know! This is an opportunity for you to directly affect the future design of LabVIEW.

    I encourage you to watch these two short videos on the LabVIEW Notebook:

    • (on YouTube)
    • (on YouTube)

    If you have time to "get behind the wheel," please join the LabVIEW Notebook Pioneer program and try it out. Although it's not actually a Beta, we're running the Pioneer through the Beta Program Resource Center, so to sign up go to ni.com/beta and select the product LabVIEW Notebook.

    Once approved to the program, you'll receive an e-mail invitation to join a private group on ni.com/Community. That's where you can download the Pioneer and discuss it on our private forum.

    Note that the LabVIEW Notebook is intended to complement the LabVIEW Project, not replace it. However, if you have ideas for how concepts in the Notebook could be applied to Projects as well, we'd love to discuss them with you!

  6. Is there official NI terminology for the concept I called fully connected? What do you think should be the best term for the concept? Somehow it resembles mathematical concept of connected manifolds. Maybe reverse or inverse connected could be more clear. They somehow tell that input need not always terminate to output terminal but instead output terminal must always originate from input terminal.
    Well, I have a term for this that I use in the code. I've never had a need to expose users to that term. In general, as in the Error List Window, we talk about run-time type propagation, as in, "The run-time type must be propagated from dyn input to dyn output." We also use "run-time type preservation," which is how the new LV 2009 primitive "Preserve Run-Time Class" got its name. In the code, I call these two terminals "thralled", since the result of the successful propagation is that the output terminal's type is now thralled to the input terminal's type. I picked this somewhat arcane term because it was unique in the LV vernacular, whereas "linked" or "chained" or "bound" had other uses. If you'd like to use that term, I can guarantee that nothing else in LV uses that term, either in the code or in public.
    Inplaceness is a competely parallel orthogonal concept. It is a compile time optimization technique used by LabVIEW to reuse buffers. The concept of inverse fully connected wires is about type propagation, if runtime output type can be guaranteed to be a function of runtime input type(s), irregardless how the VI is executed.
    To restate this using my terminology... "If the input terminal is successfully propagated to the output terminal then the output terminal is thralled to the input terminal. Given this guarantee, when a subVI is written to take a parent class but the subVI node's input terminal is wired with a child class, automatic downcasting can convert the output terminal to match the input terminal."
    • Like 1
  7. If you open a class that can't find a member of the class, you get this message in the error dialog:

    post-5746-125607842852_thumb.png

    Note that it doesn't tell you what file(s) are missing. This makes it a real pain to figure out what is 'wrong'.

    The project window should have a bright yellow triangle next to the missing file name.
    Note: the reason I got this dialog is because LabVIEW crashed while I was editing my class so some changes to the class library (including members that were renamed) were lost.
    Sorry about that. If you can reproduce it, please CAR it.
  8. Theres a lot of bugs from 2007 and 2008 that are still unresolved.
    Older bugs than that are still unresolved. The priority of fixing any given bug varies. Severe bugs are addressed quickly. Lesser bugs may be pushed off until enough of them are found in a feature to warrant a developer revisiting the code. Some bugs are simply declared "that's the way it works" and left as known issues because fixing them would create other issues. And others we just haven't had time/resources to get to yet.
  9. Regarding benchmarks, one of the FPGA team passed along this tidbit:

    You can compile FPGA VIs on a computer that is not attached to any LabVIEW FPGA targets, which lets you see the resource utilization and whether the code met timing constraints. In other words, you can do a reasonable deal of benchmarking without access to the hardware; you do need to have LabVIEW FPGA and NI-RIO installed to compile for a cRIO system.

  10. You could combine this technique with a class global that defines the name of the SEQ. If would be written to by the very first instantiation of the class. the name could be in the form of the class name with a random number appended to the name. All other methods would access your global data using the SEQ and the randomly generated name to obtain your queue reference. Using this method it would be very difficult for someone outside the class to get a reference to the queue.

    Or, more simply, just get an *unnamed* ref and put that into the into the class global, rather than the name. Now any member of the class can get the SEQ refnum from the global, without having to create and manage a refnum themselves, and there is no way for anyone outside of the class to get the reference, no matter how much guessing of names that they try.
  11. Thx for the quick reply.

    Same size as the class itself or same as self+parent(s)? I guess dynamic dispatching on FPGA is then some hierarchy of hidden case contructs in the background? (too bad all the intermediate .vhd file are encrypted these days :( )

    Sorry -- I include the parent cluster in the size of the child... that's me having too much knowledge of what goes on behind the scenes. ;-)

    Dynamic dispatching is entirely folded out in the compiler -- if we cannot resolve it to a static dispatch at compile time, the VI returns a compile error.

  12. If LVOOP only allowed us to use a NEW flavor of global maybe called a WORM (Write Once Read Many) Global, taht had the first call built in, I would stop pick at this idea. The other plus of the WORM Global is that I would be able stand behind Yair's age old idea of using Globals for defining constants.
    If you want write-once-read-only-thereafter, you *don't* want a global VI. My suggestion of the global VI as class static data [aka data common to all instances] is specifically for the cases where it would be modified from time to time. The list of methods of any given class should be trivially short enough to confirm that none of them is abusing the global VI, something not possible with a truly open global VI.

    If you want a "set once and read only thereafter", just write an LV2-style global with the First Call primitive. That's trivially done in LV today. Here's an example:

    post-5877-125555570296_thumb.png

    The input terminals are Recommended, not Required.

  13. I follow you right up until I have two seperate threads running that both try to set the method when they start. From what I read in your reply, the developer is responsible for ensuring only one entity tries to do use the Set method.
    First Call primitive can take care of that... just put all the code in a case structure that only executes if First Call is true. Thus even if multiple calls are made, the later calls are ignored. Does that solve the problem?
  14. Option A

    Inside the XControl and with a read-only property a VI could get the user event and register for it.

    Pro: you have a tight integration between the control and the event. Using the Init and Uninit abilities you can exactly define when to create and destroy the event references

    - you can have multiple listeners

    Con: you can create useless event references which get very much events which are never written.

    Why would you create useless event references? You shouldn't actually create the event reference until someone calls the property to get the reference. You do the creation in "UserEventReference Read.vi" on demand, not when it is constructed. You can have a single event that the facade knows how to process that is "add this event reference to the references my event structure is already registered for" that you fire the first time someone calls the property read to create the event. Your facade VI processes this meta-event to add to the array of registered references.

  15. Then some of the data is dumped into global variables as well, just for good measure. I'm not a global variable basher. I believe they are a tool that can be used effectively when done properly on a limited basis by someone who knows how and when to use them, but this is crazy.
    Your comments reminded me of a about a use of global VIs that might redeem them in the eyes of many LV programmers. I've been meaning to start the discussion, and your post here got me to do so. I posted the topic here.
  16. A topic that has never come up on LAVA or in any of the presentations/discussions I've been involved in in the last three years:

    There is a general repudiation of global VIs among advanced LV programmers. Generally, globals are good until the first time you are sorely burned by them, and then you develop an allergy to them that gets stronger with time, especially as you discover techniques that give you other ways to share data in your programs.

    The argument against globals is

    1. They allow any random VI any where in your system to change values, making it hard to write stable, proveably-correct code.
    2. They always create a data copy on read.
    3. They are subject to the read-modify-write race condition if used in two places in your code in parallel.

    But the argument from the other side is that

    1. global VIs are so easy to write compared to [insert alternate mechanism here]
    2. You can search and find all uses of a global VI, which you cannot do with Data Value Reference (DVR) and single-element queues (1EQ). You can search for all uses of LV2-style globals (LV2), but most of the time, those are written with a simple get/set, which means they have the same data copy and read-modify-write danger. So why not just use a global VI?

    The argument is one for the ages.

    But now we have LV classes, or any library, really. With a library, we can create a global VI and make it private scope. Now we know that the global VI is only used by a finite set of VIs -- those that are members of the class. We can guarantee that any read-modify-writes are either done singly or can be guarded by semaphore locks. We can combine the global VI with a DVR, so that the global VI stores the refnum of the DVR for easy lookup, and let the DVR be used to avoid the data copies.

    The original presentation of LVClasses mentioned the use of global VIs as a good way to implement data common to all objects of a class (called class static data by C++/C#/Java programmers). But the question of whether this is a good recommendation has never come up. Given all of this, I now formally ask the question: should a global VI that is given private (or community, since the same finite-set-of-VI-arguments apply) scope be considered acceptable LV coding practice? Would a VI hierarchy that used globals in that way be acceptable in the LAVA Code Repository?

×
×
  • Create New...

Important Information

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