Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Why add abstract message to private data?

This is probably a dumb question but I am stumped.  I've been going over the examples and materials posted here for literally months.  I'm trying to figure out the proper way to make use of abstract messages in AF.  When I use the message maker to "Create Abstract Message for Caller", a constant of the resulting message is added to the private data of the actor that owns the message.  Why is this?  Why would I ever need to hold an instance of that message object in the actor that is intended to receive the message?  Shouldn't the message be added to private data of the actor that will be sending the message?  The fact that the message lands in "Abstract Messages for Caller" seems to imply that the message classes should be in the actor that calls the actor from which the message is made?

CLAD
Message 1 of 11
(5,899 Views)

When you create an abstract message for an actor, you are defining a message type, and implying that the actor will send a message of that type to its caller.  The abstract message defines the data that will be sent, but does not provide any instructions for what to do with that data.

 

It is up to the caller to provide a concrete child of that type, which implements those instructions.  However, at edit time, there is no way for the nested actor (the one with the abstract message) to know which child message to send to its caller.  This is the point - the nested cannot know anything about its caller, and so can't know what specific child of its abstract message to send.

 

That is why the nested actor has an instance of the message type in its attributes.  Notice that, along with the new attribute, you also get a write accessor that lets you specify the actual child message to send.  Before it launches the nested actor, the caller should pass its child implementation of the abstract message to the nested actor using this accessor.

 

Make an instance of the Actor Framework sample project (the Evaporative Cooler), and look at Evaporative Cooler:Actor Core to see an example.

 

Take a look at the Send VI for the abstract message.  You'll notice that it takes the message type as input.  When the nested actor sends its abstract message, it should use the actual message type stored in its attributes.

 

Take a look at Water Level:Get new Level (also in the sample project) to see how this is done.

 

This is kind of a slippery concept for a lot of people, so don't fret too much if it takes a while to wrap your head around it.

Message 2 of 11
(5,874 Views)

Ah, so the association of messages with an actor is reversed with abstracts compared to regular AF messages.  That makes sense, because as you say the whole point is that the nested actor can't know anything about the caller, so the nested actor library has to own all the messages.  Am I close?

 

The abstract messages owned by an actor are "to" more than "for" the caller?  Describing the concept gets pretty verbose, but would it be correct to call the folder in which abstract messages land "Abstract Messages for Caller (to Implement)"?  

 

Maybe I'm lending too much weight to the semantics of the message maker, but the "for Caller" bit makes me think there's a problem inherent in using an abstract message sent from the caller to the nested actor.  Is two-way communication generally OK to implement with abstract messages?

 

Thanks for your help!

CLAD
0 Kudos
Message 3 of 11
(5,845 Views)

@testingHotAir wrote:

Ah, so the association of messages with an actor is reversed with abstracts compared to regular AF messages.  That makes sense, because as you say the whole point is that the nested actor can't know anything about the caller, so the nested actor library has to own all the messages.  Am I close?


More than close. You got it.

 


@testingHotAir wrote:
The abstract messages owned by an actor are "to" more than "for" the caller?  Describing the concept gets pretty verbose, but would it be correct to call the folder in which abstract messages land "Abstract Messages for Caller (to Implement)"? 

Yes, that would be a valid name. If we used this naming scheme, I'd probably use "to Override" instead of "to Implement", but you get the idea.

 


@testingHotAir wrote:
Maybe I'm lending too much weight to the semantics of the message maker, but the "for Caller" bit makes me think there's a problem inherent in using an abstract message sent from the caller to the nested actor.  Is two-way communication generally OK to implement with abstract messages?

More than OK... abstract messages were invented specifically to allow two-way communication in a way that doesn't bind the nested actor to the caller actor (and sometimes vice versa, but that's rarely as big a problem since a caller actor generally knows exactly the type of its nested actors except in some rare configuration-based systems).

Message 4 of 11
(5,841 Views)

I am playing around with LV2016 and have some questions and an wish:

  1. In LV2016 the abstract message wizzard creates a member variable in actor cluster but not accessors for this variable. Does it have a reason? In my opinion at least the write accessor is neccessary in most cases.
  2. LV2016 AF Template virtual folder names of Alpha and Beta does'nt fit to AF wizzard. This is not good for AF beginners.
  3. I would wish a extension for AF wizzard: creation an action VI beginning from an abstract message. Now the way is:
    1. Create a VI with an interface fitting to the abstract msg.
    2. Click at VI ->AF-> Create child of abstract message
    3. Select the wanted msg

I sugges: Click at abstract msg -> create action for caller. A list with all actors in project should appear. After selection of desired caller actor the wizzars creates a empty member VI from dynamic or static dispatch template with correct interface and a child of abstract message.

0 Kudos
Message 5 of 11
(5,825 Views)

@p4keal wrote:
  1. In LV2016 the abstract message wizzard creates a member variable in actor cluster but not accessors for this variable. Does it have a reason? In my opinion at least the write accessor is neccessary in most cases.

No accessors are created because those aren't generally meant for you to directly manipulate. Use Send on the abstract parent class to send the message, and send writes the value. You shouldn't need either the read or the write.


p4keal wrote:
  1. LV2016 AF Template virtual folder names of Alpha and Beta does'nt fit to AF wizzard. This is not good for AF beginners.

I see no place where the names do not fit. Please post a screen shot.

 

PS: The word "wizard" is spelled with only one "z".

 

0 Kudos
Message 6 of 11
(5,810 Views)
@AristosQueue (NI) wrote:
I see no place where the names do not fit. Please post a screen shot.

AF Template.png

 

Please compare the project and directory structure of Alpha (created by template) and Actor created by AF WiZard




No accessors are created because those aren't generally meant for you to directly manipulate. Use Send on the abstract parent class to send the message, and send writes the value. You shouldn't need either the read or the write.


My be I misunderstood this point, but In LV2014 projects I always create a write accessor for an abstract message object variable. Before launch of nested actor the root sets some concret messages to the nested actor.

0 Kudos
Message 7 of 11
(5,807 Views)

@p4keal wrote:
Please compare the project and directory structure of Alpha (created by template) and Actor created by AF WiZard.

I see. Good catch. When you said "fit", I was looking for something where the text was clipped on screen. You just mean it didn't match. I'll look into fixing that for 2018.

 


@p4keal wrote:

My be I misunderstood this point, but In LV2014 projects I always create a write accessor for an abstract message object variable. Before launch of nested actor the root sets some concret messages to the nested actor.


Some people do it that way. Others do it by sending the concrete message embedded in some other message when they actually need it so that the nested actor doesn't have to store that from moment to moment. This is especially common for abstract messages that will be sent from many nested actors to the common parent. Given the two different patterns of usage, we don't assume one or the other.

0 Kudos
Message 8 of 11
(5,804 Views)

Ok so I'm making progress, but am confused again.  Is there any way to avoid data dependencies between the caller actor and the nested actor when abstract messages are being sent from the caller to the nested actor?  At some point prior to launch, the caller needs to be given the correct message classes.  In order to pass those messages, my nested actor needs some sort of "expose messages" method.  That means I need to be able to verify that the nested actor is of the correct class prior to launching it, which introduces a dependency.  

CLAD
0 Kudos
Message 9 of 11
(5,779 Views)

 


@testingHotAir wrote:

Ok so I'm making progress, but am confused again.  Is there any way to avoid data dependencies between the caller actor and the nested actor when abstract messages are being sent from the caller to the nested actor?  At some point prior to launch, the caller needs to be given the correct message classes.


It is generally assumed that the Caller gets to know everything about its Nesteds at edit time.  When designing a Caller, you know it will have certain Nested actors that will accept certain messages - there aren't very many ways around this requirement.  You can keep this knowledge to a minimum - I know I am launching an actor that takes a certain set of messages,  although I have no knowledge of how it will respond to those messages - but you have to know something.  So it is permissible for the Caller to know the specific child message it will receive at edit time.  It is a zero coupling solution, but the zero coupling only goes one way - Nested to Caller.

 

If you need to decouple the Caller from Nested - where the Caller doesn't know much about the Nested it launches - look at low coupling.  In this case, you make a parent actor with a set of virtual methods - dynamic dispatch methods that contain no code - and messages for each of those methods.  Make children of this parent actor that implement the virtual methods to do interesting things.  Then write your Caller to launch the Parent actor, and make that Parent actor an attribute, not a block diagram constant.  Then, you can set the actual child to be launched by using an accessor.

 

Zero couple to your Caller.  Low couple to your Nested.

Message 10 of 11
(5,775 Views)