Jump to content

Case Structures - Is it possible to set which case is displayed?


WMassey

Recommended Posts

I can see that I can get:

a list of all the cases

references to the cases

a reference to the case selector

for the default case, an index pointing to the case number

but I have yet to see a way to set which case is the one that is currently displayed.

Has anyone else noticed a way to do this?

Link to comment
You need the VisFrame property. Wire the index of the frame you want to see.

Thanks! That's just what I needed!

Knowing that missing piece allowed me to put together the attached VI which will sit off to the side of another VI that is being edited and give me a more convenient way of accessing the states/cases in large case structures. This scripting is cool stuff :thumbup:

Download File:post-2800-1127269489.zip

Link to comment
it looks like you need to d/l the tunnel wiring wizard to get rid of all those extra shift registers in the state machine.

I recently got it and it is a slick tool. But before I go and rework all my state machine templates I want to see how the scripting stuff is impacted with the release of v8 of LabVIEW.

Link to comment

Attached is an update to the Select-A-Case VI that I had posted a few days ago.

While using it, it occurred to me that it would be really nice if I could easily jump back & forth between several cases while working with the other VI's case structure without having to continually relocate them in the (in my situation, 78-item) list.

To that end I have added a couple of "browse" buttons that let me jump back & forth among the cases I have chosen to examine.

(I also eliminated the unused shift registers too Norman)

Download File:post-2800-1128108046.zip

Link to comment
Attached is an update to the Select-A-Case VI that I had posted a few days ago.

(I also eliminated the unused shift registers too Norman)

Nice tool!

Some nitpicks on style though. Have you considered the use of bundling all the shift register elements into one cluster and only requiring a single wire to cross through your cases? Those wires take up a lot of real estate and it can be messy to debug.

Another thing. Why do you take the buttons and feed the value into a case structure inside the event frame? This is unnecessary coding. Obviously the button value is true otherwise you wouldn't be in that event case. If you are worried about button staying down then set the mechanical action to "switch when released" Which they should all be set to anyway. I'm not following the purpose of the cases in every event frame.

post-2-1128113798.gif?width=400

Link to comment
Nice tool!

Some nitpicks on style though. Have you considered the use of bundling all the shift register elements into one cluster and only requiring a single wire to cross through your cases? Those wires take up a lot of real estate and it can be messy to debug.

Another thing. Why do you take the buttons and feed the value into a case structure inside the event frame? This is unnecessary coding. Obviously the button value is true otherwise you wouldn't be in that event case. If you are worried about button staying down then set the mechanical action to "switch when released" Which they should all be set to anyway. I'm not following the purpose of the cases in every event frame.

Sometimes on more complicated systems I do bundle lots of shift register elements up into a cluster and pass that around but I have read at least one critique (NI forums) of that style as well (no reason given) and I never have been sure if there was a performance penalty with bundling & unbundling the elements. I must admit it can be easier to follow the logic with bundle/unbundle by name rather than labels sitting on top of wires. As far as real estate, I'd argue that the way I did it takes up more vertical real estate but what you suggest can take up more horizontal real estate so which you chose in that respect depends on what you've got to spend. And, while it is a small thing, it can also be easier to probe individual wires than cluster wires.

I'd love to see a discussion on the pro's & cons of this. It's something I've wondered about!

As far as the boolean feeding the case structures inside the event structure, I guess it's just something I have gotten into the habit of doing based on past experience. Over time I've tried doing this many ways and the way I have done it here gives me the highest level of assurance under all normal and off-normal conditions that the action will only be triggered when the button goes DOWN and the button will always be found in an UP state when the user expects it to be up.

Link to comment
Sometimes on more complicated systems I do bundle lots of shift register elements up into a cluster and pass that around but I have read at least one critique (NI forums) of that style as well (no reason given) and I never have been sure if there was a performance penalty with bundling & unbundling the elements. I must admit it can be easier to follow the logic with bundle/unbundle by name rather than labels sitting on top of wires. As far as real estate, I'd argue that the way I did it takes up more vertical real estate but what you suggest can take up more horizontal real estate so which you chose in that respect depends on what you've got to spend. And, while it is a small thing, it can also be easier to probe individual wires than cluster wires.

I'd love to see a discussion on the pro's & cons of this. It's something I've wondered about!

Well the performance penalty is relative. If you work with a team of developers and others have to dubug and work on your blockade of wires then it suddenly becomes an issue. They throw it back in your face and ask you to redo it. So ya, your performance goes down. ;)

As far as the boolean feeding the case structures inside the event structure, I guess it's just something I have gotten into the habit of doing based on past experience. Over time I've tried doing this many ways and the way I have done it here gives me the highest level of assurance under all normal and off-normal conditions that the action will only be triggered when the button goes DOWN and the button will always be found in an UP state when the user expects it to be up.

Can you explain what an "off-normal" condition is? I still don't follow your argument. Using the mechanical action "latch when released" covers this. I have not (since the event structure came out) seen any condition where I would have to "make sure" the button was going down. I may be missing something here, so please enlighten me. :yes: I disagree with any code on a diagram that is superfluous. It just causes the programmer to pause and have to think about what is going on. Slows comprehension of the code. Makes me think, "ok, so why is this like this?"

Link to comment
Well the performance penalty is relative. If you work with a team of developers and others have to dubug and work on your blockade of wires then it suddenly becomes an issue. They throw it back in your face and ask you to redo it. So ya, your performance goes down. ;)

If you have people throwing stuff back in your face then perhaps you are working with the wrong group of people. :blink:

Can you explain what an "off-normal" condition is? I still don't follow your argument. Using the mechanical action "latch when released" covers this. I have not (since the event structure came out) seen any condition where I would have to "make sure" the button was going down. I may be missing something here, so please enlighten me. :yes: I disagree with any code on a diagram that is superfluous. It just causes the programmer to pause and have to think about what is going on. Slows comprehension of the code. Makes me think, "ok, so why is this like this?"

I personally believe that the event structure is still a work in progress and NI could do a few things to improve it. As you may be aware it takes special effort with it to capture only the final data change event of a control like a slider or knob. Another area where I think it could be improved is if it were possible to specify the type of data change event it should react to. In the case of a Boolean it will react to either False --> True or True --> False. It would be nice to be able to specify just one or the other or both. (For numeric controls it would be nice for it to differentiate between increasing or decreasing values)

For most of what I code I only want it to respond to False --> True events which is why I include the case structures.

I have tried to contrive an example and have attached it. If the reasoning contained there-in still doesn't satisfy you then just mark it down to what I said earlier, a difference in style. It takes all kinds you know and I'm undoubtedly one of them. You are more than welcome to improve, modify or entirely rewrite a better version of the Select-a-Case VI that I had posted and then repost it and I'm sure we all would benefit from your efforts. Just to make it easy on you I have restructured the VI in the form you like and have attached it. While it is somewhat smaller and the data sources & sinks may be somewhat easier to follow, IMHO it's not a great deal better, just a different way of doing it. I also feel that it has a slightly sloppier user interface since it is possible to start it running with any or all of the various buttons depressed and by releasing any button while it is running the action associated with the button will occur while the normal user expectation is that the action will only occur when the button is pressed.

Going forward, if you think it would save the consternation for you and everyone else I could password protect the block diagram of anything I thought might be of value to others and use the time honored excuse others have used that the "code was just too messy to let others see."

Would that be better?

Download File:post-2800-1128213215.vi

Download File:post-2800-1128248648.zip

Link to comment
Going forward, if you think it would save the consternation for you and everyone else I could password protect the block diagram of anything I thought might be of value to others and use the time honored excuse others have used that the "code was just too messy to let others see."

Would that be better?

WMassey

I would greatly discourage you from taking this course of action in the future. No one learns anything from locked diagrams.

However I would also encourage you to enthusiastically defend and explain you coding style and techniques. I

Link to comment
I would greatly discourage you from taking this course of action in the future. No one learns anything from locked diagrams.

However I would also encourage you to enthusiastically defend and explain you coding style and techniques. I'm glad that Michael took it upon himself to critique your code because in the back of my mind I was thinking similar thoughts.

However I was equally impressed by your response explaining what your thought process was and what your experience has taught you. Normally this kind of insight is not expressed.

I did pickup a few tips on scripting but the discussion on shift registers and handling of terminals in event structures in my opinion is the real gem in this thread. :2cents:

I would agree with mballa. He probably knows me a little better since NIWeek and understands how picky I am when it comes to coding style. I've been fortunate throughout my early career in LabVIEW to have experienced developers around me that I could discuss ideas and techniques with. They would also challenge my design decisions which would force me to evolve my style. That's how I've reached the level I am today.

I always try to push people to explain their thought process when they code a certain way. Often time we just do things "just because". Often time this has evolved due to a few late nights of debugging customer code, only to discover that it was caused by a certain boolean button starting off as pressed. This however is the exception and shouldn't dictate how you program all applications. When we have a clear head, we should go back and evaluate, why that happened.

I'd like to add one thing on the use of bundle\unbundle. Adding a new datatype to the shift register only requires the addition of the datatype to a strict-type cluster and you don't need to wire new wires through all the cases. Of course the tunnel wiring wizard would solve this problem but that is no excuse really. LabVIEW now provides the Navigation Window, but this doesn't mean we should all start creating wiring diagrams that span the width of 10 monitors...

As far as your revised application using bundle\unbundle by name, I would give it an A. The reason I didn't give it an A+ is for 2 reasons. One reason is the use of array of strings. I used to program using array of strings and evolved over time to using standard strings with linefeed delimiter. I just recently had this discussion with a colleague and asked them to try using delimited strings instead of array of strings. He was reluctant at first but after he tried it, he was totally converted to this new method. Delimited strings allow easier editing of your state sequence lists because you can just double-click in the textbox and start typing. You can also quickly select text copy past etc.

Another item of note in your revised code is the use of wiring a TRUE though every output to your conditional terminal of the while loop. Again, it works but it's a lot easier to just use the "stop if true" option on it. This means you only really have to wire a constant out on the frame that terminates the while loop. In your case it would be the "finished" and "default". All other cases can just use the "use default if unwired" option. This means if you add a new case, you can just ignore this terminal. A Minor thing but it's nice not to worry about those pesky little constants.

post-2-1128400637.png?width=400

From your profile it looks like you are local to my area (Livermore) so perhaps we can get together at the next LAVA meeting to discuss these coding techniques some more in person. I think the next meeting should be sometime in November. :thumbup:

Link to comment
As far as your revised application using bundle\unbundle by name, I would give it an A.

Gee, if I had know that this was a graded assignment I would have put more effort into it.

Michael were you possibly a school teacher in an earlier life? You even break out a red "pencil" when you mark up my block diagrams. :D

One reason is the use of array of strings. I used to program using array of strings and evolved over time to using standard strings with linefeed delimiter. I just recently had this discussion with a colleague and asked them to try using delimited strings instead of array of strings. He was reluctant at first but after he tried it, he was totally converted to this new method. Delimited strings allow easier editing of your state sequence lists because you can just double-click in the textbox and start typing. You can also quickly select text copy past etc.

I agree and I normally use delimited strings as well for anything more than just a couple of cases. I had purposely stayed away from them in the code I posted because I wanted it to be as basic as possible with as few additional subVIs as possible. In retrospect perhaps that was the wrong thing to do, especially since there was one subVI already included anyway.

When I say I use delimited strings I mean in the constants that determine the states to follow. That delimited string is immediately turned back into an array of strings and it is the array that circulates through the shift registers. That allows me to still use array constants and array element concatenation if I find it more convenient and it keeps the next-state-stripper very simple since it is just the built-in delete-from-array function. Is this what you do or do you circulate the delimited string through the shift registers? How about a representative sample of your code?

One ability that I found convenient to build into the subVI that does the conversion from the delimited string to an array of strings is the recognition of a comment character. It's setup to default to a semicolon. It allows me easily comment out entire lines in the string constants. It would even allow for me to add trailing comments on each line if that were useful.

Another item of note in your revised code is the use of wiring a TRUE though every output to your conditional terminal of the while loop. Again, it works but it's a lot easier to just use the "stop if true" option on it. This means you only really have to wire a constant out on the frame that terminates the while loop. In your case it would be the "finished" and "default". All other cases can just use the "use default if unwired" option. This means if you add a new case, you can just ignore this terminal. A Minor thing but it's nice not to worry about those pesky little constants.

I usually go out of my way to avoid defaults if at all possible but this is actually a very reasonable suggestion.

In keeping with this education theme I'll give you a gold star for it. :star:

Since my last post I have been busy with my Select-A-Case VI. Both using it (real work has still got to be done!) and improving it.

It now will work with multiple cases across multiple VIs. It has also gotten smarter about remembering what has been selected.

I found that I was still spending more time than I wanted to looking down a sorted list of cases trying to remember the name and pick out the case I was looking to find. To make this easier I added a string-search function that allows me to quickly pull up a subset of the cases to select from.

I also found that I wanted better control of what was in the History array to allow me to flip back and forth between a subset of cases quickly. To make this easier I added several options that control how cases get added to the History array as well an option to edit the array.

And finally I added the ability to move the window containing the block diagram with the currently referenced case structure to the front of the pile of windows that always seem to be open when I'm working.

It's all a bit more complex now and there are now several subVIs included, including a few from the LVWUtil32.llb for those people who don't have that library yet. I won't guarantee that it is 100% bullet-proof but so far it has been working fairly well.

Download File:post-2800-1128537743.zip

Link to comment
Going forward, if you think it would save the consternation for you and everyone else I could password protect the block diagram of anything I thought might be of value to others and use the time honored excuse others have used that the "code was just too messy to let others see."

Would that be better?

Ouch! If you were referring to my post here, please re-read the subsequent discussion at the time and note that I was only joking. My real reason for locking the BD: because scripting was so new to us, and not a feature that NI intended to support to end users, I was reluctant to expose the undocumented nodes I had used.

That utility has been d/l'ed, it seems, by just about everybody. I know that I've given the unlocked copy of it to several people by private email; I guess I somehow thought it had ended up on LAVA. All the scripting methods and properties it uses have long since been discussed and documented elsewhere anyway.

This is probably the wrong thread, but as my public act of contrition, I'll attach it here. Note to Michael: if you want to move this post, or replace the locked-BD copy of the util with this one to save space, feel free.

Best regards,

Dave

P.S. And the BD of the TWW is messy. Since we're on a discussion of style anyway, let me just say in my defense:

  1. If you're writing a scripting helper that watches for VI activation, object selection, etc., you currently have to loop and poll
  2. I deliberately did not break the code up into subVIs because I would have had to pass scripting object refnums, thereby exposing them

Download File:post-195-1128601774.vi

Link to comment
2. I deliberately did not break the code up into subVIs because I would have had to pass scripting object refnums, thereby exposing them

Not that I care about how nice or sloppy your code looks, but for future reference, if you need to not expose stuff like that you can always just flatten and unflatten your data.

Link to comment
Ouch! If you were referring to my post here, please re-read the subsequent discussion at the time and note that I was only joking.

Your's was not the only posting that has been password protected and accompanied by the "too messy" defense, whether real or in jest. Here's the one that I was remembering at the time and I believe that I have seen more. After all, it is a very convenient (quick to type, without a lot of explanation) excuse that is easy for most of us to understand (who wants to open themselves up to blunt criticism about some aspect of their style when that was not intended to be the reason for the post). I was quite happy to accept your reason and even happier to get the tool you provided. Thank you for it. And thank you for now posting the unprotected version. I'm sure I will learn from it.

Link to comment
Not that I care about how nice or sloppy your code looks, but for future reference, if you need to not expose stuff like that you can always just flatten and unflatten your data.

Awww, m3nth, even as I wrote it, I knew somebody would 'gig' me for posting that.

Actually, what I did in another util which used scripting and recursion, was to cast the refnums to longs and back on the trip through the conpane. That was my first idea for preventing folks from cloning the scripting classes.

So many clever people on these forums, I just can't keep up with all this stuff. :wacko:

Later,

Dave

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

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