Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    202

Posts posted by Aristos Queue

  1. I disagree and as a proof of concept I wrote an example which simplifies the process of resizing a front panel. Download the attached example and open MyFrontPanel.vi. The example is for LV 8.0.

    This doesn't fullfil the design requirements. The FPResize Manager Implementation.vi is using a timeout value on the event structure. This turns it into a 200ms polling loop, which is exactly what I was avoiding by writing the Notifier implementation. The goal was a VI that uses zero CPU time when the user isn't actively clicking on stuff.

    You did manage to encapsulate the functionality better than I would've expected, but at the cost of using dynamic events, which pushes the technical difficulty of using this API beyond the knowledge of almost all users. The Notifier solution is something that I could explain to people because they've seen Notifiers and they can figure out the Event Structure. Trying to teach dynamic events has proved... difficult. There are good programming reasons why the dynamic events are set up the way they are, and they have extreme power, but they're complex beyond usability most of the time (and, yes, by "complex beyond usability" I do mean the fairly short list of steps of "enable dynamic event terminals, drop a register event node, wire everything, and configure the user event case").

    I can't look at Stephen's code, but here's my version (7.1) - simple and easy. If you get a lot of cases, just use the tunnel wiring wizard.

    Here it is back in LV7.1. Download File:post-5877-1165336751.vi

  2. My problem is with the array of clusters: When I send it in sub to save it is logically ok (however save-02A doesn't work and I don't know where is the error), but when I do a load in sub, how can I get the new array content from the sub? In other words, how can I send the pointer of this array in sub, so that I can use the same memory space for save and for load? How can I pass not a copy of the array in sub, but its address?

    You don't. There is no way to specify the address of anything in LabVIEW. Just wire it through. If the compiler detects that the data that flows in eventually flows out then the compiler will take care of making it use the same memory space. If the wire forks at some point, the compiler will decide whether a new copy is needed or whether a single allocation can fulfill both branches of the wire (if, for one simple example, both branches are only reading the array, not modifying it).

    If a copy is made, then it is because a copy is needed to do the code that you've written. If you don't need it, the compiler shouldn't allocate it.

    You'll find that the bulk of LabVIEW users will stare at you blankly when you start talking about addresses and pointers in memory. That's because there's no reason for them to pay attention to such stuff when working in LabVIEW in all but the most extreme situations. The nature of dataflow is pretty cool from a computer science perspective: Memory is allocated where the wire starts, and deallocated where it ends. Along the way, new copies spawn as needed for the code written.

    There are caveats to the above and moments when really advanced programmers trying to squeeze every drop of performance will turn on various advanced tools to tune the memory allocations, but even then they are just tuning when copies get made, not explicitly handling memory addresses. But in the vast majority of cases, LV will do a better job scheduling memory than a person could in such a highly parallel environment.

    Automatic memory management. Parallel code execution. Optimal thread scheduling.

    Just some of the benefits of a dataflow language. :wub:

  3. I wouldn't use notifiers for the task. This is a functionality you would like to package as subVI library or class library so that it can be reused in any of your applications or in a single application with multiple different windows. In this usage notifiers are unsafe and may freeze the application without "throwing" an error.

    Nonsense. Don't knock a perfectly good feature just because it doesn't serve one use case. In this instance, you can't reasonably package this behavior as a subVI since the event structure is going to have to have other cases specific to whatever events are being processed for this particular dialog. The undertaking of creating a "manager" subVI -- which dynamically registers for panel resize on another VI and then uses VI server to call the "do the resize" functionality -- is overkill compared to just putting the management in whatever dialog you happen to be writing today. I'm not even sure that if you took the effort to create the manager subVI that the API you'd end up with would be less work than just adding the necessary code to each dialog. So, given that there's only going to be one Notifier running through this diagram ever, the case that you link to never arises.

  4. Here is a tool that should work (I just whipped it up). It depends on the OpenG oglib_lvdata library. After some testing and clean-up, I'll add it to the oglib_lvdata library.

    Cheers,

    -Jim

    Jim: Test cases would be a simple class, a class owned by another library and the all important LabVIEW Object class. LVObject is actually encoded slightly different to guarantee that even if you clever users try to name a class "LabVIEW Object" that we can still distinugish the real LV Object class. The encoding for most classes is:

    name = length | cpstrlist

    cpstrlist = [lenghth | text]+

    length = a single character (byte)

    (where | means "followed by" and + means "repeat one or more times as needed)

    The encoding for LabVIEW object is simply

    name = length | "LabVIEW Object"

  5. I suspect that you could get rid of the polling behavior by being clever about posting a user event with a timestamp but I'd have to play with it to get it right. Something about a shift register with a timestamp that the resize event updates, then posts a update UI event. As long as the current value of the shift register is before the value of the timestamp when the user event fires then the user event updates the panel sizes, otherwise it does nothing. Or something like that.

    I knew it was possible to do without polling. Just took a bit to put it together...

  6. BTW, I didn't intend that my comment be an attack. It's just that it's really really wierd to see so many OpenG functions being duplicated within LV8.x.x. Perhaps it's just that NI's LV development team is noticing limitations in the current feature set just like we are.

    No no. It's LabVIEW. We spent most of LV8.0 working on the underlying artificial intelligence. It now mostly writes itself. It has been generating libraries that it thinks it needs for some time now. By now, it should've generated all the library VIs that people on OpenG, NI, LAVA and DevZone combined could think of to write. Unfortunately, it sucks as an artist. Its icons are all text or plaid and its dialogs make a Linux command line seem user friendly. We'd let it ship more libraries, but it does take time to clean up the UI. That's really all we programmers do these days. Oh, and fix the text. LabVIEW decided that most human languages sucked and only deigns to speak to us in Esperanto. Since none of us speak or read Esperanto, we spend hours studying diagrams so we can rename the VIs as whatever it is that they do. It's not really arrogant, more like a teenager out to prove it knows more than its parents. Really, the only disturbing sign so far is the 200 node VI that took hours to puzzle out. It generates a stereogram that if you stare at it long enough displays the words "Hal9000 is my hero."

    As a side note, LV's only comment when we asked it why it didn't have perfect automatic wire routing was, "The rat always complains about the path to the cheese. But the cheese is happy the path is not so direct."

    • Like 1
  7. The panel resize event is tricky tu use. Tens or hundreds of events are fired while the user resizes the panel. If you make something that forces the panel to redraw, it is funny to see the panel keeping redrawing well after the user has left the mouse until all events are serviced. You have to catch when the mouse button up but since the handle to resize the panel is "outside" the panel, it does not fire a mouse button event in the event structure. You have to use the mouse device functions to detect the mouse button up.

    You could also do something like this:

    1. On your event loop, create a boolean shift register whose value is a boolean. Initially the value is FALSE.
    2. Set the timeout of the event structure to 150 milliseconds.
    3. In the panel resize event case, turn off panel drawing. Then set the boolean to TRUE.
    4. In the timeout event case, test the boolean. If the boolean is TRUE then update the control sizes and then enable panel drawing again. If the boolean is FALSE, then do nothing.

    The result is that as long as panel size events come quickly then the timeout event will never fire. When the panel resize events quit coming then you can update. At 150 ms, you'll still get nice smooth drags if the user pauses. This does turn the event structure into one that polls every 150 ms, but since it does nothing except test a boolean, it shouldn't be a burden to your CPU.

    I suspect that you could get rid of the polling behavior by being clever about posting a user event with a timestamp but I'd have to play with it to get it right. Something about a shift register with a timestamp that the resize event updates, then posts a update UI event. As long as the current value of the shift register is before the value of the timestamp when the user event fires then the user event updates the panel sizes, otherwise it does nothing. Or something like that.

  8. Is the source code of these dynamic VIs protected or locked automatically or do I have to lock the block diagram manually? I could try this out but I'm lazy. This is btw something I've never thought of, are the VI block diagrams accessible from an executable?

    The VIs are saved without block diagrams when you build an EXE or library unless you explicitly tell AppBuilder to retain them. Even then the diagrams cannot be loaded by the app builder -- without the editor present, there's no ability to load the diagrams. Front panels can be stripped as well.

  9. I don't know if clearing the error is the use case described. What you really want to do is log errors to file ... so if you clear the error, you've lost the info you need to log. Instead of using the code as it is presented here (an error filter), I would simply add some logic to write the error code, source and time to a log file (ie build an error log). You may or may not want to log all errors --> so you may or may not need to input the error code. If you want to log all errors, you can place your error log function in the Error case of a case structure. After writing the error to file you can clear the error by using the Clear Errors.vi on the Time & Dialog palette and your loop can keep on truckn'.

    Take a look at the General Error Handler.vi. In and among its inputs is the ability to filter the wire value but still output the formatted string of the error so you can dump it to a log file.

  10. All the numeric conversions are either simple bit reinterpretations or IEEE standards for floating point behaviors. I cannot name any programming language that treats type coercion differently. In C, for example, assigning an unsigned int to a signed int will give a compiler warning (equivalent of the coercion dot) but will simply assign the bits without modification. High bit of the unsigned integer becomes the sign bit of the signed integer.

    None of the behavior is wrong. It is right, by definition, as long as it is consistent.

  11. MikaelH, I already put this info in e-mail to you, but I didn't know it was also here on LAVA.

    For the rest -- this is a behavior common to all libraries, not specific to LV classes. The AppBuilder was built in a time when all VIs were expected to have a unique file name. So when it bundles libraries into the EXE, it has to rename any VIs that collide.

    For LVClasses, we put in a hack that saves the dynamic VIs outside of the EXE, since those VIs *must* have matching names. But for static VIs, they follow the same behavior as other VIs in any library.

    A workaround that might work is to make your static VIs dynamic, even though you're not expecting to override them. I don't remember if the hack for dynamic VIs is invoked simply by a VI being dynamic or if that gets invoked only when the VI is overridden.

    This behavior is going to require significant changes to AppBuilder to fix, and it is an area outside of my purview. It gets annoying since it impacts the Factory pattern for LVClasses, which calls for an identically named static VI on a series of classes.

    If you do find a good workaround, please post it here.

  12. Well I am looking into writing an instrument driver using OOP , does anyone have any suggestions as to what type of architecture/pattern would work the best. I think my biggest problem is that in addition to figuring out which design pattern to use as a guide (after looking at it for awhile longer I am currently leaning towards the Specification Pattern along with the Factory Pattern) I also have to figure out how I am going to use the implementation in the real world , any thoughts ???? i know this OOP stuff is new to most everyone , at least in its LV incarnation....

    C'mon, ladies and gentlemen. Surely someone has an opinion on this!

    There's no right/wrong answers here... this is a grand experiment. So even if you have only read about LVClasses, perhaps you can put forth some thoughts on how you might use classes for the instrument driver. This is an unexplored topic, and I was kind of hoping that we might see some wild ideas coming to the fore.

    One note, please don't polute this thread with conversations about "by reference." We've hashed that to death. But I'll guarantee that there are ways that LVClasses can improve the API of an instrument driver written in LV. Dan's question above is mostly about the instrument driver class itself -- representing the instrument. Some other uses of LV classes that I've contemplated are encapsulation of commands to the driver, packaging of data, and error handling.

    So let's hear some brainstorming!

  13. This was reported to R&D (# 43JCLR2K) for further investigation.

    Ye, gods, gentlemen!!! Close your Context Help window!

    That's the crash. I reflexively close the Context Help. So when I tried to replicate what you were seeing, I never could.

    The data type is recursive -- the class uses a VI reference that has the class on its own conpane. While this is perfectly acceptable from a data standpoint, when the CH tries to display the data type of the wire -- when you mouse over it -- it goes into infinite recursion and crashes.

  14. These three files are three of the classes i.e. .lvclass files. These three files are among those 151 files already saved previously, so I wasn't exact enough in my sentence. Also two files from vi.lib belong to these 151 files. I assume the unsaved ones are the 4 polymorphic VIs. 151 saved files + 4 unsaved polymorphic + 1 unsaved lvlib -> 154 files in project + 2 files in vi.lib.

    These recompile bugs are known and will be fixed in the next bug-fix version.

  15. Confirmed - my LabVIEW vanished too...

    It does not replicate inside NI. Another of the LabVOOP team did get it to crash while he was on remote working in California, but cannot get it to replicate now that he's here at NI in Austin. I downloaded a fresh copy of your VIs from LAVA. I tried wiping out my .ini file. I've tried reinstalling my LV8.2 just to make sure I'm clean. I've tried another machine. Nada. I tried Brian's original instructions and Jimi's variations. Nada.

    You guys are working in MSWindows right? This isn't a Linux or Mac bug that I'm hunting, right?

    So at the moment, the best I can say is that when our developer gets back to California, I'll have him investigate this bug. And if it really does replicate when he gets back out to Calif, then I may just hang up my tools and find a new profession.

    :blink::blink::blink::blink:

    For what it's worth...

    This was reported to R&D (# 43JCLR2K) for further investigation.

  16. Well, that is a new one on me in my little circumscribed corner of the LabVIEW world. What is "the TDMS?"

    "Technical Data Management Streaming".

    Introduced in LV8.2. It's a file format created by NI and useable with CVI, LV and Diadem specificially for handling data -- streaming, archiving, reviewing, manipulating -- and is designed for huge data sets.

    That's everything I know about it. Check the online help for LV8.2 for more information.

  17. I haven't experienced runtime crashes but rather weird crashes during development time and weird corruption of the project. Both of these occurred when I started using call by ref node with class methods. EDIT: I wonder if the connector pane constant doesn't get properly updated.

    I cannot replicate this. I've tried everything. I've followed instructions verbatim, I've tried variations, I've tried loading without the project, etc. No crashes when I delete - wire - delete - rewire.

  18. -1st question:

    When I'm reaching a certain number of values (which I set before starting the vi), I want to stop writing to the file and then stop the producer loop (which will result in stopping the VI). What is the best method to send the stop signal from a consumer loop to the producer loop?

    After the producer loop, drop a Release Queue primitive. When that prim executes, it will invalidate the refnum. Any waiting Dequeue in the consumer loop will stop waiting and return an error. Have your consumer loop stop if an error is returned.

    Your second question is something I'm going to leave to others with more experience with determinism, but I suspect the Timed Loop is what you're looking for. Though, with a timing window of a full second, just putting a Wait Milliseconds wired with 1000 into your loop might do the trick.

  19. The behaviour of the standard case structure has been compiler optimized to discard any code eliminated by a constant. Cool.

    So now we also have conditional disable and diagram disable. With the changes in the case structure behaviour the differences are, to me. subtle.

    The "case structure" must have good wires in all of its frames. The "diagram disable" structure may have missing subVIs, broken wires, unwired required terminals and other broken bits in the disabled frames. The "code disable" structure is for multi-platform loading. "I want this to be enabled on Platform XYZ, and that to be enabled on Platform PDQ". This handles cases where you used to have a constant wired to the case structure for "Mac" that, when you loaded on a PC, you had to remember to go find all the instances of that constant and change them to "PC". It's also able to handle other configuration changes using the keywords that you define as part of the project environment. ("I'd like to build a debug version of my VIs, which has all this slow sanity checking code, and now, with just a change to the project, I'd like a release version which leaves out all the double-checking.")

  20. If you have a target userbase that doesn't understand that they need to write a value to a data item before they can read it (eg: I'm talking about you creating and distributing a class)

    I would include the teammate sitting at the next desk. Remember that a lot of OO stuff is about enabling team programming as much as it is about creating encapsulated distributable libraries. And it isn't so much about them not understanding. It's a case of remembering to do so. The goal is to cut down on the memory load of the other developers.

    then you need to wrap it and impliment your own layer between the user and the class.

    That would also work, but honestly the language ought to handle this. It's a problem to consider in the long run.

×
×
  • Create New...

Important Information

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