Check out our OOP Code Repository Files or visit the LabVIEW Wiki OOP Portal.
![]() |
Aug 20 2006, 01:09 AM
Post
#1
|
|
|
Changing the world, one VI at a time. Premium Member ![]() Posts: 1649 Joined: 22-October 02 From: San Francisco, CA Member No.: 17 Using LabVIEW Since:1995 LV:8.2.1 ,8.5 ,7.1.1
My Blog
My Gallery
|
Hello All,
I have posted an article on my blog called Refactoring the ReferenceObject example in LabVIEW 8.2, which is an brief analysis of the by reference object-oriented programming example that ships with LabVIEW 8.2. I have created three new examples, which (IMO) greatly improve the usability of this pattern. I look forward to your feedback (please feel free to discuss it here) and any ideas that come out of it that might improve the designs. I have attached the downloadable examples to this post. (They are also available for dowload on the article page.) [Update 8/19/2006: I have updated example 3, after learning about a new LabVIEW feature that allows a queue reference to be linked to a type definition of the element type. Thank you, Philippe Guerit, for telling me about that. Cheers,
ReferenceObject_JK01.zip ( 132.66K )
Number of downloads: 274
ReferenceObject_JK02.zip ( 118.41K )
Number of downloads: 223
ReferenceObject_JK03.1.zip ( 114.74K )
Number of downloads: 316-------------------- Tags
This content has not been tagged yet
|
|
|
|
| Ad |
Aug 20 2006, 01:09 AM
Post
#
|
|
|
Tags
This content has not been tagged yet
|
|
|
|
Aug 20 2006, 12:42 PM
Post
#2
|
|
![]() More Active Member Posts: 37 Joined: 3-December 04 From: Amsterdam, The Netherlands Member No.: 1175 Using LabVIEW Since:2003 LV:8.5.1 ,. ,.
|
Jim,
I only looked at project 3, and I like it. One of the great features of storing by queue reference is the ability to cut loose from the dataflow paradigm. Therefore I added a modified example to project 3 to emphasize the different nature of ReferenceClass.lvclass: its value is static and there doesn't require dataflow. The thick green wire suggests a real object, but it doesn't require dataflow wiring like ordinary objects do. One does need to be careful to prevent race conditions, though. My 2 cents.. Aart-Jan
ReferenceObject_JK03_mod.zip ( 130.19K )
Number of downloads: 217This post has been edited by aart-jan: Aug 20 2006, 02:07 PM -------------------- Tags
This content has not been tagged yet
|
|
|
|
Aug 20 2006, 06:39 PM
Post
#3
|
|
|
Changing the world, one VI at a time. Premium Member ![]() Posts: 1649 Joined: 22-October 02 From: San Francisco, CA Member No.: 17 Using LabVIEW Since:1995 LV:8.2.1 ,8.5 ,7.1.1
My Blog
My Gallery
|
Aart-Jan,
> I only looked at project 3, and I like it. I REALLY like #3, too. I think that it is the way to go, moving forward. > One of the great features of storing by queue reference is the ability to cut loose from the dataflow paradigm. Therefore I added a modified example to project 3 to emphasize the different nature of ReferenceClass.lvclass: its value is static and there doesn't require dataflow. The thick green wire suggests a real object, but it doesn't require dataflow wiring like ordinary objects do. One does need to be careful to prevent race conditions, though. My 2 cents.. Yes, I took it for granted that most people here (on LAVA) would already understand the implications of by reference objects -- this is the GOOP, forum after all
Cheers, -------------------- Tags
This content has not been tagged yet
|
|
|
|
Aug 22 2006, 05:02 AM
Post
#4
|
|
![]() Extremely Active Premium Member ![]() Posts: 582 Joined: 19-June 03 From: Bay Area, CA (USA) Member No.: 121 Using LabVIEW Since:1998 LV:8.2.1 ,8.5 ,8.0.1
My Blog
|
Attached is another version derivated from Jim version 3.
ReferenceObject_PJM03.zip ( 157.62K )
Number of downloads: 212It has the following new functionalities: - GetData is fully asynchroneous (it will not be locked by the GetDataToModify and it will always return data). - Access to named object from asynchroneous process through the create.vi. Drawbacks - To be able to have a fully asynchroneous GetData another queue is used with a copy of the data (if someone can figure out a way to get this without making a copy...) - The create is more complicated (the GetDataToModify, SetModifiedData and GetData are still very simple). Any comments and/or improvements are welcome. PJM -------------------- Tags
This content has not been tagged yet
|
|
|
|
Aug 22 2006, 10:45 AM
Post
#5
|
|
|
Drawing Tool - LVOOP example application Premium Member ![]() Posts: 1154 Joined: 29-January 06 From: Helsinki Member No.: 4014 Using LabVIEW Since:2004 LV:8.5.1 ,8.2.1 ,7.1.1
My Blog
|
The example #3 works for simple classes but it still lacks the ability to use the class with external algorithms that would modify the class content. (Read the post scriptum first...)
To enable this we need some further modifications - addition of new public lock method - this would lock the object and return a "lock reference" - if class user intends to modify a class object based on a result of a class method he needs to acquire a lock - only one lock for the object is allowed simultaneously - during lock all method calls that would alter the object are prohibited - during lock all get_only methods that do not modify the object are allowed (see limitations below) - addition of new public release method - releases object lock - all class methods modified - all methods have a new connector for a "lock reference in" and "lock reference out" - get only methods and methods that do not modify the object - can be accessed when object is locked and lock reference is not wired - cannot be accessed when object is locked and lock reference is wired - all methods that modify the object - cannot be accessed when object is locked unless correct lock reference is wired to lock reference input - all methods wait until the lock is released or timeout is reached unless correct lock reference is provided The programming model for algorithms that are external to the class is following: - acquire lock - get some data from the object - process data algorithm internally - modify the object trough class methods based on the processed data - release lock As an example of an algorithm consider the following An object that is container for some time series data, let's call it DataObject A algorithm that takes DataObject as an input and reduces noice and returns DataObject, let's call it Denoise - Denoise acquires a lock for the DataObject - Denoise gets the time series by calling DataObject.getTimeseries - Denoise reduces noise from the acquired time series - Denoise writes new denoised time series by calling DataObject.setTimeseries - Denoise releases the lock POST SCRIPTUM This kind of programming model closely resembles of functional programming and is often preferred over the programming model where all algorithms are defined as class methods. The advatage is generality and code re-usability, a single algorithm can be applied to a number of different classes as long as classes fullfill certain preconditions. I however started thinking while writing if this kind of functional paradigm can even be used with LabVIEW. In C++ algorithms are implemented using templates to overcome strict typing. Haskell naturally supports algorithms by polymorphic typing. Java algorithms can be defined trough defining common interfaces for the classes. None of these methods is available in LabVIEW. Polymorphism is only available via XNodes, variants, flattened strings and polymorphic VIs. XNodes are not available, variants and flattened strings don't seem to do the thing, and polymorphic VIs require adding a separate VI for each new supported class. I've used scripting to create polymorphic VIs with normal data types but I'm not sure this concept extends to creating class methods; LabVIEW 7.1.1 ,which I use for scripting, doesn't have the concept of classes. NI is propably not going to implement interfaces or templates in a long time. So we are left with manually adding new VIs to polymorphic algorithms. Perhaps the idea of algorithms just don't fit into the world of LabVIEW in it's present stage. Wouldn't be the first programming concept I'm missing... This post has been edited by jimi: Aug 22 2006, 11:38 AM -------------------- Tags
This content has not been tagged yet
|
|
|
|
Aug 22 2006, 04:06 PM
Post
#6
|
|
|
Extremely Active Premium Member ![]() Posts: 347 Joined: 6-August 04 From: Gurnee Illinois Member No.: 584 Using LabVIEW Since:1997 LV:8.5 ,8.2.1 ,7.1
|
Man! do I Love this stuff.
Ok here is something I've been working on since the Beta version but never got there until NI WEEK gave me an Idea. What if we create a class That uses both the by ref model and the by Value model and then inherit the class so any class can be run as a by reference. What I came up with was a class called Flip-Flop. Its purpose is to move the data to either a Variant stored in a Que (By Ref) or the Child class wire itself (By Value). In the Main Vis the class wire data is stored in the Que and when a public function receives the wire it transfers the data to the wire so it can process it. The power of this Idea is it takes full advantage of the new inheritance. Please check this new Idea Out. I'm calling it FLOOP for Flip-Flop OOP.
FlipFlopOOP.zip ( 320.81K )
Number of downloads: 230-------------------- If you are interested in Time saving programming
tools created in LabVIEW then download my Icon Editor Updated July 7th 08 and my SubVI Helper Updated Jan 7th 08 Tags
This content has not been tagged yet
|
|
|
|
Aug 22 2006, 04:28 PM
Post
#7
|
|
|
Changing the world, one VI at a time. Premium Member ![]() Posts: 1649 Joined: 22-October 02 From: San Francisco, CA Member No.: 17 Using LabVIEW Since:1995 LV:8.2.1 ,8.5 ,7.1.1
My Blog
My Gallery
|
Man! do I Love this stuff. Ok here is something I've been working on since the Beta version but never got there until NI WEEK gave me an Idea. What if we create a class That uses both the by ref model and the by Value model and then inherit the class so any class can be run as a by reference. What I came up with was a class called Flip-Flop. Its purpose is to move the data to either a Variant stored in a Que (By Ref) or the Child class wire itself (By Value). In the Main Vis the class wire data is stored in the Que and when a public function receives the wire is transfers the data to the wire so it can process it. The power of this Idea is it takes full advantage of the new inheritance. Please check this new Idea Out. I'm calling it FLOOP for Flip-Flop OOP.
FlipFlopOOP.zip ( 320.81K )
Number of downloads: 230Mark: Actually I was working on the same thing, for the past couple days :-) I've got some ideas too. I think that we're going to come up with something great, here! -------------------- Tags
This content has not been tagged yet
|
|
|
|
Aug 22 2006, 06:20 PM
Post
#8
|
|
![]() Extremely Active Premium Member ![]() Posts: 582 Joined: 19-June 03 From: Bay Area, CA (USA) Member No.: 121 Using LabVIEW Since:1998 LV:8.2.1 ,8.5 ,8.0.1
My Blog
|
Man! do I Love this stuff. Ok here is something I've been working on since the Beta version but never got there until NI WEEK gave me an Idea. What if we create a class That uses both the by ref model and the by Value model and then inherit the class so any class can be run as a by reference. What I came up with was a class called Flip-Flop. Its purpose is to move the data to either a Variant stored in a Que (By Ref) or the Child class wire itself (By Value). In the Main Vis the class wire data is stored in the Que and when a public function receives the wire it transfers the data to the wire so it can process it. The power of this Idea is it takes full advantage of the new inheritance. Please check this new Idea Out. I'm calling it FLOOP for Flip-Flop OOP.
FlipFlopOOP.zip ( 320.81K )
Number of downloads: 230And FLOOP, You got to love this name! PJM -------------------- Tags
This content has not been tagged yet
|
|
|
|
Aug 22 2006, 06:32 PM
Post
#9
|
|
![]() I'm a LAVA, not a fighter. V I Engineering, Inc. ![]() Posts: 3472 Joined: 13-October 03 From: Michigan, USA Member No.: 181 Using LabVIEW Since:1993 LV:8.5 ,. ,.
My Blog
|
Once you guys have got something up and running, don't forget to get it out there by using OpenG or the LAVAcr...
-------------------- ![]() Tags
This content has not been tagged yet
|
|
|
|
Aug 22 2006, 11:18 PM
Post
#10
|
|
![]() LV R&D Envoy NI ![]() Posts: 1144 Joined: 15-August 06 From: Austin, TX Member No.: 5877 Using LabVIEW Since:2000 LV:8.5.1 ,. ,.
My Gallery
|
(Jim, what follows is mostly stuff I already sent to you in e-mail, but it seems useful to post here.)
I am thrilled at all the different implementation mechanisms that Jim has proposed. But there's an underlying assumption that he makes: that we are searching for the One True Way to implement a reference class. I disagree. I think we're searching for all the good ways to implement references, and that there is no One True Way. Different implementations serve different use cases, and I think in time LabVIEW users will standardize around a set of reference models, not one single model. Example: Jim argued that the programmer should make "Check In.vi" and "Check Out.vi" private. That's true if and only if the programmer has created wrapper VIs for all the member VIs of the original class and replicated them on the reference class and if there is no performance gained from doing a Check Out, doing multiple function calls, and then doing a Check In.
Keep the ideas coming ... most folks (both inside NI and outside) don't agree with me, but I truly think that every LabVIEW developer who moves beyond a set of Express VIs on a single diagram will eventually consider classes as normal and standard as VIs. We've got to get it right in these early years. PS: Jim described his case #3 as the hands down winner. In my eyes, the "con" would be: * Reference API has to supply all possible permutations of operations for efficiency. If I have a reference to a Numeric, I need my reference class to have methods for Add and Multiply. I also need to have "Square and add another square then take the square root". Otherwise I'll have to do a check in and check out between every step of the mathematics (very inefficient). With the Check Out as a public function and the a class as the queue's type, I can check out and do a whole stream of operations, still with my class shield in place to protect the data from arbitrary changes, and only do a single check in. -------------------- "A VI outside a class is a gun without a safety. Data outside a class is a target."
--- A message from LabVOOP R&D Tags
This content has not been tagged yet
|
|
|
|
Aug 23 2006, 11:05 AM
Post
#11
|
|
|
More Active Member Posts: 30 Joined: 22-August 05 From: Stockholm, Sweden Member No.: 2808 Using LabVIEW Since:1996 LV:8.5 ,8.2.1 ,7.1.1
|
To add material to the discussion I post another design pattern. If you want to separate the by-reference semantics from the class, this is one way to do it.
I have implemented a separate container class: ObjectRepository. It has the ability to store any LabVIEW Object. The idea is that if you want to use a class by value you don't need to do anything. If you want to store the class by reference you create an instance of the ObjectRepository. On the up side: - Separetes the class from the way it is stored or handled. - The ObjectRepository can be used for any native class without adaptation On the downside: - Explicit downcast is needed when you read the object from the ObjectRepository since it returns LabVIEW Object. It has a potential for run-time errors. Without templates we cannot create generic type safe containers. - Code readablity; to pass the object by reference you actually wire an instance of the ObjectRepository. - Probably more, haven't spend too much thougth on it. Disclaimer: There may be some flaw in the implementation, it was a quick hack to show an idea. Jan
Attached File(s)
Tags
This content has not been tagged yet
|
|
|
|
Aug 24 2006, 06:52 AM
Post
#12
|
|
|
Very Active Member Posts: 162 Joined: 28-April 06 Member No.: 4885 Using LabVIEW Since:1994 LV:8.0.1 ,8.20 ,7.1.1
|
I made two examples yesterday that mimics a chunk of memory in a computer in a single LV2 style global with an array inside. It is a ref making system and makes real references for any kind of variable using variants and another version using LVOOP. It is very efficient, particularly the LVOOP, and compared with using queues it is fully asynchronous.
The other thread is here: LV2 style ref Tags
This content has not been tagged yet
|
|
|
|
Aug 26 2006, 12:55 PM
Post
#13
|
|
|
Drawing Tool - LVOOP example application |