Jump to content

Unloading VI From Subpanel


Recommended Posts

This should be relatively simple, but I'm not seeing a good way to do it. I start up a bunch of VIs that run in parallel. Each VI has a reference to a subpanel which they can be loaded into. The user can then select different screens and whichever screen they pick will be shown (pretty standard). When they are unloaded from the panel, they unregister for all events except changeView and exit, so essentially they will just sit idly and hidden. My problem is with the unloading of a panel. I can send a change view event which the visible view will receive and it will remove itself from the panel. The view to be shown will receive the event as well and load itself. With this method, however, if the view to be shown receives the event first, it will try to load itself before the other view is removed which I believe throws an error.

 

So, I have thought of a couple of solutions. I could have my top level view which owns the subpanel remove the VI before sending the "change view" event. That way the view would be unloaded and it could just unregister and do any cleanup in the background. Another option is that I can make separate hide and show methods, making the hide method synchronous and wait for a response. Or, I could have the view with the subpanel hold references to all the different views and show and hide them directly (I really don't like the first or last approach; it seems to break the messaging paradigm of parallel processes. I'd rather use messages and let the VIs load/unload themselves. But, I also tend to shy away from synchronous messaging, which basically strikes out option 2 leaving me with nothing).

 

Anyways, wondering if anyone can provide some insight here.

Edited by GregFreeman
Link to comment

I stick with the top level handling who gets load and unloaded.  That doesn't mean you have to do it that way of course.  You could be in a loop attempting to insert your self into the subpanel continuing to try until no error is see (or time out).  

 

For me I find it easier to have my sub VIs not deal with the subpanel for a couple of reasons.  The less code in my sub VIs is better because I assume I'll need the same code in each child VI and copying the same code means more places to fix it if I find a bug.  But also I some times may want to run just my child VI as the top level and debug things.

Link to comment

Why does each VI have a copy of the subpanel reference?  I would just have the top-level owner of the subpanel just send send the subpanel ref to the chosen subView, after calling “Remove VIEW”.  The receiving subView would call “Insert VI” as part of handling the message, but wouldn’t bother saving the reference.

Link to comment

One thing that may help is the VI being inserted can detect if it is in a subpanel.  So the top level may not need to tell the sub VI of the state change.  Of course that means polling so maybe that isn't the right way to go.

 

http://digital.ni.com/public.nsf/allkb/FB79ED8B6D07257B86256E93006E31FA

 

And starting in 2012, if you have the reference to the subpanel, you can get the reference to the VI that is in the subpanel using a property node.

Link to comment
Would it be better to have the 'top level' VI with the subpanel handle remove/insert for the subpanel (would require VI reference at top level) and then send a message to the parallel VIs as to who is active?

I don't mind this idea, the one thing I wasn't sure of is the fact that now the main VI which owns the subpanel has access to all the other VIs references. To me, it feels like these references should be private and other VIs shouldn't have access to them. Maybe I'm splitting hairs here though. Always the community scope/friend route but I try to avoid that if possible.

Edited by GregFreeman
Link to comment

I think it partly is a matter of opinion.  Right or not, on startup of all of my Actors I put their corresponding "This VI" into each of their own globals.  I can then use this to see which Actors have their front panels opened, and allow thing like a Manual Screen Actor which just loads other actors into a single sub panel as needed.

Link to comment
I don't mind this idea, the one thing I wasn't sure of is the fact that now the main VI which owns the subpanel has access to all the other VIs references. To me, it feels like these references should be private and other VIs shouldn't have access to them. 

Also, isn’t this unnecessarily complicated.  You already are keeping track of the communication references to these subcomponents; now your going to have to keep track of the VI refs of their VIs (plus whatever mechanism you use to get the VI refs to the top-level subpanel owner).  An “Insert into the attached subpanel” message is trivially simple.

Link to comment

For the VI that is going idle, why not just use the VI Invoke Node with the Front Panel:Close in its ChangeView event handler.

 

Then for the VI that is going visible, use SubPanel Invoke Node with Remove VI followed by Insert VI in its ChangeView event handler.  I would add a Clear Errors in between in case there is nothing in the subpanel.  You might also add a Front Panel:Close in front of all of this in case the VI is already being displayed somewhere along with a Clear Errors in the event it is not currently visible.

 

Your race condition you describe would not occur.  However, your user could go click happy and keep changing views faster than the clients can update.  It may happen that the last view desired is not the one that ends up showing simply because the last one clicked processed the event fast.  I personally would not bother handling that use case.

 

I also agree with James, that you should pass in the reference to the subpanel and not store it.  My apps have lots of subpanels.  Front Panels are swapped around all the time.  Each user wants to see things a bit differently.

  • Like 1
Link to comment
For the VI that is going idle, why not just use the VI Invoke Node with the Front Panel:Close in its ChangeView event handler.

 

Then for the VI that is going visible, use SubPanel Invoke Node with Remove VI followed by Insert VI in its ChangeView event handler.  I would add a Clear Errors in between in case there is nothing in the subpanel.  You might also add a Front Panel:Close in front of all of this in case the VI is already being displayed somewhere along with a Clear Errors in the event it is not currently visible.

I like this solution. Also, if as mentioned above, I check the current VI reference in the subpanel against the VI reference I'm about to load, I can have some logic built in determining if I need to remove the current panel or not, or even load a new one (if the references are already equal, no need to remove or load).

Edited by GregFreeman
Link to comment
  • 2 weeks later...

Join the conversation

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

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.