06-09-2016 10:09 AM
what i do not get is why the command_name is not a parameter....
Maybe it helps if you look into the Actor Framework. This is an configuration which sounds similar to your requirements... specificially the Message classes.
06-09-2016 10:44 AM
That's a logical question, for sure!
The guts of the command_name VI builds the command in G. The output of the VI is the command reference. If I made the command_name a parameter, then I'd have one dynamic dispatch VI in my method builder (good). In it, I'd have a case structure for each and every command I want to deliver (bad). In each case, the G-code that builds the command. Then I'd have to build the complete API into each method builder (really bad).
Consider the case where Customer B's Cmd_Def_Shine_Shoes.vi is a little different than Customer A's. All I want to do is define one VI in Customer B's class, "Cmd_Def_Shine_Shoes.vi". When I load the customer from disk, I specify Customer_B.lvclass and voila, Customer B gets a cream polish instead of a paste polish.
Originally I didn't want to name names, so I just wrote, "I'd like to avoid one class per method". In my mind, I was thinking, "Someon's going to throw NI's Actor Framework at this, and I don't want a class per method."
06-10-2016 02:35 AM
[...]In each case, the G-code that builds the command. [...]
What does that code look like for most cases?
I currently image string handling (e.g. for TCP interface).....
06-10-2016 02:50 AM - edited 06-10-2016 02:51 AM
Does anyone know of a supported way to skin this cat?
I'm starting with the assumption that there's currently no way to call DD VIs dynamically. You could try using the old Control Value.Set + Run VI methods combo, but I haven't checked if that works.
Assuming it doesn't, if you're in LV, one option is to script it - have code which will basically generate a VI along the lines of your original code and run it. You could even have a scheme where this happens at run time and the VI is regenerated and reloaded if the list of VIs has changed.
I'm also ignoring the possibility of doing this a completely different way, as I haven't read your use case closely.
06-10-2016 08:43 AM
Thanks for taking a look Sir tst. As I was implementing your Ctrl Val.Set suggestion, I was thinking about how hard I'd kick myself if it worked. All the years I've spent calling that method! Alas, it didn't work, at least not in how I implemented it (attached). Interesting, I found, was that it wanted to work. The method VIs had some knowledge of which class they belonged to, but they failed to dynamically dispatch the plugin's method. I give it a silver star for effort!
Scripting...My fears are I'll either reach a similar result, or that I'll spend a lot of time joining class data from scripted objects with the object already loaded in my application. Or both.
FWIW, the guts are not something I could distill into strings. It's very G, which is why I'm writing it in LabVIEW 🙂
06-10-2016 08:52 AM
Honestly, i am wondering why you work with classes at all. That setup seems to be ..... wrong by design.
However, if you re-wire the class input to Get LV Class Path.vi to the loaded class instead of the Basic.lvclass constant, i think the VI works as you originally thought it would.....
06-10-2016 09:10 AM
I could see how, in a generalized snippet of this specific derived requirement, classes might seem wrong. It's good to challenge design decisions. This particular design has been vetted. In all other aspects, native LabVIEW OOP supports my requirements well. I tried to follow your suggestion (attached), but I obtained the same results.
06-10-2016 09:15 AM
the main VI in the V2 somehow looks very incorrect....
That is what i meant before:
I hope you see the difference compared to your V1....
06-10-2016 09:22 AM
That's cheating! It's true, that version will run the plugin's methods, but AFAIK, it doesn't run the base class' methods.
06-10-2016 09:23 AM
I should have wrote, "AFAIK, it doesn't dynamically dispatch anything."