LabVIEW Idea Exchange

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

"create constant" for case structures in Labview

Status: Declined

Any idea that has received less than 5 kudos within 5 years after posting will be automatically declined.

Local variable for case structure

 

I do my best to use state machines and consumer-producer structures using queues that go into case structures for programming my applications. One of the problems I have is it is necessary to make a separate control for the various inputs that go the case structure. This situation is relatively friendly to making new cases (just edit the type def of the control and then got to the case structure and "add case for every value"). However, his takes two steps, is complicated, and is not intuitive - i.e. when I try to teach this to anyone else, it takes some time for them to appreciate how powerful it is.

 

Worse, however, is that it is very unfriendly when I want to remove cases and change the flow of the program, because I have to remove the same cases in a long list of both the control and the case structure.

 

I suggest a new way to do this - allow the case structure to "create a constant" in the wiring diagram that is linked to the case structure, so whenever the case structure is modified, any constants that were created from it are also updated. This would make creating state machines and consumer-producer programs much much simpler. Since the only cases that need to exist are those that are in the case structure, then it is a one-touch modification to add/subtract cases.

 

Please do this quickly, I am getting very tired of having to constantly open the "type def". It is way too much work and really slows down development!

7 Comments
RavensFan
Knight of NI

Let me word things a little more simply and see if this is what you are looking for.

 

You inherently want to link a type def to the cases defined in a case structure?

Rammbler
Member

Just linking a type def would be close - it may be all that is possible, but I don't think it addresses the key issues. My understanding of that would be that it would be necessary to create a ring variable or something, make a type def, then connect that type def to the case structure, then link them together. It would still be necessary to open the type def to add cases. This is still complicated - I can't get my postdocs to understand that, they would still rather just program Matlab.

 

The vision I had was more in the line of creating a case structure, then right clicking on the selelector and creating a constant (this might just create a type def, as you say). That constant would then be linked to the case structure, so if I added cases to the structure, they would appear in all of the constants. It may be necessary to add a name tag to the case structure, so it would be more like making a local variable.

 

I hope this is more clear. The problem I am trying to solve is that it is really hard to manage the type defs and case structures simultaeously. It seems that since the case structure is already there, then the cases are already somewhere in memory and should be able to be used programmatically. This would increase the useability and power of Labview state machines and consumer-producer environments greatly.

AristosQueue (NI)
NI Employee (retired)

It's a request that makes sense, but it wouldn't be easy to explain to a new user as I cannot think of an analogous situation in other programming languages. It's worth exploring the user experience. I'll add my kudos.

GregSands
Active Participant

If I understand right, I think you're asking for the Case Structure (or some derivative of it) to be an Enum?  That would make it the BD equivalent to a Tab Control, which does make sense.  Then it would be easy to make that a Typedef and have it auto-updated from one place. 

 

Also, I could see benefits in being able to freely switch between any of those representations of an enum (Convert To Enum/Case/Tab).  But that would probably require Tab to be a subclass of Enum instead of being out on its own - don't know why that is, but I'm sure there was a good reason!

 

Rammbler
Member

Thanks for the comments and support. The new user aspect is critical - it is extremely difficult to explain both the queue function and then the case structure + type def to a user, not to mention the consumer-producer. In my experience, however, people tend to "tilt" when I try to explain about custom controls and typ defs, and then start explaining about how to add and subtract cases.

 

This is exactly why people would want to use labview in the first place. I myself am a converted Visual Basic user, and it is just because I want to be able to read the code after not seeing it for a year or two. If I  have to start writing down which cases are in the selector vs. the type def in order to syncronize them, it defeats the purpose of visual programming.

 

Also, the synchronization gets messed up if someone changes the names of cases in the type def.

 

 

AristosQueue (NI)
NI Employee (retired)

Greg: Rammbler's use case is something like this:

 

Drop a case structure (aka CS). Pop up on it and select "Make Typedef".

This does the following:

  • It creates a typedef  .ctl that the user never sees, saved inside the VI that hosts the case structure. That enum is initially populated with something like "First" and "Second".
  • It automatically creates an enum constant of the typedef wired to the ? terminal.

User can copy that enum constant around, change it to a control, etc. When user right clicks on the enum and says "Open Typedef", they get a zoom highlight on the Case Structure, not on any control.

 

If they edit the frames of the case structure, it automatically updates the typedef. So if they add a ""Third"" case, then a new entry would appear in the typedef (and thus update all constants/controls). If they rename ""First"" as ""Uno"", it would update the typedef. (I'm using double quote marks because that's going to become important in a moment when we get to lists.)

 

Where things get weird: If they have an existing frame ""Second"" and they change the text to be ""Second", "Fourth"", that means add a new state named "Fourth" to the typedef.  But if they have an existing state ""Second", "Fourth"" and they change that to ""Alpha", "Beta", "Gamma"" -- is that deleting Second and Fourth and adding three new items at the end of the enum? Or is that renaming Second and Fourth and just adding Gamma at the end? Probably the second option. Ok... they have "Second..Gamma" and they change it to "Second..Koala" -- did they mean to rename Gamma or are they adding a new state Koala right after Gamma?

 

There are many more weird states ... which probably means we change tactics entirely and say, "Every frame can contain at most one entry." There is no Default allowed.  In other words, if the CS is serving as an enum typedef, we disallow the more complex multiple case selectors that we usually allow. That way we know what is going on -- the order of the frames in the case structure becomes the order of the entries in the enum, and the name of the frame is the name of the item in the enum. Want a new enum item? Add a new case frame.

 

Ok, good so far. Now... what happens if you delete the last instance of the enum constant? You go back to the CS and do Create Constant on its ? terminal. But what happens if you delete the CS? Does that delete all instances of the enum? Or does that suddenly unhide the typedef so the user still has everything tied to a typedef?

 

You have the enum constant wired to the selector terminals of two case structures. One of them is the typedef. The other is just using the typedef. How do we differentiate so the user knows which one they can edit that will change the typedef and which one they can edit that just changes the local case structure?

 

There's probably a lot of other issues I haven't thought of... it's an unusual glomming together of features. Honestly, I see why the request is being made, and at the same time, it leaves a vaguely bad taste in my mouth, at least as the feature is currently phrased. But I'm having trouble judging if this is because there's actually something problematic that is tingling my spidy-sense, or if it is just different from how I've been coding for 25 years.

 

AH. When I contemplate it from C++ code, I see why I don't like it.

 

It would be like in C++ if you never declared an enum type. You just had a switch statement that you used to define the enum type. Consider...

 

MyEnum ReadFromSource(int y) {

   return y > 10 ? kSecond : kFirst;

}

 

void SomethingThatNeedsToBeDone(MyEnum value) {

    switch (value) {

        case kFirst  : DoOneWay(); break;

        case kSecond : DoTheOtherWay(); break;

        default : DoUnrecognizedAction(); break;

        // Can have default here because this switch doesn't define the enum

    }

}

 

void main(void) {

     int q = ReadIntegerFromKeyboard();

     MyEnum x = ReadFromSource(q);

 

     SomethingThatNeedsToBeDone(x);

 

     typedef MyEnum switch (x) {

        case kFirst  : DoFirstAction(); break;

        case kSecond : DoSecondAction(); break;

        // No default: case needed because this is defining the enum, not using it.

     }

}

 

My hesitation is coming from the fact that some arbitrary piece of code somewhere is defining a data type that is potentially used throughout the code base. It's the strings being harvested from one location and applied out to other co-equal parts of the code base instead of being defined apriori in a central location and then used by all of those places. That leads to the "who is in charge of this enum type" question.

 

I don't see any reason why it couldn't be done. But it feels icky as it stands. But I see why the user is making the request. Anyone know ways to improve this so it doesn't feel so arbitrary?

Darren
Proven Zealot
Status changed to: Declined

Any idea that has received less than 5 kudos within 5 years after posting will be automatically declined.