Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Launch an actor with arguments passed from launching VI?

Solved!
Go to solution

Is there an elegant way to launch an Actor (root or nested) wherein the initial values of the class's private data are passed as arguments from the launcher and thus pre-set to some value (which is not necessarily the object's default) and available via accessors or unbundles within the "Pre Launch Init.vi"?  From what I can tell researching so far, the framework allows only an Actor with the "Make Current Value Default" settings of its private data to be launched, and then a subsequent message to change that data with a Write accessor.  But by this point it's too late because we are already in "Actor Core.vi"  and the pre-launch init has already happened.  Thanks!

0 Kudos
Message 1 of 10
(1,912 Views)
Solution
Accepted by topic author Nate@UT

You can create property accessors for your Actor. Then simply set the values via a Property Node before launching the Actor.

0 Kudos
Message 2 of 10
(1,909 Views)

Or you add a method "Launch.vi" to the class that wraps Launch [Root | Nested] Actor and has on its conpane all the stuff you want to bundle in, and then you do the bundling on the block diagram. 

0 Kudos
Message 3 of 10
(1,881 Views)

I have to regularly remind myself that Actors are, at their core, Objects. Before they're launched, they're just regular ol' by-value Objects where you can set properties, call methods, etc.

 

I usually have a "New [xyz] Actor" VI that has all of the required inputs on it, and outputs an Actor that I can then send to Launch Nested Actor (or Launch Root Actor or whatever).

 

One thing I find myself wishing for is some way to make sure an Actor has been properly "prepared for launch". I haven't found a solid universal way to prevent just dropping an Actor object cube on the diagram and wiring it to Launch. Bad/sentinel default values are one way to do it so Pre Launch Init fails, but it would be nice if there was a more universal "this object needs to be created using a constructor* not just plopping it on the diagram" method. You can of course add a Boolean with no public accessors that you set in your constructor* method, which is then later checked in PLI but it seems a touch clunky since you have to redo it for every override that needs it. Adding the boolean to Actor.lvclass won't work, because there's a potential for each override level to need their own flag. A single Actor could have multiple requirements for proper construction.*

 

*Yes I know LV doesn't do "constructors" since the object is instantiated when you drop the cube, I just don't have a better word for "it won't ever work with just a cube, you gotta throw in some initial values before this Actor can launch"

Message 4 of 10
(1,842 Views)

@BertMcMahan wrote:

One thing I find myself wishing for is some way to make sure an Actor has been properly "prepared for launch"... A single Actor could have multiple requirements for proper construction.


Use the Builder Pattern perhaps?

 

Message 5 of 10
(1,826 Views)

One thing I find myself wishing for is some way to make sure an Actor has been properly "prepared for launch"... A single Actor could have multiple requirements for proper construction.


Make the nested actor class a private member of a library. Add a public method to the library that takes the initialization values and launches the actor. 

(You will play some access scope games with the message classes, but it can be done.)

Message 6 of 10
(1,815 Views)

@AristosQueue wrote:

A single Actor could have multiple requirements for proper construction.

 


My intent would be that this must be a manually settable thing that would happen in the "constructor" function(s). That way any checks for complete settings can happen and then the "I'm good to launch" is set correctly. Basically, this is the edit-time version of checking for resources in Pre-launch Init, as I'd like to check for programmer mistakes (like trying to launch an Actor that was never properly initialized) as opposed to user mistakes (like setting the wrong config values).

 


@AristosQueue wrote:

Make the nested actor class a private member of a library. Add a public method to the library that takes the initialization values and launches the actor. 

(You will play some access scope games with the message classes, but it can be done.)


Aaaand that accomplishes exactly what I'd like to do in these cases! For some reason it never occurred to me that class constants could be set to Private scope, but it's obvious in retrospect. Thanks a ton for pointing that out! This gets me the "edit time mistake detection" behavior without having to actually run the code to throw an error.

 

(Can you tell I don't make API's for other people very often? 😁)

 

Re: the Builder pattern: that looks like a great way to implement complicated constructors. I typically don't need those but it's a good tool to have in my belt, so thanks for the link.

Message 7 of 10
(1,792 Views)

@AristosQueue wrote:


Make the nested actor class a private member of a library. Add a public method to the library that takes the initialization values and launches the actor. 

(You will play some access scope games with the message classes, but it can be done.)


I'm trying this approach with a Root Actor that uses a User Event to return information to the caller.  The event data is a cluster of an enum ("type") and variant ("data"), with the cluster and enum being TypeDefs within the actor class.  The actor's public launcher VI returns an event registration refnum which works fine when passed to an Event Structure within the: the type enum is used with a Case Structure and the data variant is converted based on the type.

 

A problem arises when the actor is launched within a subVI and the registration refnum needs to be output from this: I get block diagram errors because the two TypeDefs can not be accessed in private scope.  If I move them outside the actor class to the same location as the public launcher, everything works correctly, but it feels wrong that they're now not part of the actor itself.

 

Any suggestions of a more appropriate way to handle this scenario?  A couple of simplified diagrams attached to illustrate the two situations.

Actor launch with no block diagram errorActor launch with no block diagram errorActor launch in subVI with block diagram errorActor launch in subVI with block diagram error

0 Kudos
Message 8 of 10
(1,706 Views)

Why can't you make the typedef public access within the Actor? I believe AQ's suggestion was that the actor class itself be private, not everything in the actor.

 

Also, you could stick the Actor (private) and the Launcher (public) into a Library along with the typedef (public), assuming you want to keep the typedef outside the Actor.

0 Kudos
Message 9 of 10
(1,690 Views)

That was the solution for me, thanks Bert.  I'd just tied myself slightly in a knot with what sat where and had which access scope.

0 Kudos
Message 10 of 10
(1,570 Views)