Jump to content

K-node

Members
  • Posts

    90
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by K-node

  1. I did not see the attachment, but the changes were straight forward to implement. I actualy removed creating the interface bag at the _GetInterfaces method returning just the list. It is up to Interfaceable.GetInterface to populate the bag or even just work off the obtained list since the _GetName can be called for each Interface. Summarizing your suggestions from your "sibling search" post ( http://lavag.org/topic/11186-ideas-for-an-issibling-algorithm/), I think you were suggesting that the GetInterface method accept an object derived from IUnknown instead of using the name since all IUnknown derived objects must implement the _GetName method. Is that what you suggested? I like it - saves typing (and typos)! And also you were saying to use the PreserveRuntimeClass function as opposed to the ToMoreSpecific class after obtaining an interface from GetInterface. Am I correct? I have to reread what AQ said about those two functions. So, now for the question... Let's say you have a SmartCellPhone class that derives off of CellPhone. Would you expect it to implement the ISleepable interface, or utilize the CellPhone class capability? This may be a more fundamental question on interfaces. I have implemented interfaces, but I have never derived a class that had an interface (or at least did anything about it if it had one). Thanks for sharing this framework.
  2. Dak, Back to your original question of finding common lineage... I do not know how to programmatically traverse a class hierarchy given an instance of an object, expect to make the object do it. So, would it be feasible to make a 'must override, must invoke parent method' method that returns an array of strings (class names), or even an array of objects that are essentiall empty (DVR not allocated) instantiations of classes. At that point you have the entire inheritance tree for both objects and a level by level comparison can be done. By the way, the class factory idea does work well. In my case I previously write a LV XML file of an array that contains every class that I expect the Factory to create. In my application where I use the class factory I have it read the file. I suppose I could tell the factory to read multiple XML files and therefore add to its list (extending it's capabilities). All classes must implement the DD Create method as it will be called when you use ClassFactory.CreateNewInstance. There are probably other ways to implement the array without actually resorting to a file. Your array of implemented classes comes to mind from your interface framework. -kugr
  3. I nosed around this for a little bit and I like it. Nice work. I would prefer, as a developer using this framework, not to have to have the ImplementationCollection as part of my class. I would prefer this on the Interfaceable class. I realize that you would need to change the Interface class to store a more general (but common) base class as the Target ObjRef. You could use the LabVIEW Object or create a new common base class. How does the ImplementationCollection get populated? I am restricted by business rules on what I can install on my laptop, so the OpenG stuff was out of the question. I replaced the references to this using a string array for the keys and an Interfaceable object array for the items. But the list is empty when I finally try to get the named interface in the BabyDemo vi. Not sure what I broke. Perhaps you can help there. In the mean time I simply added the ISleepableBaby object to the ImplementationCollection of Baby in the _GetInterfaces method I had to override. I kinda like your _CreateDVR method. As I get more and more properties I might find it a pain and would prefer to resort to a Create method that is called once - but then from the User perspective it is one less thing to remember to call as the User instantiates these things. Is there a reason that the Interface Class holds a DVR to its target and not just an Interfaceable object as the target? I will probably have more thoughts, but overall, well done. Thanks for sharing this with us.
  4. If I am understanding your approach, the script would essentially automate the creation of wrappers. Interesting. What would you do with the override dynamic dispatch methods in the folder? Handled at the parent's virtual folder? So, would my main vi wire up the method that has a DVR terminal?
  5. Can I have multiple subpanels (on the same 'main' vi) show the same opened vi? Each representing its own instance (and access to its own data)? Say forinstance that I have a VI that shows a word from a list. I have three lists - one each for subject, verb and object. I know how to set the value of a front panel item, so I can set a VI's data in that respect. I just cannot seem to InsertVI into multiple subpanels. Any suggestions?
  6. Sorry, this kind of duplicates what Jim just said. I think that Jim would consider only implementing the lock-unlock on an as needed basis. I am not sure that all transactions can be generalized as atomic. The approach of the class as a DVR or always using a semaphore for data access clearly serializes access to the class which defeats the parallel nature. Sure this will protect the programmer from potential pitfalls of non-synchronized access, but it can also bottle neck other threads. 'Atomic' transactions are not just limited to intra-class operations. What about an accounting system where assets have to equal liabilities. Adding an asset then has to have a comparable increase in liability. If I were to implement an OO hierarchy on an accounting system, assets and liabilities would not be one class, but I would need to be able to 'freeze' access to the system while a transaction is completed. In those cases I would probably have some 'token' that I can grab from the accounting system and return when my transaction was done. I would implement the same approach for intra-class transactions. This could get pretty complicated as some transactions are independent (multiple transactions and on semaphore) and others are interleaved (one transaction multiple semaphores - if that is possible). Or I can make my life simple and have only one semaphore for the entire class - invoking as needed. If LV2009 supported some form of dynamic dispatch on a DVR, I do not think we would be having this discussion. It would probably be the opposite - how do I let other threads have asynchronous access to other (read only) methods in my DVR'd class hierarchy. I choose to go to the DVR'd data member route because the programming overhead (time and complexity) to implement a framework that uses class DVRs that supported dynamic dispatch was not appealing. And dynamic dispatch was more important to me than protecting myself from the complexities of multi-threaded programming.
  7. I guess my observation is that the behavior of the vi added to the subpanel is different based on it location in the LabVIEW Project hierarchy. I have attached a simple example to illustrate. I comes from the LV2009 example of subpanels. I added an unused class (TestTermination.lvclass) in the project soley for the purpose of having a 'folder' to drag the vi that is being used in the subpanel. To replicate: 1) Run the Simple Subpanel.vi. 2) Click the Abort Execution button (the red stop sign in the tool bar). 3) Open up the plugin1.vi and note that it is not running. 4) Move the plugin1.vi into the TestTermination 'folder' from LV's Project explorer window. 5) Run Simple Subpanel.vi. 6) Click the Abort Execution button (the red stop sign in the tool bar). 7) Open up the plugin1.vi and note that it IS still running. 8) Optionally create a virtual folder and move plugin1.vi into it. Run again, abort and open plugin1.vi to see that it too has stopped. I hope this helps to explain. The work around is to add an Invoke Method function and use the Abort VI method, ignoring the error in the event that it is not running. SubPanel.zip
  8. Not sure this is the right forum, but it is loosely related to labview classes. So, I created a vi that represented a 'view' of the object. And because it is part of the class (not dynamic dispatch), I have it under the class icon in the project explorer. On a 'main' vi I added a subpanel and wired the refnum of the 'view' vi to the subpanel. All good so far. I run the 'main' vi, but when I "Abort Execution", the 'view' vi, continues to run though no longer visible. (I can open it up from the project explorer window and the execution arrow indicates it is running). If I move the 'view' vi to somewhere NOT under a class icon of the project explorer window - top level under 'My Computer' or even a Virtual Folder - the 'view' vi will terminate automatically - which is what I want. It does not seem to mater where on the disk the file resides. This is probably a feature, but I would like to turn it off. Any ideas?
  9. Two more disadvantages of DVR's data members: 1)DEBUGGING: With DVR'd data members, when you look at an object, all you see is the reference number. This is certainly true for DVR'd objects as well, but perhaps you would be in a IPE more often than just the Read/Write accessor methods. 2)Flattten to XML: Here too all you get is the reference number of the data. Not surprising, just dissapointing. Even with these two additions, I am not swayed until NI comes out with something to help.
  10. SciWare and I have the same first name (yes, with a K), so it was funny to read your first reply as if you were talking to me. I agree with you on all of your points. Your downside point #1 (not knowing if class's data is inside a DVR) is rather critical too. It is very dissapointing to use a class as if its data was inside a DVR and find out that it does not. My solution is to have all of my classes support this concept. I am not sure how painful this is going to be in the long run as my project is in the early stages. I am essentially a one man show on the LVOOP front at my company. My colleagues have lots of LV experience but little OOP. I came on board earlier this year with the oppposite. This forum has been a life saver! Anyway, this extra work is a nuisance and I would rather migrate to an NI implementation.
  11. Thanks for the update. I too have seen the lockup. It can be not-so-obvious too. That is, you could call what appears to be a parent method that then calls a dynamic dispatch method that ends up attempting to access the same DVR you started in. Hope that was clear . All in all, I am finding this a very sweet way to implement objects as references yet still allow me to have dynamic dispatch work. I am still expecting to find a 'gotcha', but for now I am enjoying the feature. I have modified daklu's DVR Composition project such that it implements the member vars as a DVR of a cluster. The original DVR Composition project primarily showed an approach to facilitate Interfaces and Implementations by using DVR's of objects. The addition of DVR member variables eliminated the IPE structures from the general application code seen in Main.vi and reduced the casting that was used inside the IPE of the Multiply By Two Implementation. I hope to post this soon with some screen shots. My biggest problem is that my development machine is not on the network and my network machine is restricted to have only certain applications. So the transfer is just one more hurdle. Between your scheme of DVR'd member variables and daklu's Interface/Implementation work, this solved a huge problem I was having in my project. I also plan on posting some of this too. I am a bit restricted on what my employer will allow me to publish .
  12. I will work on that. I kind of destroyed it when I was playing with it further. I was trying different approaches to the structure. Should have left it alone while it was working. Perhaps deep is a relative term (there are only 5 levels). I will post a diagram soon. I need to grab Visio or something. I work for a huge company and it takes a bit longer to get through the red tape of allocating a license. Anyway, so far it has worked for me. I am using SciWare's approach regarding making the class's private data cluster contain a single DVR to a Strict TypeDef (I can also see advantages to multiple DVRs). I have hit some deadlock situations where IPEs have competed, but that was rather poor implementation on my part. I know I will hit more as I progress, but it seems better appraoch from a class usability standpoint. All of the IPEs are held inside the class's methods (typicaly data access methods). The calling VIs do not know anything about DVRs and DynamicDispatch works great. What is a real pain is debugging. Putting a probe on a wire that represents an object AND that object uses DVRs as member variables - all you see is the refnums! I am not surprised at this. I would like a way to dereference these values in the debugger. Am I missing something?
  13. I am developing something similar. For simplicity I added a string variable to the base object representing a name and also had the 'ObjectManager' keep a separate array of strings. So, I search for an object by name using the 1D array search function. The index found is used in the return the object from the ObjectManager's list. I am doing this in LV2009 not Endevo so I cannot help you on that front. And I don't actually pass around the ObjectManager. I actually have several ObjectManagers and have ManagerOfManagers so to speak to handle the sharing of the ObjectManagers. This in the end may have been overkill but the implementation was fun.
  14. Daklu, I was wondering if you tried to implement this using SciWare's approach of having the class's data members as a single DVR of a TypeDef and not creating a DVR of the object itself (see http://lavag.org/topic/10666-labview-oop-by-ref/). I played around with it a bit on your example and it does clean up the 'Application' part of the VI. All of the IPEs can be inside Get/Set methods. Makes the application programmer's job a bit easier in my opinion. There was an ensuing debate on whether this approach (DVR of data member cluster) was both 'in the spirit' of NI's implementation and safe from a race or deadlock conditions. SciWare any further thoughts on the latter issue? I do not see much risk beyond what is 'expected' when you share references to the same memory across threads. The project I am working on has a fairly deep class hierarchy. One branch of the hierarchy represents hardware components - motors, actuators, sensors, analog outputs. Another branch represents assemblies of these components (or other assemblies) - arms, grippers, thermal baths. My original thought was to have the assemblies hold a DVR to the hardware components. But without the ability of Dynamic Dispatch on a DVR the IPEs were simply too cumbersome. So, in comes SciWare's idea and the IPEs are now buried in the classes Get/Set (sorry NI, Read/Write) methods. Yes, I am worried about deadlock conditions. And a bit worried about performance, but since I am controlling slow mechanical devices (e.g. benchtop robots), speed is not really a concern. I am hoping that others out there are also trying this. I too will give some feedback as my design get implemented a bit further.
  15. Ah, and here I was looking for another right click item - go figure.
  16. LV (2009 in my case) allows you to add multiple nodes to the In Place Element Structure, but I cannot figure out how to remove one that I do not want anymore. Am I missing something? Thanks. Kurt
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.