LAVA Forums Buy cool LAVA gear Forums RSS Feed

Welcome Guest ( Log In | Register )

Tags
This content has not been tagged yet

> Related links

Check out our OOP Code Repository Files or visit the LabVIEW Wiki OOP Portal.


3 Pages V   1 2 3 >  
Reply to this topic Start new topic
> Refactoring the ReferenceObject example in LV 8.2
Jim Kring
post 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
United States us_california Nothing Selected 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. smile.gif ]

Cheers,

Attached File  ReferenceObject_JK01.zip ( 132.66K ) Number of downloads: 274

Attached File  ReferenceObject_JK02.zip ( 118.41K ) Number of downloads: 223

Attached File  ReferenceObject_JK03.1.zip ( 114.74K ) Number of downloads: 316

--------------------
-----------------------------------------------------------------------------------------------------
| Book | OpenG | LAVA | Champion | VIPM | Builder | Blog | JKI |
-----------------------------------------------------------------------------------------------------


Tags
This content has not been tagged yet
Go to the top of the page
+Quote Post
Ad
post Aug 20 2006, 01:09 AM
Post #















Tags
This content has not been tagged yet
Go to the top of the page
Quote Post
aart-jan
post 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 ,. ,.
Netherlands us_california Nothing Selected


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-JanAttached File  ReferenceObject_JK03_mod.zip ( 130.19K ) Number of downloads: 217


This post has been edited by aart-jan: Aug 20 2006, 02:07 PM

--------------------
Aart-Jan


Tags
This content has not been tagged yet
Go to the top of the page
+Quote Post
Jim Kring
post 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
United States us_california Nothing Selected 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 smile.gif . The implications being the following:
  • data does not flow. only a reference flows, unchanged, which points to the data
  • forking a wire copies the reference but not the data
  • race conditions and locking must be considered, since calls may be made in parallel
I think that your additional example drives these points home. Another example that I like is a dual loop, where each loop has a reference to the object and one loop modifies the data (calls SetValue) while the other loop reads the data (calls GetValue). On that note, there is a very nice (IMO) overview of by reference GOOP in appendix D of LabVIEW for Everyone, 3rd edition (this appendix is 20 pages long).

Cheers,

--------------------
-----------------------------------------------------------------------------------------------------
| Book | OpenG | LAVA | Champion | VIPM | Builder | Blog | JKI |
-----------------------------------------------------------------------------------------------------


Tags
This content has not been tagged yet
Go to the top of the page
+Quote Post
PJM_labview
post 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
United States France Nothing Selected My Blog


Attached is another version derivated from Jim version 3.

Attached File  ReferenceObject_PJM03.zip ( 157.62K ) Number of downloads: 212


It 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

--------------------

Got VIPM?

JKI . VIPM . EasyXML . OpenG . LAVA . Builder . Blog



Tags
This content has not been tagged yet
Go to the top of the page
+Quote Post
Tomi Maila
post 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
Finland Nothing Selected Nothing Selected 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... smile.gif

This post has been edited by jimi: Aug 22 2006, 11:38 AM

--------------------
Tomi Maila



Tags
This content has not been tagged yet
Go to the top of the page
+Quote Post
mballa
post 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
United States us_illinois us_michigan


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.


Attached File  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
Go to the top of the page
+Quote Post
Jim Kring
post 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
United States us_california Nothing Selected My Blog My Gallery


QUOTE (mballa @ Aug 22 2006, 09:06 AM) *
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.


Attached File  FlipFlopOOP.zip ( 320.81K ) Number of downloads: 230


Mark: 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!

--------------------
-----------------------------------------------------------------------------------------------------
| Book | OpenG | LAVA | Champion | VIPM | Builder | Blog | JKI |
-----------------------------------------------------------------------------------------------------


Tags
This content has not been tagged yet
Go to the top of the page
+Quote Post
PJM_labview
post 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
United States France Nothing Selected My Blog


QUOTE (mballa @ Aug 22 2006, 09:06 AM) *
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.


Attached File  FlipFlopOOP.zip ( 320.81K ) Number of downloads: 230

And FLOOP, You got to love this name!

PJM

--------------------

Got VIPM?

JKI . VIPM . EasyXML . OpenG . LAVA . Builder . Blog



Tags
This content has not been tagged yet
Go to the top of the page
+Quote Post
crelf
post 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 ,. ,.
Australia United States Nothing Selected 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
Go to the top of the page
+Quote Post
Aristos Queue
post 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 ,. ,.
United States Nothing Selected Nothing Selected 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.
  • Making the check in/out functions public is a model where the data is mostly used by value and the reference is created only occassionally for a particular value. It is similar to "Index array, do a bunch of modifications, replace element in array."
  • Making the check in/out functions private is a model where the reference model is the primary way the class is used. That model is like "Tell Array Y to do the following modifications to index X."
Both implementations are valid concepts, and both are useful depending upon the architecture being implemented. Many customers have argued that NI should put forth a standard by-reference implementation so that everyone uses the same system, but I've got half a dozen "standards" that I can envision, each serving a different design goal. I'm more comfortable letting conversations like this one run for a while before NI starts putting an official standard together -- I think we need to see the full range of what develops in the world before anyone can definitively say what the standard(s) should be.

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
Go to the top of the page
+Quote Post
Jan Klasson
post 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
Sweden Nothing Selected Nothing Selected


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)
Attached File  ReferenceContainer_v1.zip ( 105.47K ) Number of downloads: 640032
 


Tags
This content has not been tagged yet
Go to the top of the page
+Quote Post
bsvingen
post 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
Norway nor_north_trondelag Nothing Selected


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
Go to the top of the page
+Quote Post
Tomi Maila
post Aug 26 2006, 12:55 PM
Post #13


Drawing Tool - LVOOP example application
*