bbean Posted March 23, 2007 Report Share Posted March 23, 2007 Does anyone have an example of how to persist an Open GOOP object? I looked at Tutorial 8 from from Sciware's Goop Developer Template (http://www.sciware.com.au/goopdeveloper/SciWare%20GOOP%20Developer%20User%20Guide%20and%20Tutorial.pdf) using supermessaging and INI files. But it seems cumbersome to create section/keys for each object. Also I'm worried that the INI format might not be right/fast for more complex objects. For instance, say I want to persist a collection of digital pumps (from the examples http://www.sciware.com.au/goopdeveloper/GOOPExamples.zip). I want to be able to save this collection and recall it and its state at a later time. The Collection would be an array of pumps. Each pump object also contains a DataIO object. Each of these objects can be instaniated as a child object. One place I'm getting stuck is reading the file back. How do I know from reading the file which instance of the pump and/or digitalIO objects to create. Are there design patterns and file formats that I can use to make this easier? P.S. Pardon my use of terminology. Just learning this GOOP stuff. Quote Link to comment
Kurt Friday Posted March 23, 2007 Report Share Posted March 23, 2007 Hi bbean There are several ways of persisting object data, the super messaging example is a great way for persisting object data where there is an object hierarchy, but its more of an example of super messaging than persisting data. One of the things I really like about ini files is that they are very readable and you can be selective about the attributes that you persist, not every member should be persisted. A couple of alternative methods of persisting data would be. 1) Use the OpenG Variant Configuration File package to write or read your data members, everything will be persisted though. the ini file format is very readable. 2) Write the data member cluster to an XML file, this is readable to a degree but everything will be persisted. 3) Cast the the data member cluster to a string and write to a binary file, non readable form unless you know the type of your data member which could change, ie add an attribute and suddenly you cant read the data members. I would avoid this technique, its quick and dirty To enable initializing your data members from file simply use one of the above inserted in the create between the default members and the Object.New. The file path to the persist file should be added to the data members so that it is available when you persist the data in the Destroy. I'm currently doing up some demo code for you but time hasn't permitted me to get it out today, but stay tuned and I'll pop something up here tomorrow that should help you out. Quote Link to comment
bbean Posted March 23, 2007 Author Report Share Posted March 23, 2007 QUOTE(SciWare @ Mar 22 2007, 02:38 AM) Hi bbeanThere are several ways of persisting object data, the super messaging example is a great way for persisting object data where there is an object hierarchy, but its more of an example of super messaging than persisting data. One of the things I really like about ini files is that they are very readable and you can be selective about the attributes that you persist, not every member should be persisted. A couple of alternative methods of persisting data would be. 1) Use the OpenG Variant Configuration File package to write or read your data members, everything will be persisted though. the ini file format is very readable. 2) Write the data member cluster to an XML file, this is readable to a degree but everything will be persisted. 3) Cast the the data member cluster to a string and write to a binary file, non readable form unless you know the type of your data member which could change, ie add an attribute and suddenly you cant read the data members. I would avoid this technique, its quick and dirty To enable initializing your data members from file simply use one of the above inserted in the create between the default members and the Object.New. The file path to the persist file should be added to the data members so that it is available when you persist the data in the Destroy. I'm currently doing up some demo code for you but time hasn't permitted me to get it out today, but stay tuned and I'll pop something up here tomorrow that should help you out. Thanks. I use the OpenG Variant package a lot for other projects. I was able to save the Pump.Digital data members to an ini file using the OpenG code. The attached file shows what I have so far. I didn't create the persist method for the DataIO member of the Pump Class because I couldn't determine how the Config File Reads would automatically determine the instance type of the DataIO object from the sections created by the Pump.Persist methods. For example, if one pump has a DigitalIO object that is a DataIO.FieldPoint.Digital and another pump has a DataIO.Datasocket.Digital. The "type" key in the "DataIO object" section of the ini file only says "DataIO" not the specific instance type. Also if I have a collection of pumps how do you distinguish them in the INI sections? Do you add the instance name to the section header? BTW I was going to post on the sciware forums ( http://sciware.com.au/forums/''>http://sciware.com.au/forums/' target="_blank">http://sciware.com.au/forums/ ), but they seem to be down. Thanks for your help. Brian Quote Link to comment
Kurt Friday Posted March 24, 2007 Report Share Posted March 24, 2007 I'm doing up a very interesting demo they implements persistence and allows dynamic loading of children, Its looking good but is a couple of hours away. the persistence is based on the OpenG Variant Configuration File package and works very nicely. I took the forums down for a while until I can protect it from spammers, they make my blood boil. Quote Link to comment
Yair Posted March 24, 2007 Report Share Posted March 24, 2007 QUOTE(SciWare @ Mar 23 2007, 07:01 AM) the persistence is based on the OpenG Variant Configuration File package and works very nicely. Note that the current version of the variant config VIs does not handle array persistance in a case where your array becomes smaller (the old element values are not deleted) so if you have arrays in your example, you will need to do something to work around that. Looking forward to seeing your example. Quote Link to comment
Jim Kring Posted March 24, 2007 Report Share Posted March 24, 2007 QUOTE(yen @ Mar 23 2007, 06:48 AM) Note that the current version of the variant config VIs does not handle array persistance in a case where your array becomes smaller (the old element values are not deleted) so if you have arrays in your example, you will need to do something to work around that.Looking forward to seeing your example. Variantconfig does handle arrays that get smaller, it just doesn't delete some of the keys. Quote Link to comment
Kurt Friday Posted March 24, 2007 Report Share Posted March 24, 2007 You can download the demo from. http://www.sciware.com.au/goopdeveloper/Dy...PersistDemo.rar The demo dynamically instantiates DataIO and Pump objects and passes the creators a persist file, you simply configure the system from a central ini file describing what type of DataIO child you want and the same with the Pump. This is a really nice demo of persistence and a great way to achieve a plugin architecture, with this kind of architecture you would simply drop your new child objects in, configure your central ini and create default persist files. As I mentioned the persistence uses the OpenG variant config VIs which worked very well and saved a heap of coding, the only issue I came across is that when persisting the Pump object datamembers which contains a DataIO object I had to clear the DataIO obj, I'm not sure why yet and I'll investigate this further. I think persistence should be worked into the template, probably embedded into the mechanics of the object so that it is a native feature that the user can just enable, I'll have to think of a cool way to do it. Have fun Quote Link to comment
bbean Posted March 25, 2007 Author Report Share Posted March 25, 2007 Thanks Kurt. Its going to take me a while to digest this. Unfortunately (or Fortunately) I'm going on vacation tomorrow for a week. I'll take a look in detail when I get back. I like what I see so far. One question: 1) Is there any reason you made the Persist Method private? It seems like it would be a candidate for a virtual function call. I realize its called in the virtual method of Destroy. Quote Link to comment
Kurt Friday Posted March 26, 2007 Report Share Posted March 26, 2007 QUOTE(bbean @ Mar 24 2007, 06:41 AM) Thanks Kurt. Its going to take me a while to digest this. Unfortunately (or Fortunately) I'm going on vacation tomorrow for a week. I'll take a look in detail when I get back. I like what I see so far. One question:1) Is there any reason you made the Persist Method private? It seems like it would be a candidate for a virtual function call. I realize its called in the virtual method of Destroy. I had toyed with a virtual method, and the super messaging examples, however since I used the variant config vi's they initialize all of the data members so I had to call read persist before I set the DataIO object in the Pump object, hence this operation had to be performed even before the object was created, virtuals need the object to be created first. Also in the case of an active object you want the data members initialized before you launch the process. In its present form if you were to make a new child a persist method would be automatically created that will be able to handle the child datamembers, so making it virtual is not neccessary. Enjoy your holiday, I just came back from a couple of days in the sun north of Sydney, was brilliant. Quote Link to comment
Kurt Friday Posted April 2, 2007 Report Share Posted April 2, 2007 I've moddified the code to demonstrate how to build such an application as an exe. The Bin folder where the exe resides includes a Plugin directory which contains objects saved as llb's which are then dynamicaly called. Use the same link above to download the new demo. Quote Link to comment
bbean Posted April 5, 2007 Author Report Share Posted April 5, 2007 QUOTE .....however since I used the variant config vi's they initialize all of the data members so I had to call read persist before I set the DataIO object in the Pump object, hence this operation had to be performed even before the object was created, virtuals need the object to be created first. Kurt, Got back from vacation and am starting to look over everything. Everything works great. After looking at your code I started to feel a little braver and wanted to revisit some of the approaches I tried before I saw your example (probably a bad idea). What I was trying to do with the GoopTemplate Pump Examples was implement the Factory pattern from LV8.2 shown here: See http://jabberwocky.outriangle.org/Factory_UsingVIs.zip and http://jabberwocky.outriangle.org/Factory_UsingClassRef.zip using the GoopTemplate in LV7.1. The motivation as i see it (may be wrong) behind using the Factory pattern is to seperate the Persist Path data member from the pump object because it doesn't seem like persist file path should be a member of the Pump object. Also the factory approach seems like a very flexible means of abstracting the creation of Pumps (or any other objects). Attached is half-hearted attempt to implement this pattern. The Pump Save.vi creates a digital pump object with a VISA Data IO member, then saves the object data to the ini file under the objects instance name as a section header. After that, I try to implement the pumpfactory to read the pump data from the file dynamically. http://forums.lavag.org/index.php?act=attach&type=post&id=5405 In the PumpFactory I attempt to determine the pump type by reading the "object type string" from the ini file header and then comparing it to the list of "Pump types" in "Pump Factory". Once the type is determined, I would like to dynamically call the appropriate Pump.Create (as opposed to creating a case statement with the hard coded Pump.*Create objects). I guess I'm stuck here and wonder if I'm wasting my time. http://forums.lavag.org/index.php?act=attach&type=post&id=5406 Thanks for all your help, Brian Quote Link to comment
Kurt Friday Posted April 6, 2007 Report Share Posted April 6, 2007 Hi Brian I hope you didn't spend your holiday playing with this stuff, there are better things to do :beer: The idea of the dynamic create being able to choose the correct object based on the persist file is in interesting idea, I quite like it, I'm not sure yet how to correctly implement it. The demos I've put together that implement persistence are proofs of concept at the moment, I think there are better ways of achieving it, I need the time to tinker with some ideas and begin working it into the mechanics of the object. You are right, the persist file path doesn't really belong in the datamembers but probably in the object cluster, but this was the quick fix until I can create a GOOP template that provides it. It would be cool if you would like to participate in this. I suppose the direction you take with this depends on the time you have to do your project. If you can tolerate having the persist file path in you data members then go with the architecture I've provided, however if you have the time to tinker then carry on, I don't think you are wasting your time, its just a matter of how much time you have, this stuff is fun after all. In the mean time I'll play with some ideas and post them up for discussion. BTW I posted up a built exe version in 8.2 of the DynamicPersistDemo that you would no doubt be interested in, see the following post. Question about making the Executable file with GOOP or download the code from here Quote Link to comment
bbean Posted April 6, 2007 Author Report Share Posted April 6, 2007 QUOTE Hi BrianI hope you didn't spend your holiday playing with this stuff, there are better things to do :beer: The holiday was all skiing and beer in Canada. Highly recommend the Banff area for skiing, even in late March. QUOTE The idea of the dynamic create being able to choose the correct object based on the persist file is in interesting idea, I quite like it, I'm not sure yet how to correctly implement it. The demos I've put together that implement persistence are proofs of concept at the moment, I think there are better ways of achieving it, I need the time to tinker with some ideas and begin working it into the mechanics of the object. You are right, the persist file path doesn't really belong in the datamembers but probably in the object cluster, but this was the quick fix until I can create a GOOP template that provides it. It would be cool if you would like to participate in this. Sure. QUOTE I suppose the direction you take with this depends on the time you have to do your project. If you can tolerate having the persist file path in you data members then go with the architecture I've provided, however if you have the time to tinker then carry on, I don't think you are wasting your time, its just a matter of how much time you have, this stuff is fun after all. In the mean time I'll play with some ideas and post them up for discussion. BTW I posted up a built exe version in 8.2 of the DynamicPersistDemo that you would no doubt be interested in, see the following post. Question about making the Executable file with GOOP or download the code from here I saw that right after I posted the message. I'll take a look 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.