Jim Kring Posted August 21, 2009 Report Share Posted August 21, 2009 So I thought that if the class just holds the DVR of the datamembers then I get dynamic dispatch without any fuss and I have a reference to my datamembers giving in effect a object that has by ref characteristics. Hi Kurt, I've been looking at your example reference classes (Bike+Racer) and I'm starting to second-guess my decision about wanting to put the DVR outside the object (rather than put the DVR inside the object). I how your example (DVR inside the object) allows dynamic dispatch at the public method level (instead of having a static, by reference method that wraps a protected, dynamic, by value method -- this creates a lot of extra methods). However, one thing that makes me uneasy about putting the DVR inside the object (as your example does) is that each level of the inheritance hierarchy has it's own DVR and is locked/unlocked separately. I worry that this could cause some nasty race conditions or deadlock -- have you thought about this? And, an attempt to remedy this issue takes us back to where we have a lot of framework/support VIs for each class. Cheers, Quote Link to comment
Kurt Friday Posted August 22, 2009 Report Share Posted August 22, 2009 However, one thing that makes me uneasy about putting the DVR inside the object (as your example does) is that each level of the inheritance hierarchy has it's own DVR and is locked/unlocked separately. I worry that this could cause some nasty race conditions or deadlock -- have you thought about this? And, an attempt to remedy this issue takes us back to where we have a lot of framework/support VIs for each class. Cheers, Hey Jim That's a good point that I haven't explored deeply. My first thought is that class Bike has its own DVR to it's datamembers and the child Racer has its own so they are separate and shouldn't interfere with each other. I'll do some tests and see what is involved in breaking it or causing it to lock. Quote Link to comment
Aristos Queue Posted August 22, 2009 Report Share Posted August 22, 2009 Hey Jim That's a good point that I haven't explored deeply. My first thought is that class Bike has its own DVR to it's datamembers and the child Racer has its own so they are separate and shouldn't interfere with each other. I'll do some tests and see what is involved in breaking it or causing it to lock. Talk to Mikael... putting the DVR inside the class sounds an awful lot like the GOOP Toolkit implementation where they wrap a raw reference to data in a class to give it dispatching behaviors. Mikael may have some info about the deadlock potential of this situation. Quote Link to comment
Kurt Friday Posted August 22, 2009 Report Share Posted August 22, 2009 Talk to Mikael... putting the DVR inside the class sounds an awful lot like the GOOP Toolkit implementation where they wrap a raw reference to data in a class to give it dispatching behaviors. Mikael may have some info about the deadlock potential of this situation. We had a beer together last week and realized that we had both come to the same solution. Perhaps we can put our heads together again on this one. Quote Link to comment
Daklu Posted August 22, 2009 Report Share Posted August 22, 2009 Perhaps we can put our heads together again on this one. Beer induced deadlock? Quote Link to comment
Kurt Friday Posted August 22, 2009 Report Share Posted August 22, 2009 Beer induced deadlock? I'm all too familiar with that kind of system failure. Quote Link to comment
Kurt Friday Posted September 10, 2009 Report Share Posted September 10, 2009 However, one thing that makes me uneasy about putting the DVR inside the object (as your example does) is that each level of the inheritance hierarchy has it's own DVR and is locked/unlocked separately. I worry that this could cause some nasty race conditions or deadlock -- have you thought about this? And, an attempt to remedy this issue takes us back to where we have a lot of framework/support VIs for each class. Cheers, I've been having another play with the concept of datamember DVR inside object ref and it’s appearing to be solid. The only thing you need to watch is that you don't perform a method call inside an In Place Structure DVR R/W that acts on the same data. So placing a method of the same class or a parent method with dynamic dispatch will cause it to lock. Placing a parent only method inside a child method's InPlace Structure DVR R/W is OK since it only acts on the parent data which has its own DVR. But in the end it’s the same kind of rules you would use as before when you had lock and unlock primitives in previous architectures. I haven’t been able to create a race condition as a result of implementing parent and child data member DVR’s. Since parent data is accessed in a child by parent methods the data is protected, the data locking protection mechanism exists at all levels of the object hierarchy. Quote Link to comment
K-node Posted September 10, 2009 Report Share Posted September 10, 2009 I've been having another play with the concept of datamember DVR inside object ref and it’s appearing to be solid. The only thing you need to watch is that you don't perform a method call inside an In Place Structure DVR R/W that acts on the same data. So placing a method of the same class or a parent method with dynamic dispatch will cause it to lock. Placing a parent only method inside a child method's InPlace Structure DVR R/W is OK since it only acts on the parent data which has its own DVR. But in the end it’s the same kind of rules you would use as before when you had lock and unlock primitives in previous architectures. I haven’t been able to create a race condition as a result of implementing parent and child data member DVR’s. Since parent data is accessed in a child by parent methods the data is protected, the data locking protection mechanism exists at all levels of the object hierarchy. 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 . Quote Link to comment
Jim Kring Posted September 10, 2009 Report Share Posted September 10, 2009 I've been having another play with the concept of datamember DVR inside object ref and it’s appearing to be solid. The only thing you need to watch is that you don't perform a method call inside an In Place Structure DVR R/W that acts on the same data. So placing a method of the same class or a parent method with dynamic dispatch will cause it to lock. Placing a parent only method inside a child method's InPlace Structure DVR R/W is OK since it only acts on the parent data which has its own DVR. But in the end it’s the same kind of rules you would use as before when you had lock and unlock primitives in previous architectures. I haven’t been able to create a race condition as a result of implementing parent and child data member DVR’s. Since parent data is accessed in a child by parent methods the data is protected, the data locking protection mechanism exists at all levels of the object hierarchy. Hi Kurt, I'm happy to hear you say this, since I've come to the same conclusion while talking it over with other members of my team. IMO, the value of being able to Dyamic Dispatch any method, regardless of whether it's a by value or by reference method, without having to create special, duplicate by reference wrapper methods around dynamic by value methods is huge. The only downsides (that I can see) of using the DVR inside an LVOOP object are: 1) You can't tell just by looking an an object that it's by reference (as you can when you see a DVR with an LVOOP object inside) 2) You have to unbundle the DVR before you can pass it into a IPE Structure Oh, and there's one situation that you also have to be very careful for: If you're inside a child method and you call a parent method inside an IPE structure, you might deadlock if the the parent method is itself, or calls inside of it, a dynamic dispatch method that results in child method being called. With this in mind, one feature that I'd love to see in LabVIEW is for IPE structures to be smart at run-time and output an error (rather than deadlock) if an IPE is called inside another IPE and tries to dereference data that has already been dereferenced by the outer IPE. Cheers! 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 . I see that you posted similar thoughts, just as I was typing up my reply to Kurt, above Cool! It seems that we're all starting to converge on the preferred methodology (pun appreciated but not intended) for by ref OOP in LV2009. I guess that I would add that if NI were to implement either the ability to dynamic dispatch on methods with DVRs of objects OR the ability to wire a DVR of an object into a by value method (dereferencing/referencing behind the scenes) then I would probably migrate over to DVRs containing objects, rather than vice versa. But, until then... Quote Link to comment
K-node Posted September 10, 2009 Report Share Posted September 10, 2009 Hi Kurt, I'm happy to hear you say this, since I've come to the same conclusion while talking it over with other members of my team. IMO, the value of being able to Dyamic Dispatch any method, regardless of whether it's a by value or by reference method, without having to create special, duplicate by reference wrapper methods around dynamic by value methods is huge. The only downsides (that I can see) of using the DVR inside an LVOOP object are: 1) You can't tell just by looking an an object that it's by reference (as you can when you see a DVR with an LVOOP object inside) 2) You have to unbundle the DVR before you can pass it into a IPE Structure Oh, and there's one situation that you also have to be very careful for: If you're inside a child method and you call a parent method inside an IPE structure, you might deadlock if the the parent method is itself, or calls inside of it, a dynamic dispatch method that results in child method being called. With this in mind, one feature that I'd love to see in LabVIEW is for IPE structures to be smart at run-time and output an error (rather than deadlock) if an IPE is called inside another IPE and tries to dereference data that has already been dereferenced by the outer IPE. Cheers! I see that you posted similar thoughts, just as I was typing up my reply to Kurt, above Cool! It seems that we're all starting to converge on the preferred methodology (pun appreciated but not intended) for by ref OOP in LV2009. I guess that I would add that if NI were to implement either the ability to dynamic dispatch on methods with DVRs of objects OR the ability to wire a DVR of an object into a by value method (dereferencing/referencing behind the scenes) then I would probably migrate over to DVRs containing objects, rather than vice versa. But, until then... 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. Quote Link to comment
K-node Posted September 10, 2009 Report Share Posted September 10, 2009 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. 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. Quote Link to comment
Kurt Friday Posted September 10, 2009 Report Share Posted September 10, 2009 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 . Cool, I'd love to see some OOP frameworks, would be great to have a bit of a community effort on this. The only downsides (that I can see) of using the DVR inside an LVOOP object are: 1) You can't tell just by looking an an object that it's by reference (as you can when you see a DVR with an LVOOP object inside) 2) You have to unbundle the DVR before you can pass it into a IPE Structure Good points, would be useful to see at a glance that your object is by ref, but I suppose we are using by value objects in a by ref capability. Perhaps a convention could be started by choosing a specific wire color, I'd suggest a green color which is consistent with other by ref implementations such as File IO, VI Server, control refs. Yes, unbundleing all the time is an overhead and takes up a bit of real estate. At the moment I'm also placing a few more items in the object data other than just the datamember DVR to achieve active objects so its usefull to unbundle and get what I need. It would be nice to just plug the object into the IPE but then how does it know what to unpick since the object can hold many things, multiple DVR's possibly Oh, and there's one situation that you also have to be very careful for: Ifyou're inside a child method and you call a parent method inside an IPEstructure, you might deadlock if the the parent method is itself, orcalls inside of it, a dynamic dispatch method that results in childmethod being called. With this in mind, one feature that I'dlove to see in LabVIEW is for IPE structures to be smart at run-time and output an error (rather than deadlock) if an IPE is called inside another IPE and tries to dereference data that has already beendereferenced by the outer IPE. Ahh, yes, that would get you. At the moment I'm carefull about placing methods inside an IPE unless I have to. If I dont I just use them outside. I agree with you that there needs to be some checking that looks at the method you place and does a check to see if there is any possibility of cycling back to a read on the same DVR 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. A probe on the DVR to show the data would be handy, I suppose the probe would have to implement an IPE behind the scenes and then I can see a situation where you probe your object within and existing IPE and then you get a lockup. I suppose you could make your own custom probe that is a member of your class, a bit like the old object explorer. I'm really happy that everyone is on the same page with respect to implementing by ref objects. Looks like we have a great kickoff point with a workable framework that is easy to implement and doesn't require a heap of support vi's. In the past I've always used my own OOP implementation to give me what I want because LVOOP just wasn't there yet, but now it is and I'm very happy and I have to say a big thank you to NI for working on this Quote Link to comment
Aristos Queue Posted September 10, 2009 Report Share Posted September 10, 2009 Jim Kring wrote: 1) You can't tell just by looking an an object that it's by reference(as you can when you see a DVR with an LVOOP object inside) Strong recommendation we've developed over the last few years: If your object contains even a single refnum, make the wire color be refnum green. I even updated the color picker in LabVIEW 2009 so that refnum green is one of the default colors displayed so it is easy to grab it for your wire designs (it's the last non-gray square in the row of pre-selected colors). Also, I've had a few people suggest that if one member of your private data control is a refnum then all of them should be refnums, so that everything in the object behaves like a reference. I'm not sure what I think of that, but I'll throw it out there for consideration. With this in mind, one feature that I'd love to see in LabVIEW is for IPE structures to be smart at run-time and output an error (rather than deadlock) if an IPE is called inside another IPE and tries to dereference data that has already been dereferenced by the outer IPE. Unfortunately, the bookkeeping on this is significantly problematic. Essentially, you'd need the inside of the IPE to output an array of refnums that are "the refnums I currently have deref'd" and then pass that by dataflow to any nested (including inside subVIs) IPEs. But the subVIs don't have magic secret inputs/outputs that would allow this information to pass along, and trying to do it in a "global store that each IPE checks to see if refnum was used upstream" requires the IPE to know aspects of dataflow that are simply unknowable, such as what nodes are upstream of it. We did kick around embedding the information in the refnum wire itself, but with a reference, there's no guarantee that the reference is used in only one place.In the end, we couldn't find a way for the IPE to tell the difference between a refnum that was dereferenced upstream (and should error) and dereferenced in parallel (that will eventually be released), except in the most trivial of cases. If you're writing circular reference code, you'll need to carry along with the refnum a parallel array of refnums already opened, and at every IPE, manually check whether the chosen refnum is already referenced. 1 Quote Link to comment
Mellroth Posted September 11, 2009 Report Share Posted September 11, 2009 Also, I've had a few people suggest that if one member of your private data control is a refnum then all of them should be refnums, so that everything in the object behaves like a reference. I'm not sure what I think of that, but I'll throw it out there for consideration. I really like to be able to have both byRef and byValue within the same class.That way I can have a number of high speed access members, and still beable to use ByRef on data that need it. So please don't force peopleinto selecting one type or the other. /J Quote Link to comment
Yair Posted September 11, 2009 Report Share Posted September 11, 2009 If your object contains even a single refnum, make the wire color be refnum green. How about also adding a refnum glyph to the banners of these classes (e.g. a folded page or a zigzag line)? 1 Quote Link to comment
Aristos Queue Posted September 11, 2009 Report Share Posted September 11, 2009 I really like to be able to have both byRef and byValue within the same class.That way I can have a number of high speed access members, and still beable to use ByRef on data that need it. So please don't force peopleinto selecting one type or the other. It's definitely not something I would force ever. It's just a recommendation that a couple folks think should be followed. I've had multiple situations where the mixture was useful, and haven't seen any negatives yet, myself. Quote Link to comment
Daklu Posted September 11, 2009 Report Share Posted September 11, 2009 How about also adding a refnum glyph to the banners of these classes (e.g. a folded page or a zigzag line)? I like this idea much better than using green wires. Color is one of the main ways I distinguish between groups of related classes. Quote Link to comment
Aristos Queue Posted September 14, 2009 Report Share Posted September 14, 2009 I like this idea much better than using green wires. Color is one of the main ways I distinguish between groups of related classes. One option: Use an edge of green and a core of something else, similar to the queue wires. Quote Link to comment
Jim Kring Posted September 15, 2009 Report Share Posted September 15, 2009 One thing that I've started doing with the DVR-inside-LVOOP scheme is using an IPE Structure to (un)bundle the DVR reference outside of the IPE that (de)references the private data. I like this a lot because it keeps the object/reference/data wire in straight line without any branching -- it seems to have the best "style". Note that I named the DVR "ref" to keep the (un)bundle nodes small in width. What do you think? 1 Quote Link to comment
Kurt Friday Posted September 15, 2009 Report Share Posted September 15, 2009 One thing that I've started doing with the DVR-inside-LVOOP scheme is using an IPE Structure to (un)bundle the DVR reference outside of the IPE that (de)references the private data. I like this a lot because it keeps the object/reference/data wire in straight line without any branching -- it seems to have the best "style". Note that I named the DVR "ref" to keep the (un)bundle nodes small in width. What do you think? That is nice and neat, I like it. 1 Quote Link to comment
Mark Yedinak Posted September 15, 2009 Report Share Posted September 15, 2009 One thing that I've started doing with the DVR-inside-LVOOP scheme is using an IPE Structure to (un)bundle the DVR reference outside of the IPE that (de)references the private data. I like this a lot because it keeps the object/reference/data wire in straight line without any branching -- it seems to have the best "style". Note that I named the DVR "ref" to keep the (un)bundle nodes small in width. What do you think? I also like the look of that. Does anyone have a basic example of DVR LVOOP object? 1 Quote Link to comment
Kurt Friday Posted September 15, 2009 Report Share Posted September 15, 2009 I also like the look of that. Does anyone have a basic example of DVR LVOOP object? If you scroll back through this tread you will find some demo code that I posted early into this discussion. Just recently I added a By Ref OOP Framework that also includes examples. Quote Link to comment
Mark Yedinak Posted September 15, 2009 Report Share Posted September 15, 2009 If you scroll back through this tread you will find some demo code that I posted early into this discussion. Just recently I added a By Ref OOP Framework that also includes examples. Thanks. I will take a look at it. It gets hard to keep track of all the posts and what has and hasn't been posted. Quote Link to comment
Shaun Hayward Posted September 16, 2009 Report Share Posted September 16, 2009 One thing that I've started doing with the DVR-inside-LVOOP scheme is using an IPE Structure to (un)bundle the DVR reference outside of the IPE that (de)references the private data. I like this a lot because it keeps the object/reference/data wire in straight line without any branching -- it seems to have the best "style". Note that I named the DVR "ref" to keep the (un)bundle nodes small in width. What do you think? Looks nice - I frequently do the same thing - using the IPE structure more for style than its pure function - it is a lot less messy than index array followed by wiring the original array and the desired index across the code to the Replace Element function. Shaun 1 Quote Link to comment
bdp Posted September 21, 2009 Report Share Posted September 21, 2009 Hello All! This may be a stupid question and not the place to ask it and I did do a rudimentary (but possible not sufficient) search, but where does one find a data value reference constant on the control palette? I am thinking specifically about the situation of creating a class similar to the one contained in the project by SciWare: LVOOP2009_ActiveObj.zip In attempting to create my own class with a DVR member, I ran into the problem of where to get the DVR control to place in my strict type definition. It's not in the refnum palette, as I would have suspected and typing "Data Value Reference" in QuickDrop is similarly unsuccessful. My only options were either to copy DataRef.ctl fromthe above project to my own lvclass and change the contained element to my own type or to create a new VI, place a New Data Value Reference primitive on the block diagram, create a constant on its DVR output terminal and drag that to my custom control. What am I missing? Thanks in advance! Brandon 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.