PA-Paul Posted November 3, 2009 Report Share Posted November 3, 2009 Hi All, Quick question. I'm writing a user interface based on using an event structure in a while loop (nothing unusual there!). However, to keep it simple I run the code for each UI generated event within the event structure. The problem is, some of the "events" may take some time to complete, and I need one or two controls to be accessible at all times (an interrupt and an exit etc). The events themselves are based on calls to a queued state machine in a separate VI, so they are inherently interruptible, but of course whilst they're running the event structure loop is essentially "stuck" and wont respond to an interrupt. Would it be "bad labview" to include a second event structure loop which only responds to the "interrupt" type controls (this would then allow me to fire an interrupt command into the queue of the subvis "engine" doing all the work)? Or should I re-write my UI as (another) queued state machine, whereby the state machine runs the longer tasks and the event structure driving the UI state machine can also fire things into the engine queue for interrupts? Any thoughts or suggestions welcome! Cheers Quote Link to comment
jcarmody Posted November 3, 2009 Report Share Posted November 3, 2009 Would it be "bad labview" to include a second event structure loop which only responds to the "interrupt" type controls (this would then allow me to fire an interrupt command into the queue of the subvis "engine" doing all the work)? Or should I re-write my UI as (another) queued state machine, whereby the state machine runs the longer tasks and the event structure driving the UI state machine can also fire things into the engine queue for interrupts? Any thoughts or suggestions welcome! Cheers You're Ok if your second Event Structure is in a separate loop. Take a look at the Caveats and Recommendations when Using Events in LabVIEW. I like to put my logic in its own state, called by the Event Structure rather than in it. This allows me to use it again apart from an event (and without using a "Value (Signaling)" Property Node to fire the event - I hate that). Jim Quote Link to comment
PA-Paul Posted November 3, 2009 Author Report Share Posted November 3, 2009 You're Ok if your second Event Structure is in a separate loop. Take a look at the Caveats and Recommendations when Using Events in LabVIEW. I like to put my logic in its own state, called by the Event Structure rather than in it. This allows me to use it again apart from an event (and without using a "Value (Signaling)" Property Node to fire the event - I hate that). Jim Thanks for that. I realise each and any event structure would need to be in it's own loop. I was just curious if it was considered a "bad idea" to have two event structures in one UI VI... It does feel a bit strange/dirty having essentially two loops dealing with user interface events, but it does mean I don't end up writing another queued state machine to control a queued state machine which in turn is controlling another queued state machine! Quote Link to comment
Cat Posted November 3, 2009 Report Share Posted November 3, 2009 Any time your users can kick off multiple simultaneous, long-term events, you're probably going to have to have multiple structures to deal with that. I use multiple loop/event structures often. I've tried both putting the code inside the event structure and also calling it from a queue. I'd have to say I like the code-inside-the-event frame version better for most applications. It takes up less screen space, and in a particularily complex piece of code, I don't have to go hunting around for the right queue handler. Quote Link to comment
Mark Smith Posted November 3, 2009 Report Share Posted November 3, 2009 If I understand the question correctly, I think the best solution in this case is just to start the queued state machine that's handling the events in a separate thread. I presume you're calling the queued state machine inside the event case and it's blocking until it completes. If that's true, why not just handle the event case by putting the request on the state machine queue and returning immediately? Then the UI will be ready to handle any button clicks and pass the message on to the state machine thread - of course, I may have completely misunderstood the problem. At any rate, I find having more than one event structure on a UI to be a complete PITA. I think there's only one event queue (the real experts can weigh in here) so I find you have to carefully enable/disable controls because any control not handled by the currently active event loop that gets in the queue can cause the application to block forever - the event structure you hope will handle the event can't execute because the other event structure is waiting. This can be avoided and I know some people make this work, but every time I've tried it I've eventually found a better way. Mark Quote Link to comment
Grampa_of_Oliva_n_Eden Posted November 3, 2009 Report Share Posted November 3, 2009 If I understand the question correctly, I think the best solution in this case is just to start the queued state machine that's handling the events in a separate thread. I presume you're calling the queued state machine inside the event case and it's blocking until it completes. If that's true, why not just handle the event case by putting the request on the state machine queue and returning immediately? Then the UI will be ready to handle any button clicks and pass the message on to the state machine thread - of course, I may have completely misunderstood the problem. At any rate, I find having more than one event structure on a UI to be a complete PITA. I think there's only one event queue (the real experts can weigh in here) so I find you have to carefully enable/disable controls because any control not handled by the currently active event loop that gets in the queue can cause the application to block forever - the event structure you hope will handle the event can't execute because the other event structure is waiting. This can be avoided and I know some people make this work, but every time I've tried it I've eventually found a better way. Mark This thread on the dark-side http://forums.ni.com/ni/board/message?board.id=170&message.id=245990#M245990 is a very in-depth discusion of the event structure and who gets waht when and under what conditions. It is not lite reading but it digs into every hole we could think of. Ben 1 Quote Link to comment
PA-Paul Posted November 3, 2009 Author Report Share Posted November 3, 2009 If I understand the question correctly, I think the best solution in this case is just to start the queued state machine that's handling the events in a separate thread. I presume you're calling the queued state machine inside the event case and it's blocking until it completes. If that's true, why not just handle the event case by putting the request on the state machine queue and returning immediately? Then the UI will be ready to handle any button clicks and pass the message on to the state machine thread - of course, I may have completely misunderstood the problem. At any rate, I find having more than one event structure on a UI to be a complete PITA. I think there's only one event queue (the real experts can weigh in here) so I find you have to carefully enable/disable controls because any control not handled by the currently active event loop that gets in the queue can cause the application to block forever - the event structure you hope will handle the event can't execute because the other event structure is waiting. This can be avoided and I know some people make this work, but every time I've tried it I've eventually found a better way. Mark Basically, we have a low level "engine" VI which deals with low level commands for the system we're controlling. We then have several "intermediate" level vis which call this engine to perform specific tasks made up of multiple use of the low level commands. Above this we have the UI which as well as being able to call the low level stuff, calls the intermediate level VIs to perform the automated tasks. I need to be able to interrupt the engine (from the UI), but at present since the code in the UI is within the event structure, when one of the intermediate VIs is called, it "blocks" the event structure loop until it completes, meaning that I can't interrupt the engine as my UI won't do anything until the intermediate VI completes. The way I see it there are two solutions - the simplest is to add a second event structure loop which is only triggered by 2 or 3 "interrupt" type controls. This structure can be used to send interrupt commands down to the engine level (via the queue setup we have in place) even if the main UI event structure is waiting for an intermediate VI to complete. The alternative is to shift to a queued state machine in the UI, so I have one event structure which, when triggered, fires instructions into the state machine which can then deal with the intermediate VIs - leaving the event structure free to fire interrupts down to the engine if necessary. The disadvantage here is that I need to recode what I've already done, and you add yet another state machine to the mix (the intermediate VIs calling down to the engine are largely queued state machines, as is the engine itself!). Hope that clarifies what I'm trying to achieve! Cheers for the comments Paul Quote Link to comment
Mark Smith Posted November 3, 2009 Report Share Posted November 3, 2009 Basically, we have a low level "engine" VI which deals with low level commands for the system we're controlling. We then have several "intermediate" level vis which call this engine to perform specific tasks made up of multiple use of the low level commands. Above this we have the UI which as well as being able to call the low level stuff, calls the intermediate level VIs to perform the automated tasks. I need to be able to interrupt the engine (from the UI), but at present since the code in the UI is within the event structure, when one of the intermediate VIs is called, it "blocks" the event structure loop until it completes, meaning that I can't interrupt the engine as my UI won't do anything until the intermediate VI completes. The way I see it there are two solutions - the simplest is to add a second event structure loop which is only triggered by 2 or 3 "interrupt" type controls. This structure can be used to send interrupt commands down to the engine level (via the queue setup we have in place) even if the main UI event structure is waiting for an intermediate VI to complete. The alternative is to shift to a queued state machine in the UI, so I have one event structure which, when triggered, fires instructions into the state machine which can then deal with the intermediate VIs - leaving the event structure free to fire interrupts down to the engine if necessary. The disadvantage here is that I need to recode what I've already done, and you add yet another state machine to the mix (the intermediate VIs calling down to the engine are largely queued state machines, as is the engine itself!). Hope that clarifies what I'm trying to achieve! Cheers for the comments Paul So, I think I understood the question and I still would avoid two event structures on the same BD. The reason is because every time I've gone down this rabbit hole ("Oh - we forgot to tell you we need an Abort button!") I've ended up doing your alternative two and building some sort of asynchronous message handler so the event structure never blocks. The only other thing that I've used that might be useful in your case is to launch a dialog panel on entry into the blocking case that exposes an "interrupt" button and handles queuing up the message to the state machine. This might even be as simple as adding this button to the blocking VI and then opening its front panel. Just my observations - ymmv Mark Quote Link to comment
Daklu Posted November 3, 2009 Report Share Posted November 3, 2009 Basically, we have a low level "engine" VI which deals with low level commands for the system we're controlling. We then have several "intermediate" level vis which call this engine to perform specific tasks made up of multiple use of the low level commands. Above this we have the UI which as well as being able to call the low level stuff, calls the intermediate level VIs to perform the automated tasks. I need to be able to interrupt the engine (from the UI), but at present since the code in the UI is within the event structure, when one of the intermediate VIs is called, it "blocks" the event structure loop until it completes, meaning that I can't interrupt the engine as my UI won't do anything until the intermediate VI completes. The way I see it there are two solutions - the simplest is to add a second event structure loop which is only triggered by 2 or 3 "interrupt" type controls. This structure can be used to send interrupt commands down to the engine level (via the queue setup we have in place) even if the main UI event structure is waiting for an intermediate VI to complete. The alternative is to shift to a queued state machine in the UI, so I have one event structure which, when triggered, fires instructions into the state machine which can then deal with the intermediate VIs - leaving the event structure free to fire interrupts down to the engine if necessary. The disadvantage here is that I need to recode what I've already done, and you add yet another state machine to the mix (the intermediate VIs calling down to the engine are largely queued state machines, as is the engine itself!). Hope that clarifies what I'm trying to achieve! Cheers for the comments Paul I agree with Mark on this. You're at a point where your application requirements cannot be satisfied by keeping your logic inside the same loop as the event structure. Don't try to fix it with band-aids--take the time to refactor it correctly. Break out the intermediate level vi calls into a second queued state machine and send it messages from your UI loop. You'll thank yourself later. Quote Link to comment
PaulL Posted November 3, 2009 Report Share Posted November 3, 2009 I, too, advocate what is really the Model-View-Controller separation principle. The UI should just handle UI actions and send messages to the controller, which determines how to handle the requests from the UI. A quite elegant way to do this is with the (object-oriented) Command Pattern. In our case we send objects flattened to strings via a single shared variable. (We have implemented this as an asynchronous message system.) This works great! Other approaches already suggested will work fine, too. If it fits your plan at all it really is worth it to separate the UI from the controller! Quote Link to comment
Cat Posted November 3, 2009 Report Share Posted November 3, 2009 Yes, but... (apologies if I'm hijacking this thread) I've been looking at some code I wrote quite some time ago that has an event structure that passes messages to a queue with lots of code underneath it. I think the only reason I did it this way was there were a few bits of code I could reuse by just sending different inputs triggered from different events. I would have had to copy the same code to those events, otherwise, or put it in an event with a "value signaling" trigger (jcarmody, I believe this is what you were talking about?). But this was a rare case and usually I have code in events that is unique. And even tho I'm doing it this way, I still have to be very careful about what controls are enabled/disabled when. My users like to randomly push buttons when they're bored... But if it wasn't for the code reuse issue, I'm not sure what generally the benefits are to separating the event and the code for the event. I'm not buying the "more elegant" concept (which is subjective, anyway). I look at my event/queue code and see it being less readable since the action and reaction parts are separated. I also see twice as much BD space being used. And I see one loop having to rely on another loop for its stop signal (that's one of my least favorite "rabbit hole"). I don't call that "elegant". So if there are real hard technical reasons why I should go to using the event-to-queue paradigm on a more regular basis (keeping in mind that I have no issue with using multiple event structures when necessary), please tell me! Old cats *can* learn new tricks. (And bonus points if you can convince me it means LV will make fewer copies of my Really Big data sets ) Quote Link to comment
Mark Smith Posted November 3, 2009 Report Share Posted November 3, 2009 Yes, but... (apologies if I'm hijacking this thread) I've been looking at some code I wrote quite some time ago that has an event structure that passes messages to a queue with lots of code underneath it. I think the only reason I did it this way was there were a few bits of code I could reuse by just sending different inputs triggered from different events. I would have had to copy the same code to those events, otherwise, or put it in an event with a "value signaling" trigger (jcarmody, I believe this is what you were talking about?). But this was a rare case and usually I have code in events that is unique. And even tho I'm doing it this way, I still have to be very careful about what controls are enabled/disabled when. My users like to randomly push buttons when they're bored... But if it wasn't for the code reuse issue, I'm not sure what generally the benefits are to separating the event and the code for the event. I'm not buying the "more elegant" concept (which is subjective, anyway). I look at my event/queue code and see it being less readable since the action and reaction parts are separated. I also see twice as much BD space being used. And I see one loop having to rely on another loop for its stop signal (that's one of my least favorite "rabbit hole"). I don't call that "elegant". So if there are real hard technical reasons why I should go to using the event-to-queue paradigm on a more regular basis (keeping in mind that I have no issue with using multiple event structures when necessary), please tell me! Old cats *can* learn new tricks. (And bonus points if you can convince me it means LV will make fewer copies of my Really Big data sets ) As usual, there is no "wrong" or "right" answer - only shades of gray...... But here's a couple of reasons to consider decoupling the actual "code that does something" from the UI 1) Responsiveness - if you have any action that takes a long time and your program is capable of doing something else (safely) then it's best to let the user continue to interact rather than locking them out and making them wait. For instance, an app that takes data for a long period (more than seconds) might be quite capable of loading and displaying previously acquired data sets while it takes new data. 2) Flexibility - if you have a state machine, for example, that can be queue-driven then you can call it in many different ways. If your state machine is effectively coupled to your UI, that's about the only way you can make it run. Having the "stand-alone" state machine makes it much easier to automate, both for test and deployment. But sometimes it does make sense to just have the code in the event-driven UI, like a data viewer, for example. Here the only use case is human-driven interaction so there's no sense in mucking it up with anything complicated. But I would still argue that if you find yourself needing multiple event handlers in a UI, then the UI is trying to do too much and the program logic needs to be separated from the UI (like the Controller in Paul's example). Mark Quote Link to comment
Cat Posted November 3, 2009 Report Share Posted November 3, 2009 As usual, there is no "wrong" or "right" answer - only shades of gray...... Not unexpectedly... 1) Responsiveness - if you have any action that takes a long time and your program is capable of doing something else (safely) then it's best to let the user continue to interact rather than locking them out and making them wait. For instance, an app that takes data for a long period (more than seconds) might be quite capable of loading and displaying previously acquired data sets while it takes new data. Well, I've already admitted to the heresy of being willing to put multiple loop/event structures on one BD (back to the original thread). That's how I deal with the exact example you give. 2) Flexibility - if you have a state machine, for example, that can be queue-driven then you can call it in many different ways. If your state machine is effectively coupled to your UI, that's about the only way you can make it run. Having the "stand-alone" state machine makes it much easier to automate, both for test and deployment. I've used a lot of state machines but never had the need to use one that was queue-driven. Or maybe just didn't know that's what I should have been using. Thanks for your input. Quote Link to comment
Grampa_of_Oliva_n_Eden Posted November 3, 2009 Report Share Posted November 3, 2009 ... I've used a lot of state machines but never had the need to use one that was queue-driven. Or maybe just didn't know that's what I should have been using. Thanks for your input. I started a thread in the old version of LAVA asking if the day of the queue-driven SM was behind us. i was suprised to find how many people thought it was "the way to go". I have a project in-house that was developed (by the customer) and we maintain it. The case selector fills the screen from top to bottom. And between pushing to the front vs back of the queue makes it a real nightmare to maintain. For me, I'll stick with the flat versions were at least I can draw a diagram illustrating state transitions. I pefer to spead things out at let as much code as possible run in parallel and the QD-SM forces everything to wait in line. But I as I ack'd earlier, I am in the minority. Ben Quote Link to comment
shoneill Posted November 3, 2009 Report Share Posted November 3, 2009 I started a thread in the old version of LAVA asking if the day of the queue-driven SM was behind us. i was suprised to find how many people thought it was "the way to go". I have a project in-house that was developed (by the customer) and we maintain it. The case selector fills the screen from top to bottom. And between pushing to the front vs back of the queue makes it a real nightmare to maintain. For me, I'll stick with the flat versions were at least I can draw a diagram illustrating state transitions. I pefer to spead things out at let as much code as possible run in parallel and the QD-SM forces everything to wait in line. But I as I ack'd earlier, I am in the minority. Ben For What it's worth I don't like queue-driven SM at all. I use Events far more than Queues, although I must admit Queues have their place too. Shane. Quote Link to comment
jcarmody Posted November 3, 2009 Report Share Posted November 3, 2009 [...] The case selector fills the screen from top to bottom. [...] I love those. But, only one screen full of states? That's rather small. That was my motivation for writing the CaseSelect JKI-RCF Plugin. Quote Link to comment
Grampa_of_Oliva_n_Eden Posted November 3, 2009 Report Share Posted November 3, 2009 I love those. But, only one screen full of states? That's rather small. That was my motivation for writing the CaseSelect JKI-RCF Plugin. <<< Please note Smiley before reading on. But when it comes to "one of those", I would tend to follow the advice in the second line of your signature. <<< Remeber, I used a smiley face? Ben Quote Link to comment
Mark Smith Posted November 3, 2009 Report Share Posted November 3, 2009 Uncle! Uncle! - I don't often use queued state machines either - it was just an example What I do use is lots of asynchronous code and lots of VI server calls to start the VIs in new threads and return - it's required by the nature of my current projects. And I never need more than one event handler per BD because the event handler always returns rather quickly. And I can leave the "Lock Front Panel Until This Event Completes" option checked and LabVIEW will prevent the user from clicking anything else until the event handler is ready - and that's all I have to do. Since I am simple-minded, I tend toward the simple solutions Mark Quote Link to comment
crelf Posted November 3, 2009 Report Share Posted November 3, 2009 I started a thread in the old version of LAVA asking if the day of the queue-driven SM was behind us. i was suprised to find how many people thought it was "the way to go". For What it's worth I don't like queue-driven SM at all. I don't understand the loathing of the humble Queued Message Handler (QMH) state machine. Like every architectural pattern, it has it's uses and can be abused. We have a reuse library that encapsulates the QMHSM and it works great - as long as it's used appropriately. I can't see me suggesting that any pattern is inappropriate for all situations. Quote Link to comment
shoneill Posted November 3, 2009 Report Share Posted November 3, 2009 (edited) I don't understand the loathing of the humble Queued Message Handler (QMH) state machine. Like every architectural pattern, it has it's uses and can be abused. We have a reuse library that encapsulates the QMHSM and it works great - as long as it's used appropriately. I can't see me suggesting that any pattern is inappropriate for all situations. If I was using Queues for communication I'd use the QSM. Since I tend to use events, I have an event-driven State Machine. I've said nowt about the merits of state machines, only the queue-driven ones. Shane. Edited November 3, 2009 by shoneill Quote Link to comment
jcarmody Posted November 3, 2009 Report Share Posted November 3, 2009 When I chimed in on the QD-SM, I was referring to the JKI String-Based Queued State Machine. I'm not sure how to avoid having many states if my ATE performs many functions using many devices. One thing I'm avoiding (like the plague H1N1 FUD virus) is making one state perform multiple functions. Each state does one thing and I call it wherever I need that function (using Macros). This results in a long list. What else can I do? However, I must say, that the CaseSelect RCF plugin makes it a piece of cake. Jim PS - Ben, I've read enough of your posts to put the best possible construction on anything you write. Quote Link to comment
ShaunR Posted November 3, 2009 Report Share Posted November 3, 2009 When I chimed in on the QD-SM, I was referring to the JKI String-Based Queued State Machine. I'm not sure how to avoid having many states if my ATE performs many functions using many devices. One thing I'm avoiding (like the plague H1N1 FUD virus) is making one state perform multiple functions. Each state does one thing and I call it wherever I need that function (using Macros). This results in a long list. What else can I do? However, I must say, that the CaseSelect RCF plugin makes it a piece of cake. Jim PS - Ben, I've read enough of your posts to put the best possible construction on anything you write. The JKI State Machine Plugin........ The quickest way to turn a dataflow language into a procedural one Quote Link to comment
crelf Posted November 3, 2009 Report Share Posted November 3, 2009 If I was using Queues for communication I'd use the QSM. Since I tend to use events, I have an event-driven State Machine. Ahhhhh - my misunderstanding. I agree. Quote Link to comment
Daklu Posted November 3, 2009 Report Share Posted November 3, 2009 (edited) The JKI State Machine Plugin........ The quickest way to turn a dataflow language into a procedural one I agree with this comment, but it's not a fault of the JKI State Machine or state machines in general. From what I've seen it's due to the way people use the state machine architecture. (Me included.) Most state machines I've seen are a combination of "sequence machines" where a series of states are called in the same order every time and "procedure machines" where a specific state essentially takes the place of a sub-vi. I don't think I've ever heard of a developer actually sitting down to figure out what the valid states of his application are and developing around that. Edited November 3, 2009 by Daklu Quote Link to comment
jcarmody Posted November 4, 2009 Report Share Posted November 4, 2009 I agree with this comment, but it's not a fault of the JKI State Machine or state machines in general. From what I've seen it's due to the way people use the state machine architecture. (Me included.) Most state machines I've seen are a combination of "sequence machines" where a series of states are called in the same order every time and "procedure machines" where a specific state essentially takes the place of a sub-vi. I don't think I've ever heard of a developer actually sitting down to figure out what the valid states of his application are and developing around that. ShaunR and Daklu have me confused. I'm not sure what to ask, but I thought I was following good practices. Can you 'splain? I believe I understand what you mean by a "sequence machine", but product testing requires performing a sequence of operations and testing the result. How is this not a state machine? I also think I see what you mean about a "procedure machine"; I use a sub VI in one state to avoid having it (an instrument driver, for example) all over the place. This also lets me keep my BD simple and makes modification incredibly easy. How is this not a state machine? I use data flow everywhere (no local variables for me); how is this procedural and a queue of enums not? I'm missing something. Either I misunderstood your posts or there's something fundamentally wrong with the way I'm working... 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.