LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Best Practices: Initializing parent properties by children

My use case is parametrization of processing of continuous DAQmx channel acquisition. The results of DAQ come in array of waveforms, the idx is the array index. Every processing type has one or more waveforms as inputs and a method for computing the output.

 

Simplified scheme of my abstraction:

Parent class: Processing.lvclass

Parent properties: Processing name (string, e.g. division), Processing Inputs (array of {description, idx})

Children: Division.lvclass, Add.lvclass, Average.lvclass... with distinct properties.

 

Now I want each children to set the parent Inputs property its own way (Average.lvclass has one input with simple description "input", while Division.lvclass will have two inputs with descriptions "dividend" and "divisor"). The user will only fill the idxs (on what element of waveform the processing is computed).

 

The cool thing I want to achieve is that the classes would be loaded dynamically from folders.

 

My idea:

Create a parent method called "Init CORE", which is overridden by children and has 0 inputs and 1 output called "Processing Inputs" and contains only a constant value, different for each children. Then a static parent method Init would just call the specific "Init CORE" method based on actual class and use the output to write its "Processing Inputs" property.

 

My other idea:

Involve a map with keys "Class name" (string) and values "Descriptions" (array of string). Every time I want the user to specify the idxs, I would search the map and prefill the "Processing Inputs" array. But the map would have to be stored in a separate file, which means adding a Processing type would mean also editing this file. It seems clumsy to me.

 

Is there any other, maybe already established way? Which one do you like best?

 

Sorry for the long post, here's a potato.

VitSlaby_0-1663745392778.jpeg

 

0 Kudos
Message 1 of 5
(904 Views)

I would take care of these differences at the time of instantiation, probably by defining a unique static dispatch "Create" function for each of the children.  Being static dispatch, each child's version can have different terminal wiring to accomodate the different parameters needed for various kinds of processing.  Those parameters get stored as class data within the child object so the child function "Process" can access them when needed.

 

At the application level, only parent-level functions should exist on the diagram to let dynamic dispatch do its magic.  The one exception is when the *actual* object (whether parent, or one of many possible children, grandchildren, etc.) gets instantiated. 

 

I'm not a major expert on LVOOP, but this kind of approach has seemed to work out pretty cleanly.   Others may offer better ideas.

 

(And thanks for the potato.  It made me chuckle -- and respond.  Here, have a spider.)

image.png

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 2 of 5
(878 Views)

@VitSlaby wrote:

 

The cool thing I want to achieve is that the classes would be loaded dynamically from folders.

 


This limits your options significantly.

 

All initialisation of your modules will have to adhere to a common parent-defined set of input data (connector pane).

 

If the initialisation is self-contained (not dependent on user input) just declare an "init" VI in the parent, and handle everything internally with only obejct input and output and any data which is required by ALL instances. Each child knows its parent and then knows how to handle its own initialisation.

 

Where things get complicated is handling dynamic input (strings, I32 whatever). If you want to be able to load dynamically, you have to keep a standard connector pane, which prevents you from doing class-specific initialisation in your calling code. The code must be handled within the object itself.

Message 3 of 5
(836 Views)

@VitSlaby wrote:

The cool thing I want to achieve is that the classes would be loaded dynamically from folders.


What I do is keep a configuration file (XML or JSON format) that I use to initialize my drivers.  I just pass in the JSON object or the XML node and the children can grad whatever information they want from that.  Part of those JSON object/XML node is to state what class to load.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 4 of 5
(826 Views)

The two possible variations are:

 

1) make something that creates initialized classes based on 'generic settings mechanism',

2) make some 'generic settings mechanism' and make each class use it to initialize itself.

 

'Generic settings mechanism' could be anything. A map, variants, strings (JSON, ini, XML), a file reference, a databse (mySQL, SQLight, etc.) even REST or (g)RPC,,,

Message 5 of 5
(797 Views)