TG Posted January 21, 2007 Report Share Posted January 21, 2007 Goal: Create A ref to a 'dynamically' constructed class instance plus support for inheritance My project involves automating a process that uses many serial instruments, actuators, sensors etc. My boss wants me to "do it with objects this time" because we expect to be maintaining this for years to come and also we will use parts of it for future projects etc. Because some of the classes will support serial instrument and Field point calls I (think?) I'll need to refer some of them by (simulated) reference. I might need to refer to all of them this way. Various control loops will be used. Speed is not really an issue to be concerned about, except in reading serial data in real time from say, one or two instruments. Inheritance is being used (I prefer to stay in LV8.2 and not use outside party toolkit for serial device classes.) Enough of the lead in . Here is the question'(s). Aristos Queue provided the coolest example of (a factory pattern?) A solution to a problem posed By Lee Robertson that can work in a built app. It uses coercion to do some cool stuff with classes. It works by simulating instantiating an object dynamically using VI server. By loading a VI "default data" with the desired class inside it and a generic class as the output terminal. I am amazed at how simple this is. I took the liberty of reposting the example code. http://forums.lavag.org/Need-help-with-inh...tion-t4033.html http://jabberwocky.outriangle.org/ Factory_UsingVIs.zip Here is the essence of the thing. The inside of the call by ref node contains (essentially) the code below except for a mod I added in pseudo code. To make a long story short I want to embed a reference queue to the object in the actual object. Q is he following: Would it be possible to "pseudo constructor' the object before it is passed out to the generic terminal and could we give it a reference to itself as shown in the pseudo code below? If I go down this road what kind of trouble should I expect? If so why would it not work, and what would be required? IF it DID work how could it also support inheritance? There Quote Link to comment
Jim Kring Posted January 21, 2007 Report Share Posted January 21, 2007 I saw something similar to this, during the beta. Open a reference to a VI with the child class datatype on the front panel and then do a get control (object) value as variant. You can then upcast this variant (to more generic class) as the parent class, using the Variant to Data function. I'm pretty sure that this, or some similar variantion will work. Best of luck. [update ==>] I found some of my old notes on this subject, including a screenshot of some concept code (see, below -- there's also a screenshot, but I couldn't find the original VI). Load Plugin is a generic subroutine (it will know nothing of the class types), and could be converted into a subVI. The caller of Load Plugin will pass it the plugin path and the Base Class control reference. The caller will wait until Load Plugin completes execution and then read the Base Class data from the control, whose reference was passed to Load Plugin, earlier. Then the object data will be used in the application. Finally, the class will be unloaded from memory, after the application no longer needs the plug-in. In this example, the "Main VI" will both load and unload its own plug-in(s), rather than have some other VI sitting on top of it and loading plug-ins for it. It requires only a single support VI, to load plug-ins. Quote Link to comment
LAVA 1.0 Content Posted January 21, 2007 Report Share Posted January 21, 2007 Hi John, I'm not exactly certain what were you trying to do. However I try to answer your questions anyhow, tell me if I answered the wrong question. We are creating LVOOP objects dynamically. Our objects refer to files. As each file can be of different format, we need to have a file parent class and number of child classes, one for each file format. We have a factory class, which has a open file method. This method is passed a file path. From the extension of the file, the method identifies which file format is needed and calls appropriate file object constant returning VI dynamically (in a similar way as in your first example VI). This VI returns a parent class (File Class) constant. Then we pass this constant to a dynamic constructor VI with the file path as a parameter (dynamic meaning dynamically dispatched, but not called by-reference-node). The runtime type of the file class wire determines wich constructor should be called (dynamic dispatching). Then this constructor for the specific file type opens the file and stores file reference as a private data member. We have multiple "abstract" dynamic methods in the File Class to manipulate the file. These methods are then implemented in each file format class inheriting from File Class. We also have a dynamic close method, that closes all the references that have been opened. We only store file reference as private data so our objects act as by-reference objects. I understood that you want similar kind of behaviour but you do not have real references to store to private data members. You can overcome this problem by creating a queue in the dynamically dispatched constructor and storing what ever private data members to this queue. Then in each interface method of your child class you must get the data members from this queue, modify them and return them to the queue. In the close method you must empty the queue, properly close any references that has been stored to the queue (if any) and close the queue reference. Quote Link to comment
LAVA 1.0 Content Posted January 21, 2007 Report Share Posted January 21, 2007 I wrote you an example that uses LVOOP class plugins to access different kinds of data files. Our real system is somewhat more complicated. The plugins in the attached example are opened at run time and correct plugin is automatically selected based on the file extension. I wrote two plugins, one for text and a second for binary data files. The text plugin uses queue based reference and the binary files uses native LabVIEW file reference. Of course the text file could use native LabVIEW file reference but I thought the example is more educative if I use queue based reference in the other plugin and you John also mentioned that you'd like to use queue based references. Open the File.prj project file and take a look at the two examples within. Download File:post-4014-1169410820.zip Quote Link to comment
TG Posted January 21, 2007 Author Report Share Posted January 21, 2007 I wrote you an example that uses LVOOP class plugins to access different kinds of data files. Our real system is somewhat more complicated. The plugins in the attached example are opened at run time and correct plugin is automatically selected based on the file extension. I wrote two plugins, one for text and a second for binary data files. The text plugin uses queue based reference and the binary files uses native LabVIEW file reference. Of course the text file could use native LabVIEW file reference but I thought the example is more educative if I use queue based reference in the other plugin and you John also mentioned that you'd like to use queue based references. Open the File.prj project file and take a look at the two examples within.Download File:post-4014-1169410820.zip Boy that is a nice example Jimi. Elegant and educational. Actually I do not think it is that far off from what I need to do. I have many questions about this example because I am still playing (eternal) catchup but I'll keep it short. In the (specilaized for binary file version) Dymanic Vi "Open file.VI" I notice the embeded file reference to the open file. Now if this "by value" class object were to branch I assume refnum would be copied along with it but would still be valid (provided the file were not closed by some buggy code running somewhere else), thus any copy of the class could be used to get at the data in the open file as long as refnum was valid (I understand this may be risky but what is the alternative I have no idea). SO the Q is the following: How could I do the same thing except instead of an external data file, what about creating a reference to the class itself and inserting this reference into the original class object? In other words how to simulate "by ref" behaviour for any given "by value" class. I can see (in my mind) that this is probably common technique for simulating by ref access to the class object, however inheritance looks murky to me with respect to simulating byref behaviour. I saw your examples in Refactoring the ReferenceObject example in LV 8.2 Im wondering if the example you showed is the way to handle inheritance with "by ref" behaviour? Quote Link to comment
LAVA 1.0 Content Posted January 22, 2007 Report Share Posted January 22, 2007 Boy that is a nice example Jimi. Elegant and educational. Thanks! I wrote the example as I knew there are not very good examples on using LVOOP classes dynamically. In the (specilaized for binary file version) Dymanic Vi "Open file.VI"I notice the embeded file reference to the open file. Now if this "by value" class object were to branch I assume refnum would be copied along with it but would still be valid (provided the file were not closed by some buggy code running somewhere else), thus any copy of the class could be used to get at the data in the open file as long as refnum was valid (I understand this may be risky but what is the alternative I have no idea). That's true, you got it right. If the file operations do not ship with build-in safety mechanism against concurrent access, then accessing the file in multiple places of your application simultaneously may be risky. To overcome this problem you need to implement the safety mechanism by your self. The easiest way to implement such a safety mechanism is to store the reference to a single element queue. When your code needs to access the file, it get's the reference from the queue. The queue becomes empty and therefore no other part in your application can get the reference simultaneously. Only until you return the reference to the queue, other parts of your application can get the file reference. How could I do the same thing except instead of an external data file, what about creating a reference to the class itself and inserting this reference into the original class object? In other words how to simulate "by ref" behaviour for any given "by value" class. I don't really understand what you mean by a reference to the class itself. When you say "class", do you mean a class or do you mean an object (a runtime instance of the class) instead. LabVIEW objects do not have references that are exposed to users (internally they do). Therefore you cannot get a reference to an object. In addition class private data control cannot refer to itself recursively. In Refactoring the ReferenceObject thread we have used the technique to store the private data of the class to a single element queue. This way the objects of the class act as if they were by-reference objects. However this means extra work as you may have noticed. I understand that you would like some easier way to overcome this problem. I haven't really thought of the issue since I posted my inheritance example to the Refactoring the ReferenceObject thread . Now that I think it, there is one other alternative, but it's not that nice either. I post my alternative implementation on this issue to the Refractoring the RefereceObject thread as it suits there better and it's not something you would do by yourself. EDIT: here is the link to the other thread: http://forums.lavag.org/index.php?showtopi...amp;#entry23148 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.