LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

modularity: how to automatize new actions without modify code (remove hard coding)

hello

my program communicates with a printer.
in a database whe have 1 kind of sheet per client, with dynamic fields, identified by labels
When a specific client is detected, the printer application is able to find the right sheet and update its dynamic fields depending on the product serial.


problem:
dynamic fields implies that every times a client requires a label update (new or less dynamic fields), I have to modify the sourcecode to hard encode the new label fields to modify.

Sans titre.png


my idea:
-create objects "label field" that represent each dynamic field in the sheet. each one manages 1 dynamic field (serial, date or code) and has its own methods (build value, send, receive)
-from my database, get a table containing dynamic fields's names to invoke.
-in a for loop, call the object having the same name of fields's names invoked.

constraint:
-I don't want to go inside the code again. I want those object to be external and to be called by name.

question:
-is it feasible?
-how to make objects external in a way to call them dynamically
-do you suggest another way to do?

thanks in advance for your help

Pierre FCentum TNS, Grenoble
Certified LabVIEW Associated Developer
0 Kudos
Message 1 of 13
(2,771 Views)

I am going through a similar mess right now with my hardware drivers.  What you need to do is develop Packed Project Libraries.  These are libraries that are fully compiled.  So you can then develop a plugin architecture so that to load an object, you just give a path to the PPL and the class within it.  It is a pain up front, but it gives you what you want.

 

You might want to give this article a look: Plug-in Architecture using Packed Project Libraries


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
0 Kudos
Message 2 of 13
(2,741 Views)

If your code is not flexible now, and you want it flexible, I'm afraid you need to refactor ("go into the code") at least once.

 

Personally, I'd do this with OO. I can't really see how to do it without anymore. This situation seems like a perfect fit. Maybe even a reason to switch if you haven't already. You'd be able to add a new child class without any problems, dynamic (as a plug-in) or by adding the class to the code without changing anything else and rebuild.

0 Kudos
Message 3 of 13
(2,723 Views)

you can also use a template, for example, a html file.  in the file you can create variables that your application will replace with actual values.  for example,

 

<html>

<body>

text here <img src=%VARIABLE1%> <br>

Date: %VARIABLE2%

</body>

</html>

 

your application would searches for the %VARIABLE1% and replace it with whatever value, then do the same for %variable2%, then either display or print the html file.  you will need one template for each client, and a map of the variable names to the actual values to be used.

 

-Joe

0 Kudos
Message 4 of 13
(2,693 Views)

@Pierre_F wrote:

hello

my program communicates with a printer.
in a database whe have 1 kind of sheet per client, with dynamic fields, identified by labels
When a specific client is detected, the printer application is able to find the right sheet and update its dynamic fields depending on the product serial.


problem:
dynamic fields implies that every times a client requires a label update (new or less dynamic fields), I have to modify the sourcecode to hard encode the new label fields to modify.

Sans titre.png


my idea:
-create objects "label field" that represent each dynamic field in the sheet. each one manages 1 dynamic field (serial, date or code) and has its own methods (build value, send, receive)
-from my database, get a table containing dynamic fields's names to invoke.
-in a for loop, call the object having the same name of fields's names invoked.

constraint:
-I don't want to go inside the code again. I want those object to be external and to be called by name.

question:
-is it feasible?
-how to make objects external in a way to call them dynamically
-do you suggest another way to do?

thanks in advance for your help


I love it!

 

And I'm sure it can be done with only one turn of the source code and you are starting along the right direction.

 

You need "Fields" where each type of Field has a Type property with Get and Set methods for such types attributes.

 

"MyFieldOfDreams" may be of type "Baseball" inherited from the Sport Class with a method that increments "Score"  when ball is hit out of the park.  Or it may be of tyoe "Barley" inherited from the Farm Class that has a method that adds to "Bank Account" when time has elapsed without a "Natural Disaster" occurance.

 

Notice I discribed them in writing!  So a *.ini or a *.xml or a *.txt file could be constructed to discribe those fields too.  ini and xml have pre-defined interfaces.  Next: What thoughts did that kick into your head?


"Should be" isn't "Is" -Jay
0 Kudos
Message 5 of 13
(2,685 Views)

kanks for your replies

 

I have tried to create class 'label field' then created herited objects 'field1date' 'field2code' etc...

 

I finished the development but for the moment did not validate what I did. I keep you informed.

Pierre FCentum TNS, Grenoble
Certified LabVIEW Associated Developer
0 Kudos
Message 6 of 13
(2,666 Views)

hi I have a new problem...

 

here is what I tried:

 

Sans titre.png

 

1) created general "label field" class

2)created subclasses "field1LDN", "field2date" herited from the general one

3)compiled Lvlibp containing the field subclass, 1 lvlibp for one subclass, then stored it in a folder

 

now I'm calling those objects with the code I send you joined (LV2015) + illustration above

 

4)constitutuion of the lvlibp path depending on the name of the label field

5)using of the function "get exported file path" and "get LV class default value"

6)"to more specific class" pointing to the general label field class

 

it doesn't work Smiley Sad

error 1448 "LabVIEW:  Bad type cast.  LabVIEW cannot treat the run-time value of this LabVIEW class as an instance of the given LabVIEW class."

Am I in a good way?

Pierre FCentum TNS, Grenoble
Certified LabVIEW Associated Developer
0 Kudos
Message 7 of 13
(2,638 Views)

You can't just cast any class to another. Is the dynamically loaded class a child of the type you're casting to? It should. Try casting to a LabVIEW object. This won't get you far, but at least you can check the loading mechanism and go from there.

0 Kudos
Message 8 of 13
(2,631 Views)

Hi

 

I used this way because the different classes to call have differents methods (but methods have the same name).

 

The picture I show is inside for loop from wich the output class is auto indexed.

 

then this array is processed in another indexed for loop, inside a dynamic dispatch VI.

 

if I remove "to a more specific class" the wire will be the one of a generic Labview class, that will not work in my dispatch VI

 

an idea? :'(

 

 

how can I pass them without using "with a more specific class" given that

Pierre FCentum TNS, Grenoble
Certified LabVIEW Associated Developer
0 Kudos
Message 9 of 13
(2,621 Views)

Pierre_F wrote: 

I used this way because the different classes to call have differents methods (but methods have the same name).


AFAIK that's not enough. The dynamically loaded child needs to be marked as having a parent with the same name. You cannot any cast a class to any another, even if the names are the same.

 

So the class that you put in the packed library, needs to have a parent with the same name and interfaces (basically the entire declaration needs to be the same) as in the executable. If not, the cast will fail.

 

You do need the cast, but only after you're sure the dynamic loading is perfect.

0 Kudos
Message 10 of 13
(2,616 Views)