Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Inheriting from Multiple AF Extension Libraries

Solved!
Go to solution

Hi, I was wondering if anyone has ideas about the following.

 

My team has created several extensions to actor framework that inherit from the base actor class. For example, we have a logging extension that overrides the handle error VI and sends a log message. Another extension is a config manager actor that adds some messages and overrides the pre launch init VI to initialize the configuration.  Each library is separate and individually inherits from the base actor class.

 

Now my problem is that I have a project where I want the capabilities of both extensions in my actor. I can't inherit from both, only one or the other. Only a couple ways I can think to do this.

 

1. Change the inheritance chain so that the config manager actor inherits from the logger actor, which inherits from the base actor. This seems bad because now my config manager has a dependency on the logger actor, which it doesn't actually need. And maybe I don't need the logger actor in a different project. Plus if I have more extensions my inheritance chain is going to be full of stuff I don't need.

 

2. Include both the logger actor and config actor classes in the private data of my actor. In VIs that each extension overrides, create a new override VI and manually call the extension VI. This seems bad since it creates a lot of extra plumbing and complexity. Plus I would need someway to forward messages to extension actor objects (maybe call each extension actor core from my actor's core).

 

Is there a better way that I'm not considering?

0 Kudos
Message 1 of 10
(4,643 Views)

Consider using composition instead of inheritance.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 2 of 10
(4,630 Views)

 


@Taggart wrote:

Consider using composition instead of inheritance.


Sure, but that's what his Option #2 is about ...

 

To properly resolve this issue we need Traits in LabVIEW. We started discussing Traits  at the CLA Summit yesterday. Perhaps would continue discussing today as well ...

 

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

Sounds like all of the best things are discussed at CLA summits.

 

Off topic, but does any of this usually become public? In a location other than kind bloggers' reviews/reports?


GCentral
0 Kudos
Message 4 of 10
(4,611 Views)

 

 

on second thought here is a suggestion using inheritance:

 

Make a parent class that all your classes inherit from called Base Actor (except for the logger)

 

Make a logger actor.  You just send it a message with a string and it logs it.

 

Then have all your other actors inherit from the Base Actor.  Base Actor contains an enqueuer for the logger (NOT the actor itself) in its private data. Do your override to log all errors in this class as well. Just pass whatever you want to log by sending a message.  Also give it a method which sends a string to the logger to log.  Make it protected so any children of Base Actor can easily log and you don't expose the enqueuer to the logger, so noone can stop it or send it extraneous messages.

 

Then have your root actor launch the logger first (it can also be a child of Base Actor and store the enqueur in its own private data) and pass the enqueuer to each of your  Actors before they get launched (ie. give Base Actor a method to set the Logger Enqueuer)

 

For configuring actors, I recommend putting all your config information in a file.  Have a configure method in Base Actor that takes in a file path. Pass each actor the file before you launch it. Then each class in your heirarchy pulls whatever it needs out of the file.  

 

You do run the risk that not every actor needs configured, and not every actor has something to log, but I think most do.  So it does add a little bloat.

 

 

 

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
Message 5 of 10
(4,605 Views)

@Dmitry wrote:

 


@Taggart wrote:

Consider using composition instead of inheritance.


Sure, but that's what his Option #2 is about ...

 

To properly resolve this issue we need Traits in LabVIEW. We started discussing Traits  at the CLA Summit yesterday. Perhaps would continue discussing today as well ...

 


To your point, yes traits would help. 

 

to point 2 - I think you don't want to include the actor itself, but the enqueuer.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 6 of 10
(4,604 Views)
Solution
Accepted by mbremer

@mbremer wrote:

Hi, I was wondering if anyone has ideas about the following.

 

My team has created several extensions to actor framework that inherit from the base actor class. For example, we have a logging extension that overrides the handle error VI and sends a log message. Another extension is a config manager actor that adds some messages and overrides the pre launch init VI to initialize the configuration.  Each library is separate and individually inherits from the base actor class.

 

Now my problem is that I have a project where I want the capabilities of both extensions in my actor. I can't inherit from both, only one or the other. Only a couple ways I can think to do this.

 

1. Change the inheritance chain so that the config manager actor inherits from the logger actor, which inherits from the base actor. This seems bad because now my config manager has a dependency on the logger actor, which it doesn't actually need. And maybe I don't need the logger actor in a different project. Plus if I have more extensions my inheritance chain is going to be full of stuff I don't need.

 

2. Include both the logger actor and config actor classes in the private data of my actor. In VIs that each extension overrides, create a new override VI and manually call the extension VI. This seems bad since it creates a lot of extra plumbing and complexity. Plus I would need someway to forward messages to extension actor objects (maybe call each extension actor core from my actor's core).

 

Is there a better way that I'm not considering?


In my opinion, inheritance should map always a “Is - a” relationship. For example: "Cat is an animal" is good. "Cat is a paw and a stomach and a fur" is bad. That's why I'm against the 1st option.

For 2nd option, I have created a small example. I have a child class inheriting from the father class. In addition, child should have properties of the mother. Because LV does not support multiple inheritance, one must use composition. That means to create a passive object of the mother class in the child class and some wrapper VIs for actions and member accessors. For a caller actor it should appears that it communicate with a child object.  For this, I override the Receive Message.vi in the child class. There I check if a mother message arrives and call the corresponding child wrapper VI.Childs Receive Message.png

 

If Child action need some input parameters, downcast the message like in Do.vi and wire inputs with message data.

 

I may miss some complications, but at first glance that should work.

0 Kudos
Message 7 of 10
(4,583 Views)

@p4keal In my opinion, inheritance should map always a “Is - a” relationship. For example: "Cat is an animal" is good. "Cat is a paw and a stomach and a fur" is bad. That's why I'm against the 1st option.


For 2nd option, I have created a small example. I have a child class inheriting from the father class. In addition, child should have properties of the mother. Because LV does not support multiple inheritance, one must use composition. That means to create a passive object of the mother class in the child class and some wrapper VIs for actions and member accessors. For a caller actor it should appears that it communicate with a child object.  For this, I override the Receive Message.vi in the child class. There I check if a mother message arrives and call the corresponding child wrapper VI.Childs Receive Message.png

 

If Child action need some input parameters, downcast the message like in Do.vi and wire inputs with message data.

 

I may miss some complications, but at first glance that should work.


I think this solution makes the most sense, at least until (if?) traits or mixins are implemented in LabVIEW.

 

I wonder if it makes sense to create an AF extension class that inherits off the base actor and handles the composition plumbing for you.  You would register a number of extension (passive) objects with the actor (add to object array), and it would handle calling the extension overrides for you (call override for each object in the array).

 

Another way to go would be to create extension classes and let the user place them in the appropriate locations (i.e. place "Log Error.vi" in the handle error override).  Would be a lot of manual plumbing, but maybe you could use VI scripting to connect everything for you.

0 Kudos
Message 8 of 10
(4,560 Views)

Excuse me what is a trait or mixin?

Got it.

 

 

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

I stumbled across my old post.... That's quite weird to check the class by its name in Receive Message.vi.
Meanwhile, I think there is a better way without having to override Receive Message.vi. We can use the new LV2020 feature interfaces. Define an interface for the class whose VIs should be called.  Inherit the "child class" from the interface. Override the vis of the interface and call parent's vi inside. The updated example is attached.

0 Kudos
Message 10 of 10
(2,399 Views)