GregFreeman Posted May 28, 2014 Report Share Posted May 28, 2014 (edited) 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 May 28, 2014 by GregFreeman Quote Link to comment
hooovahh Posted May 28, 2014 Report Share Posted May 28, 2014 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. Quote Link to comment
drjdpowell Posted May 28, 2014 Report Share Posted May 28, 2014 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. Quote Link to comment
GregFreeman Posted May 28, 2014 Author Report Share Posted May 28, 2014 Good points above. And James, you're right I could easily pass the subpanel reference as message data. Quote Link to comment
Tim_S Posted May 29, 2014 Report Share Posted May 29, 2014 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? Quote Link to comment
hooovahh Posted May 29, 2014 Report Share Posted May 29, 2014 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. Quote Link to comment
GregFreeman Posted May 29, 2014 Author Report Share Posted May 29, 2014 (edited) 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 May 29, 2014 by GregFreeman Quote Link to comment
hooovahh Posted May 29, 2014 Report Share Posted May 29, 2014 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. Quote Link to comment
drjdpowell Posted May 29, 2014 Report Share Posted May 29, 2014 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. Quote Link to comment
K-node Posted May 29, 2014 Report Share Posted May 29, 2014 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. 1 Quote Link to comment
GregFreeman Posted May 29, 2014 Author Report Share Posted May 29, 2014 (edited) 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 May 29, 2014 by GregFreeman Quote Link to comment
gb119 Posted June 10, 2014 Report Share Posted June 10, 2014 Why not use a semaphore that each subvi tries to acquire before inserting itself and releases after it unembeds? This seems to involve minimal changes to the existing structure... 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.