From 11:00 PM CDT Friday, May 10 – 02:30 PM CDT Saturday, May 11 (04:00 AM UTC – 07:30 PM UTC), ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Is it possible to use plugins with AF?

Solved!
Go to solution

I was wondering if it is possible to use a plugin architecture using the standard AF where a developer works on some actor, saves it as (something like a DLL or exe or maybe PPL (I don't have any experience with them)) and then can navigate through some caller actor that loads that particular actor at runtime (i.e. from a file that it does not know exists at compile time).

I think I've seen a measurement system by Eli Kerry doing this using linked network actors, but as I understand it the whole queue-> localhost network stream was required to make it work, as it is a common denominator between the app instances.

0 Kudos
Message 1 of 10
(5,850 Views)

Yes.  I have a general-purpose application framework based on AF (actually based on State Pattern Actor AF) that loads everything at run-time as plug-ins.  With everything zero-coupled.  (Config files or scripts hook everything together at run-time.. and tear it down at run-time, too, to build something different -- run a different test, etc.)

Works great.  No worries.

Message 2 of 10
(4,634 Views)

This sounds promising. Would you have any examples to share? In particular I'm wondering how you go from "class constant into launch nested actor" into "load something from disk" and likewise how you prepare that something beforehand (what kind of file is it?)

If you're using zero coupling, then can I assume that the calling actor must at least need to implement do.vi's for all possible plugins beforehand?

0 Kudos
Message 3 of 10
(4,634 Views)

My emloyer won't allow examples.  But it's not that complicated to do.

You shouldn't be using very many class constants in any app (use controls instead), but you ultimately start with a class name if you're using plug-ins.

In my system, the plug-in actors are named with a string that matches their class name.  This name is the same string used to name the files on disk, which is where your plug-ins originate.

So you're really going from a name of an actor class, which is its file name, to using the LabVIEW built-in to load from disk; this VI returns an instance of the class.  You can then launch that instance using "Launch Nested Actor".

I don't prepare my actors before launching except to give them a unique identity -- another name string.  The actors are responsible for preparing themselves to run, once they're launched.  Config files, XML, scripts, etc. can be referenced by a launched actor to determine how to set itself up.  (It has a unique name which allows referencing a unique set-up.) 

They can also send messages to ask how to set up some things.  (They all have "caller actors", except for the Root Actor -- but it's a special case in any architecture.

You don't need Do.vi's for all possible plug-ins.  You only need an agreed-upon API for each actor so that other actors know how to interface to them.  Zero-coupling means that a given actor doesn't know anything about other actors that interact with it, only that they use base classes of things that have a well-established API for their use.

I'm using a glorified publish-subscribe protocol (mainly, along with an ability to send what amounts to a call-back as part of request messages).  Actor A can request Actor B be launched so that Actor B can perform some sort of service for it.  Then Actor A can subscribe to data that Actor B produces.  (Similar schemes can also be used to broadcast events, request data semi-synchronously, etc.)

My system works to move coupling between actors out of the source code and into files of some sort (i.e., text files that could be scripts or config files -- things the end-users can safely edit) so that the code doesn't have to be modified just to run different tests, alter behavior, control different hardware, etc.

Everything is extensible/override-able, modular, and based on plug-ins and external configuration files to control everything.  So the base system can be extended to handle new instruments, new protocols, new methods, etc. without changing the code, just adding code.

Message 4 of 10
(4,634 Views)

Yes,

I also do this.

I use "Get LV Default Class Value" with a path that I read from a config file. Then use "To More Specific Class" to cast it to the parent type. I use zero coupling too. I put the reply message classes in here, right before launch. Then launch.

Casey

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

0 Kudos
Message 5 of 10
(4,634 Views)

Yes, this is a straightforward technique that works great.  But be aware that once loaded, you can't unload a class.  LV doesn't allow that (yet).

In my system, I happen to insert my reply message classes post-launch, with the ability to determine which ones to insert at run-time (and the ability to load them as plug-ins as well. 

"Everything's a plug-in", just as "Everything's an object".

0 Kudos
Message 6 of 10
(4,634 Views)
Solution
Accepted by topic author rik_aspinall

I posted an example that does zero coupling along with loading actors at runtime. Looking at this should show you the techniques to use.

https://decibel.ni.com/content/thread/36645?tstart=0

Brad Remenak
Certified LabVIEW Architect
0 Kudos
Message 7 of 10
(4,634 Views)

This is very helpful! It sounds like an architecture I am about to embark on creating.

Brad Remenak
Certified LabVIEW Architect
0 Kudos
Message 8 of 10
(4,634 Views)

Remy, thanks for sharing such a great example! I see how you have organized things, and I can see how Casey's input reduces the coupling. Just a small point - when building the .exe, I had to copy your Calculation Actors into the .exe folder (or adjust the build to put the exe in the main project folder) to get it to work - all part of the adjustment for when the RUNTIME condtion is true.

0 Kudos
Message 9 of 10
(4,634 Views)

No problem. I do have a newer version I plan to post at some point. I cleaned it up a bit more with the other suggestion from Casey about how he usually uses the Enquerer method. But everything else stays the same. I still want to try and figure out a way for the calculation actor to send back its message type to the calculator instead of building the array of message classes in the calculator (This is the last suggestion by Casey that hasn't been implemented)

I am glad you got it to work as an exe. I am not sure I actually tried building the exe (I went to look for my built exe and it didn't exist), but what you did was exactly how I would have done it.

Brad Remenak
Certified LabVIEW Architect
0 Kudos
Message 10 of 10
(4,634 Views)