dannyt Posted July 16, 2009 Report Share Posted July 16, 2009 Good day all, First off, though this post is sort of based on the JKI state machine, I have posted it on Lava as it really covers a wider and more general question of design patterns and therefore, I want to open it to a wider audience I have to opportunity, to rewrite our top level VI for our Test Executive. It currently has a number of separate polling loops to check for user events, and it works on a basic state machine principle, though not to any of the now standard design patterns. I am after something that would allow the UI to be responsive to certain actions even while a long test sequence would be running underneath it. I have spend some time looking at various patterns like Queued State Machine and also the JKI State machine , I do like the simplicity of the JKI state machine and have used it once on a sub-project that went very well for me, however it as it stands will not suit this situation.... or so I though ... and I really need something like the queued state machine. Now my question is this, I was reading a thread on the JKI state machine and something there really hit me... "First, you might want to consider using LabVIEW User Events for passing data instead of queues, that way your UI will never be polling" This brings to mind a Producer / Consumer pattern bases on this idea, whereby both the Producer and Consumer are simple state machines with the Producer generating user event that the Consumers looks for, JimK talks specifically about this pattern in post 10 of the above thread. I really like this idea and I am thinking of trying it for new rewrite, I just wondered about people thoughts and comments on this as it is not really a standard design pattern. cheers Dannyt Quote Link to comment
Antoine Chalons Posted July 16, 2009 Report Share Posted July 16, 2009 [...] I really like this idea and I am thinking of trying it for new rewrite, I just wondered about people thoughts and comments on this as it is not really a standard design pattern. [...] Yep, I've been developing an application based on what Mr. Blum calls in his LabVIEW Style Book the "Modular Multiple-loop Application Framework" (page 283>285), each loop being based JKI SM. I used different techniques for passing data and events (queues and FGVs) depending on the cases, I didn't think of user event because I'm familiar with them but they could surely be a good option! I'm interested in looking more into that :-o Quote Link to comment
dannyt Posted July 16, 2009 Author Report Share Posted July 16, 2009 Yep, I've been developing an application based on what Mr. Blum calls in his LabVIEW Style Book the "Modular Multiple-loop Application Framework" (page 283>285), each loop being based JKI SM. Opening book to those pages and reading now, thanks. Does mean skipping forward as I am only really on page 98 so far cheers Dannyt Quote Link to comment
Black Pearl Posted July 16, 2009 Report Share Posted July 16, 2009 Are you looking for something like this: NI Forum Community Nugget ? Felix Quote Link to comment
Aristos Queue Posted July 16, 2009 Report Share Posted July 16, 2009 "First, you might want to consider using LabVIEW User Events for passing data instead of queues, that way your UI will never be polling"... I really like this idea and I am thinking of trying it for new rewrite, I just wondered about people thoughts and comments on this as it is not really a standard design pattern. Actually, it is a standard design pattern in LabVIEW. NI has presented it in many places. Most recently, it was in the spring 2009 Developer Days conference presentations for "Design Patterns in LabVIEW." The slides are here. Quote Link to comment
Daklu Posted July 16, 2009 Report Share Posted July 16, 2009 Actually, it is a standard design pattern in LabVIEW. NI has presented it in many places. Most recently, it was in the spring 2009 Developer Days conference presentations for "Design Patterns in LabVIEW." The slides are here. So is there a preferred way for a class to expose events to subscriber vis? Here are a few options I've considered but I'm not sure of all the tradeoffs associated with each. Exposing a User Event - Easy to implement for the class developer, but forces the caller to handle all event registration duties, probably leading to duplicate code if events are registered in more than one place. Since user events have data types associated with them it could be harder to implement this is a complex class hierarchy. Exposing a Message Queue - Aside from the UI polling issues, this seems similar to exposing a user event except it 'feels' like it would lead to more tightly coupled code. Different classes may have different message types. Event subscribers would have to implement separate event loops for each class. Accepting an Event Registration Refnum - Have the class expose Register and Unregister methods that implement the prims. Event subscribers pass an event registration refnum to those methods. I think I would prefer this implementation except calling Unregister for Events removes all events from that refnum. The class has no way of knowing what other events are registered to that refnum, meaning the event subscriber has to implement bookkeeping and auto-reregistration routines. Accepting Callback VI Refnums - Same idea as the event reg refnum except the subscriber passes vi references to the registration methods. When the event fires the class automatically executes the callback VIs. The problem with this is I haven't figured out a good way to pass data with the events. If I invoke the callbacks using a Call By Ref node the callback has to finish executing before the thread returns to the class. When multiple callbacks are registered for a single event one poorly written callback could significantly delay (or prevent) other callbacks being executed. Maybe the answer is to require the subscriber to query for data after the event...Any other ideas? Quote Link to comment
David Wisti Posted July 16, 2009 Report Share Posted July 16, 2009 Actually, it is a standard design pattern in LabVIEW. NI has presented it in many places. Most recently, it was in the spring 2009 Developer Days conference presentations for "Design Patterns in LabVIEW." The slides are here. Wow! On slide 55 is a picture of Custy's. I live very close to Custy's but I haven't eaten there yet. Quote Link to comment
unicorn Posted July 27, 2009 Report Share Posted July 27, 2009 Hi, I would like to give some thoughts: I am working on two programs which handels a set of 600 images with approximately VGA resolution. The images will be loaded and processed according to user commands from the run-time menu as well as by pressing buttons. This amount of data cannot be handled by a queue. So the image data need to be stored once in a data repository or using IMAQ Vision Images. The whole dataset cannot be passed as data flow from VI to VI. While working with that I found that it is not really necessary to pass data using a queue. Nevertheless I use a queue in one of the programs. The program is based on a producer consumer loop. The producer is the GUI-Handler which start e.g. the aquisition of the image set by queuing a respective element. The consumer loop detects it and start aquisition. The aquisition process can be stopped from the GUI whereby another element is queued. The aquisition VI will look at the queue and stops if requested. While aquisitions runs the GUI-Handler can perfom other things. GUI-Handler contains a event structure, so that it is not polling for user commands all the time. In conclusion the queue transmits information i.e. certain user events which control the aquisition process. The other programm is using only a while loop with eventstructure. Here I register own user events. No data is passed. the event just carry information. Using user event and having only one event structure (otherwise you run into problems) the user events are handled sequentially with all the other event. there is no parallel processing like with the producer-consumer loop. The event are something like update a plot and produce the right legend. Using user events is only suitable for code with short duration because the user interface is not reacting while the user events are processed. In general I don't see the design pattern as a strict dogma and vary them as needed. Regards Quote Link to comment
Aristos Queue Posted July 27, 2009 Report Share Posted July 27, 2009 In general I don't see the design pattern as a strict dogma and vary them as needed. Completely correct. That's part of why the patterns aren't something that can be implemented once and reused by everyone who needs them. They vary in details for every implementation. Quote Link to comment
ShaunR Posted August 12, 2009 Report Share Posted August 12, 2009 (edited) Accepting Callback VI Refnums - Same idea as the event reg refnum except the subscriber passes vi references to the registration methods. When the event fires the class automatically executes the callback VIs. The problem with this is I haven't figured out a good way to pass data with the events. If I invoke the callbacks using a Call By Ref node the callback has to finish executing before the thread returns to the class. When multiple callbacks are registered for a single event one poorly written callback could significantly delay (or prevent) other callbacks being executed. Maybe the answer is to require the subscriber to query for data after the event...Any other ideas? If you can find my callbacks example (originally posted in the old forum) it does exactly this. A callback is installed to any invoked vi and fires when a control or indicator changes. When a control changes, the callback is invoked automagically, sending the control refnum as a parameter of the event. It is received in the event structure in the main vi and various information about the control (text, value, image) is displayed. This is all that's in the callback: Edited August 12, 2009 by ShaunR Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.