Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Nested Actors

I have an AF project that is using nested actors.  Actor A is started then Actor A selectively launches several Actor B's based on events occuring. The problem I am having is that everytime Actor A launches an Actor B, a new Actor A is created.  Is there a code example of an Actor launching several other Actor instances?  How should the send queue be handled?  I am new to AF and trying to wrap my head around it.  Thank you for the assistance.

Ken J

0 Kudos
Message 1 of 22
(6,832 Views)

Can you provide a diagram of your class hierarchy? I suspect that Actor B is a child of Actor A when it shouldn't inherit from A at all.

0 Kudos
Message 2 of 22
(4,489 Views)

Can you post the portion of the code where you launch your nested actors?

0 Kudos
Message 3 of 22
(4,489 Views)

Hi David,

I do have Actor B as a child of Actor A.  I want Actor B to inherit the properties of Actor A.  I want the messaging to go between Actor A and all the Actor B's.  Actor A is the system controller and the Actor B's need to pass status to and receive commands from Actor A.  Is there a better way to do this?

Ken J

0 Kudos
Message 4 of 22
(4,489 Views)

Actually is is OK to have the inheritance.  If more Actor A's get launched when you launch an B, perhaps their is a Call Parent Node from B that makes the launching of another A happen?

0 Kudos
Message 5 of 22
(4,489 Views)

Thanks Kurt,

There is a Call Parent Method for Actor A in the Actor B Actor Core but it is required.

Ken J

0 Kudos
Message 6 of 22
(4,489 Views)

That's what I was referring to. Because you're forced to launch all dispatches of Actor Core.vi in an Actor, if A has a dispatch and B inherits from it with its own dispatch, you'll get both dispatches every time you launch a new B. You can create an "abstract actor" for A where Actor Core.vi isn't overridden and all must-override requirements are passed on to its children, but that may not serve your use case.

If you need unique Actor Core functionality in each of A and B (like a displayed UI panel for each), then you'll either have to disable the logic in A's Actor Core.vi when the actor object is an instance of B.lvclass (so the A.lvclass:Actor Core.vi is a no-op when launched), or you'll have to make A and B sibling children of Actor.lvclass.

Message 7 of 22
(4,489 Views)

David, Yes, I see what you are saying.  I had not thought of that because most of my actors are faceless but if an Actor Core.vi presents a UI, I probably would not derive from it or I would get a bunch of UIs - though each set would actually belong to the same actor.  So there are not really multple Actor A's started, just the front panel of Actor A's Actor Core .vi.

Ken, Perhaps you can set your Actor Core.vi execution defaults to NOT show front panel when called.  Then have a message sent to the Actor to show it's front panel.  When Actor A received the message, clearly it shows it's front panel.  Actor B when sent the same message would process that message for itself.  You might need to store the VI ref of the Actor Core front panel.

Another way is to take your UI loop out of Actor Core and make it its own dynamic dispatch VI.  Your root Actor Core would call the ShowUI.vi method.  Actor A would show one thing and Actor B would show another because Actor B's ShowUI method is different and would not call the Call Parent Node.

Alternately you could have additional actors that are the UI's for each Actor and leave Actor A and Actor B faceless.  I do something similar to this, except that they are not Actors, but rather EventLoops.  Same idea, but using events.  Yes, this mixes messaging schemes and I know somewhere AQ has said he's not seen good results from that (not quite his words).  But I am restricting what this does.  It still communicates with its 'owning' actor via messages.  I need an event loop anyway for user interaction.  The other nice thing this gives me is a way to display the data of one actor in multiple ways.  I can show a graph, a chart, a histogram, etc of say XY data, but the data is actually stored in the Actor and only presented to the user in the UI event loop.

Not sure I was clear on any of this.  Someday I hope to write something about it though my employer is not a fan of sharing.

Kurt

Message 8 of 22
(4,489 Views)

I'm getting a strong itch to drag this thread down a sweet rabbit hole about how to structure Actor hierarchies for decoupling UIs from their core logic and internal state, but we already beat that horse to death at the last CLA summit.

Staying on point, I realize that I recommended testing the actor object type to see if it's a child of A...I don't know if you can in fact do that in LV. If I get an object from a control of type Actor.lvclass, how can I find out which of type A.lvclass or B.lvclass the object actually is? I throw together a quick test using the "To More Specific Class" and "Preserve Run-Time Class" prims, and neither gave me useful information (like an error) when trying to cast a B to an A.

0 Kudos
Message 9 of 22
(4,489 Views)

> I throw together a quick test using the "To More Specific Class" and "Preserve Run-Time Class" prims, and neither gave me useful information (like an error) when trying to cast a B to an A.

That's because it is perfectly legitimate to cast a B object as an A object if class B inherits from class A. Any B *is* an A.

You've got two options:

a) Use the Get LV Class Path.vi and compare the path of the unknown object against the path from a default A object.

b) Add a dynamic dispatch method to A called "Get Class Name.vi", return "A" in that method and then override it in B to return "B".

There are other workarounds, as David mentions, but for direct fixes, these are the two choices.

Message 10 of 22
(4,489 Views)