Cloning Front Panels -- Refinements to a VI Server Technique
Overview
In his "Cloning Front Panels" article (LTR Volume 6, Number 3), Allen C. Smith described how to create multiple instances of the same VI. His solution was to make copies of the VI as needed and use VI Server to open and run the copies. I had done something similar on a project I worked on, so Allen and I corresponded briefly, commiserating over finding out that someone else had already discovered what we each thought was an original idea. I prefer to liken it to the Newton-Leibnitz controversy, but I recognize that this technique might not prove as useful to the world as Calculus.
But we have both moved on, and in this update to Allen's original article, I refine the technique a bit further by discussing the following topics:
- Eliminating the need to copy the VI on disk using VI templates
- Cleanly initializing the panel so that the user does not see this initialization
If you use VI Server to open a reference to a template VI, you actually get a new copy of the VI in memory, so you do not need to copy the VI on disk and then open the copy. Not having to do so saves time and cleanup effort and simplifies your diagram. Using this technique, you need only a simple code fragment to dynamically clone a VI, open its front panel, and run it asynchronously (see Figure 1).
If you read the VI Name property of the VI, LabVIEW returns a unique name. Notice that the VI Path property returns "<Not a Path>" because the VI does not actually exist on disk anywhere.
Why haven't you heard about this technique before? Well, you have actually been able to clone VIs in this manner in the LabVIEW Development System since version 5.0, but with LabVIEW 6.0.2, you can do it using executables and shared libraries, making this a practical solution for dynamically cloning VIs.
I personally think that software can look rather shoddy when you get to see the initialization of an interface happen. For example, it is not considered good technique when a pop-up panel opens and you see controls become disabled right before your eyes. They should be disabled before the panel opens.

Figure 1: Dynamically Cloning a VI, Opening it, and Running it Asynchronously
Unfortunately, the solution shown in Figure 1 could have this very problem. Notice that the panel is opened before the VI starts running. Therefore, if the first thing the VI does is initialize its panel (that is, disable or hide controls, update control captions, and so on), the user sees the initialization happen. Well, how can you solve the problem?
The best thing to do is to have the VI displaying the panel open its own panel once it is done doing any necessary initialization. But if you just do that blindly, you can run into a pretty serious problem. Remember that LabVIEW automatically unloads VIs from memory when it does not need them any more. How does LabVIEW know if it needs to keep a VI in memory? Well, LabVIEW keeps a VI in memory in the following situations:
- The VI is directly in the hierarchy of a loaded VI
- The panel of the VI is open
- Some VI or application has an open reference to the VI
If you just put a Property Node that sets the Front Panel.Open property to true at the beginning of the VI being cloned, you might run into the problem that our brand new clone gets unloaded from memory before you have even had a chance to use it. Why? If the Close LabVIEW Object Reference function in the code that creates the clone executes before the panel is open, LabVIEW throws the VI out of memory—it is not in the hierarchy of any loaded VI, its panel is not open, and the only open reference to it was just closed.
So you need to make sure that the newly-cloned VI either opens a reference to itself or opens its panel before the Close LabVIEW Object Reference function executes. This problem calls for a little synchronization. What you can do is generate an occurrence and pass the occurrence refnum to the new clone. Then, the creator of the clone waits on that occurrence before executing the Close LabVIEW Object Reference function, as shown in Figure 2.
First, the clone either opens a reference to itself or opens its panel and then sets the occurrence. This informs the creator of the clone that it is safe to go ahead and close its own reference to the VI. Figure 3 shows the diagram of the VI template. Then you can be sure that a reference to the cloned VI is always open. Therefore, LabVIEW does not throw the VI out of memory until you tell it to do so by closing the open reference. Having a VI open its own panel after doing some sort of initialization is a good idea regardless of whether you are dynamically cloning VIs. However, dynamically cloning the VIs causes some additional complications.
For an example of both of these techniques, I chose to build upon Allen’s example for his original article. Being a bit of a game player myself, I appreciated his example of creating panels that mimic the polyhedral dice that are common in role-playing games. For the sake of simplicity, I reduced the example down to its essentials. The original example maintained a registry of all active VI instances so that you could operate on all of them at once (for example, to close all of the windows at the same time). My example is not as good for a real application, of course, but I just want to demonstrate the technique.
The resulting code is quite simple. The top-level VI, Bag of Polyhedral Dice.vi, allows you to open as many panels as you want for each kind of die (d4, d6, d8, d10, d12, and d20). You can then roll each die and close its panel when finished. Each die you create is actually a dynamic instance of the template VI die.vit. The VI Create VI Instance.vi is responsible for creating the instances of this template. Additionally, it provides a generic mechanism for passing data to the cloned VI. In the example, the top-level VI tells each clone what kind of die it needs to mimic. Notice that it behaves just like a real bag of dice. You can put the bag away without putting all of the dice back first. If I had implemented a registry to keep track of the clones, it could behave even better.
In most cases, this technique is just overkill. If all you need is multiple calls to the same subVI executing in parallel, then just making a VI reentrant likely will meet your needs. However, if you need multiple instances of a single user-interface VI, you need to create dynamic instances of that VI. Cloning a VI template is the most straightforward method available to create these dynamic instances.
LabVIEW Technical Resource (LTR) is the leading independent source of LabVIEW-specific information. Each LTR issue presents powerful tips and techniques and includes a Resource CD packed with VIs, Utilities, Source Code, and Documentation.
Kyle P. Gupton is the manager of the TestStand software team at National Instruments. He has been with NI since 1994 and is a former member of the LabVIEW R&D team. He can be reached at kyle.gupton@ni.com.
Reader Comments | Submit a comment »
new technique???
Just wonder if the author looked at this:
"Opening Multiple Instances of a Front
Panel Simultaneously"
by M. Egmond from Genoa, VI-s were written
back in May 2001, so what is actually NEW?
- Serge Musteata, BCO. serge@bco-inc.com - Mar 20, 2003
Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).


