LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
sbus

New Array and Cluster Properties (Primarily When Using Control RefNums) - Cleaning Up the Implementation

Status: New

INTRODUCTION

 

Dealing with arrays that are passed by reference (using control RefNums) to a SubVI has much more utility if it is NOT necessary to extract a local copy of the array in order to play with it. In additiion, there are some properties missing from arrays and clusters that would make it much easier to write code, and which seem to be consistent with other objects' property offerings.

 

Note: All proposed properties are IN ADDITION to existing properties. The behavior of existing properties is NOT changed.

 

NEW PROPERTIES

The following is a list of the proposed new properties:

NEW ARRAY PROPERTIES

ArraySize

ElemIndex

ElemRef

ElemRefs[]

 

NEW CLUSTER PROPERTIES

ControlLabels[]

 

DISCUSSION

 

Array Sizing 

CURRENT:       If you pass an array reference to a SubVI and want to know the size of the array, you need the wire the array "Value" property to the reference (which allocates space

                         and creates a local copy of the array) so that you can then wire the array to ArraySize to find the number of elements in the array.

 

PROPOSED:    I propose a new array property "ArraySize"  to return the number of elements in the array. This would have identical functionality as ArraySize.vi, but would be implemented

                         as a property where it can be used with array RefNums.

 

Deriving References to Array Elements

CURRENT:       If you want to traverse an array and generate a list of references to all elements in the array, you have to first set the "NumCols" and "NumRows" to 1, and then use IndexVals

                          (to set which element is indexed) followed by "ArrElem" to actually get the reference.

 

PROPOSED:   It'd be a lot sweeter if two more properties were added to arrays; the first would (obviously!) be an index function that is NOT related to the visibility properties of the array (as is

                        "IndexVals"). Let's call this new property "ElemIndex". Of course, in order not to break existing code, you cannot let the "ElemIndex" property cause damage to programs that currently

                         use "IndexVals", so we also need a new property (let's call this one "ElemRef") that returns the reference to the element in place of "ArrElem".

 

Obtaining References to Multiple Array Elements

CURRENT:     Currently the "ArrElem" property returns a reference to a single element.  it would be nice to get an array of references to elements in an array in the same manner as you can get

                        an array of references to all controls in a cluster using the cluster "Controls[]" property.

PROPOSED:  So let's create another array property called "ElemRefs[]" that returns an array containing a reference to each element in the array.

 

Identifying Cluster Members Obtained Using "Controls[]"

CURRENT:    The "Controls[]" property of clusters suffers from the problem that you have to know the order of elements in the cluster if you are looking for a specific cluster member. If you write

                      code using "Controls[]" then you are dependent on the order of elements in the cluster. When the cluster is a strictly typed control, this defeats the advantages of strict typing. The

                      effect is that when you change the type definition of a strictly typed cluster so that either (1) the order of elements change, or (2) you insert or delete an element, you have to rewrite

                      code that used the "Controls[]" property if that code needed to identify specific cluster elements and not just process all elements identically.

PROPOSED: A new property,  "ControlLabels[]", alleviates this problem and adds significant utility to clusters, especially those strictly typed. The ControlLabels[] property when added to clusters

                      allows the references returned by the "Controls[]" property to be matched to a specific cluster element using that cluster element's label. The ControlLabels[]  array returned would

                      be the labels of all cluster elements in the same order as the references returned by the "Controls[]" property (which is in the same order you see with "Reorder Controls in Cluster") .

                      This means that code written for a type defined cluster will still work if the type definition is modified either in the order of controls in the cluster, or if new elements are added or deleted

                      (so long as the deleted element wasn't one that was handled specifically in the code!).

 

 

 

 

 

10 Comments
AristosQueue (NI)
NI Employee (retired)

Your first suggestion is good.

 

The next two are impossible by design. There is only one element control. The full set of all properties of a control are not replicated for each element of the array, which is what would be required to support properties varying by each element. That single element control is redrawn in each position, and the only visual that changes is visuals tied to the value property. Replicating all the properties for every element of the array is prohibitively expensive and would make it impossible to render most large arrays without an unacceptable amount of overhead.

 

The last suggestion I'm ambivalent about. You can easily loop a list of references and ask for label if that's your goal.

 

I gave kudos for the first suggestion.

fabric
Active Participant
I'd also love an array size property! Kudos for that...
drjdpowell
Trusted Enthusiast

> Dealing with arrays that are passed by reference (using control RefNums) to a SubVI has much more utility if...

 

It would be better to use a DVR, rather than a Front-Panel control, to pass an array by reference.  

AristosQueue (NI)
NI Employee (retired)

> It would be better to use a DVR, rather than a Front-Panel control, to pass an array by reference. 

 

I agree. The Array Size property is primarily in case I want to resize the array control to show all the elements, or something like that.

Manzolli
Active Participant

Kudos for Array Size.

André Manzolli

Mechanical Engineer
Certified LabVIEW Developer - CLD
LabVIEW Champion
Curitiba - PR - Brazil
Intaris
Proven Zealot

I agree with the array size proposal.  So much so I posted ages ago about it.....

sbus
Member

So one of the things I don't understand is why the compiler can't AUTOMATICALLY suppress copying data whenever possible WITHOUT the user providing hints in the form of an in-place element. Many compilers generate internal semaphores to protect critical data JUST FOR THAT REASON, and do so on-the-fly without the user needing to provide instruction or write special code...

 

My understanding of DVRs is that they have a semaphore attached, and the data can only truly be accessed within an in-place element. I assume the semaphore is obtained when the DVR is passed into the in-place element and released on exit. So if I want the data to be used in parallel, even if neither modifies the data I would need two in-place elements, and they'd actually operate sequentially rather than in parallel due to the semaphore... So SUGGESTION1: arrange it so that you can mark in-place element border-nodes as read-only; anything that wanted to modify the value passed thru THAT border node would generate an exception; but border nodes marked read-only would NOT acqure the semaphore... thereby not blocking border nodes (on any in-place element operating in parallel) that used the same DVR as input. In addition to allowing more user control over parallel processing, this would also make it more useful to pass DVRs to SubVIs since if they SubVI needed read-only data access it would consume less overhead (no semaphore acquire/release).

 

I pass references to arrays to SubVIs. Sometimes the SubVI operates on the array elements. Sometimes it passes on a particular element to a different SubVI. I want to be able to control whether the array and array elements have to be loaded into memory when accessed thru the reference. (Remember: I['m a C programmer; I'm used to pointers). The idea of getting the array size WITHOUT loading into memory lets me control loops that pass indexes and references (to arrays or to array elements) without using memory when I don't need to access the data, just pass it on. However, the use of references (*not* just DVRs)  is limited, and I think there's a way to make them way more useful. So SUGGESTION2: Add a border node ("Get/Put Value") to in-place elements that gets/sets the underlying data value from a reference (rather than requiring you to use the Value property). An example is pictured (ungracefully!) here, along with two other implementations illustrating less memory and cpu cycle efficient (but functionally equivalent) ways of doing the same thing. What I want to accomplish is NOT copying the data into memory just because of the "Value" property...:

 

And finally, a QUESTION1: If I were to take the unbundle-modify-bundle used in examples 1 and 3, and make that a nested in-place element using an Unbundle/Bundle border node, would that save me anything?

 

Suggestion 2

 

 

sbus
Member

AQ:

 

1. I don't understand why ElemIndex and ElemRef would require properties of elements. They would in essence simply allow the user to traverse the element list and get a reference to one of the elements from the control without using visibility of the control to do so. That functionality exists now if we set the visible cell...

 

2. One of my major issues with references is the limitations on  their use. For instance, a reference to an array requires the entire array to be instantiated in memory to find its size (yes, I'm aware that may be fixed soon), to access one element, etc. It would seem that if there were an array  property (Elements[]) that gave you an array of references to each array element that would be useful because you would then be able to instantiate (get the Value of) only specific elements in the array. Coupled with my prior suggestion (the "Get/PutValue" Property we could update array elements by reference without ever instantiating (copying into local memory).

 

It seems that 'visibility' is the issue; but I don't understand why getting access to array contents and visibility of array contents can't be separated. Leaving the 'Value' property alone, the idea of ElemIndex and ElemRef is that visibility is NOT an issue; just memory access. The arrays I'm using are usually hidden; there IS no actual visibility. And even if the mechanics are implemented as such, it still makes sense to provide a separate method of examining array contents memory. There is also a precedent; the AllObjects[], Controls[], and Decorations[] properties...

tst
Knight of NI Knight of NI
Knight of NI

It's important to understand that a control is not a variable and a reference is not a pointer. In LV, a control *should* be used either for user interaction (hence AQ's note about a single control - he's refering to the actual control drawn on the screen) or as I/O in a subVI. If you want to operate on actual data, you use wires to keep the data, not controls. When you do that, LV does optimize memory allocations (including if have controls on the FP of a subVI and you pass data through them).

 

This is a completely different paradigm to that of C, so it can be confusing.


___________________
Try to take over the world!
Goks
Member

I kudoed for Array Element's Reference Property..!! I am too looking for the same..  🙂