LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
dthor

Combine While Loop and Case Structure into new "State Machine" Structure

Status: New

First of all, I know I'm going to get a heck of a lot of flack for this idea. I know how you guys hate changes or additions to core structures Smiley Very Happy

 

 

State Machines and Abortable Sequence Structures are very, very powerful. In my opinion, their only downfall is the fact that they require two structures surrounding the code: a Case Structure and a While Loop (or sometimes For Loop) surrounding that. This takes up diagram space (albeit not an absurd amount) and it is annoying when needing to resize the structures. If you add more code (and are OCD about everything matching up on the BD grid like I am), then you need to resize 2 structures instead of one.

 

My suggestion is to create a new structure that combines these two structures. I believe that this new structure, if implemented correctly, will reduce the number of overused stacked sequence structures by providing a simple yet intuitive core structure that offers the same functionality with more power. This new structure will also make it easier for non-programmers to become familiar with State Machines and their power.

 

Here is what the "State Machine" structure would replace:

Abortable Sequence and State Machine.png      --->     becomes  --->            combined case and While loop.png

 

The S input is a right-click option "Enable State Machine Input" which acts as a shift register and also as the case selector for the state. If "Enable State Machine Input" is disabled, then the iteration terminal i is used as the case selector. The i and Stop If True terminals are shown in every case, and the Stop If True has the option to use default if unwired (False) through another right-click menu (you can see this icon in the 1st "Abortable Sequence" structure). In my example I used an enum as the input, but any valid state machine input would work (string, DBL, boolean, etc.)

 

This would not be a full replacement for the original architecture: sometimes there is code that needs to be run before or after the state, on every iteration. This new structure would not be able to handle that in a nice way (you'd have to copy the code to every case, and that's just silly).

 

 

So, what does everyone think? Where are the flaws? What parts do you like?

 

13 Comments
RavensFan
Knight of NI

"epolde" means ???

KeithTK
Member

I'm happy to see I'm the only one bothered by all these compound rings around my code. 

 

I think this applies naturally to event cases as well.  Event cases outside of a while loop and multiple event cases in a single while loop are shunned by ni from the start, so why let beginners even do it at all?

 

I like smmarlow's graphic for an intuitive blend of the existing structures and agree that the iteration and conditional terminals should be pinned to the borders and slide vertically.  Since the iteration terminal that we never use must be available to support legacy code, why not add a right-click option to display/hide the terminal the way a conditional for loop does?

 

Having a 'use default if unwired' option for the conditional terminal is a nice option, so long as it throw an error when none of the cases wires to it.  I could see dropping in a new structure and glossing over that last detail since some other case will have it wired of course.  And handing newbies a structure that can lock you in an infinite loop with 3 clicks and by default it would.

 

As for the bits of code that sometimes lie between the while and case/event structures, why not add them in as well.  I don't like the concept of tucking them in as *special* cases since you would have to go looking for them whenever opening someone else's code, and especially because you couldn't see both the lead-in and lead-out cases simultaneously, making reading that code as annoying as drilling through a 20 page stacked sequence a lazy programmer has left for you.  Why not keep them visible as panes on the left and right sides of the case structure similar to a timed sequence.  There would be right click options to enable or disable lead-in and lead-out panes individually, again similar to how the timed sequence structure is handled, keeping a familiar way of configuring these more advanced structures.

 

Speaking of timed loops, add an option to convert the while part of the structure into a timed loop.

 

Now if only you could cram in for loops and in-place element structures, you could just call it the "unified structure" and get rid of all the rest.

 

jmorris has a point about queued state machines, but why couldn't you handle them in this manner as well?  Just wire a queue reference to the case selector and the structure would automatically identify an enum element data type (or an enum in the outermost bundle of the type) as the input to the case selector.  A right click option could allow you to identify a different element within the defined data type as the case selector input as well.  To distinguish that this is a queued structure the shift register/case selector terminal should change appearance slightly, replacing the shift register arrow with a miniaturized version of the dequeue (left side) and enqueue (right side) vi icons.  The queue itself would still operate as it usually does, allowing parallel code to enqueue elements, opposite end enqueue, flush the queue, or even steal pending operations from the structure's queue.  The dequeue would still need a way to timeout which I see handled just as event case structures do with an hourglass terminal that pops up when the structure recognizes it's operating on a queue that's been wired to the case selector and optionally adding a timeout case to the structure's list.  This would not be a state defined in the queue's data-type, but a unique case that this specific structure owns to handle things the "timed out?" terminal on queue operations does now.

 

All these variations of multi-functional structures have potential to simplify diagrams significantly and help coach "good users" by making many common newbie mistakes easier to avoid or plain impossible to do.  But transitioning existing code by replacing structure after structure will be tedious.  So I suggest a right click option just like the current ability to replace While with For and vice/versa, but slightly more advanced.  Shift clicking on a case/event structure and a surrounding while loop would display a simple dialog, or a right-click style menu with a "replace with state machine" option and probably would have a few options to choose from in how that takes place.  When doing this replace, labview should use dataflow to determine input or output dependency to the case and move that code into the appropriate left-side or-right side pane while it collapses the while loop down onto the contained case structure.  (Imagine an animation where the while loop keeps reducing in size until it merges to the other structure, mac-style prettiness 😉 )

 

I guess I've been wishing for this magical compact structure for some time since there are several concepts in this post!  Perhaps I should break them out into individual concepts and submit them as ideas separately...

cowen71
Member

I really like this idea. It enforces the idea of what a state machine is and how it is used and of course, allows implementation with fewer clicks.

 

I also like that it enforces good programming techniques with the use of enums for the state machine control. Having had a regular conversation with colleagues who prefer strings for this is so frustrating!!!! 😞