Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 
Reply

When to call Initialise; Helper Loops

Solved!
Go to solution
Highlighted

Hi all,

 

I am looking for some advice on what I am doing wrong. Apologies if this is old, resolved history; I couldn't find anything sufficiently relevent when I searched.

 

In essence, I want to call Initialise in a Parent (it is a relevant method for the Children) but I want to access the private class data generated therein in the helper loop of the Child. I would normally put the Initialise call in the Actor Core of the Parent (solution 1), or send a message to the Parent/Child Actor to call Initialise (solution 2), or put the Initialise call into the Pre-Launch Init (solution 3), or call the Initialise in the Child and split the Initialise methods (solution 4) .

 

But in this case I also want to write some references to Parent Actor Core FP items in the private data. The Parent's Initialise requires access to these references to function properly, so I can't just put them in Pre-Launch Init, right?

 

Also the Child needs access to the private data for it's helper loop to function. But, putting the Initialise in the Parent's Actor Core or calling it using a message means that the method is only called in the Call Parent method in Actor Core, which is necessarily occurs after a branch into a helper core.

 

A workaround could be to allow the helper loop to have access to the private data, or make some method where I can send this data to the helper loop. I read something about snap shots, but I don't like how this goes against encapsulation and could result in race conditions.

 

I could split out the Initialise function into two parts, one that is required by the parent and one for the child, but that doesn't seem very to optimise code reuse. Plus I am not really sure what to call this method; a sure sign I am not doing SOLID properly!

 

I prepared a project to illustrate this sort of thing.

 

Any advice welcome!

CLA - Kudos is how we show our appreciation for comments that helped us!
0 Kudos
Message 1 of 11
(353 Views)

Can you please save the project for 2017?

Programming languages don't create bad code, programmers create bad code....
0 Kudos
Message 2 of 11
(341 Views)

Good point, I have updated the first post with the 2017 version!

CLA - Kudos is how we show our appreciation for comments that helped us!
0 Kudos
Message 3 of 11
(328 Views)

Provided I have understood your use case right....

 

1.) Define Parent

a.) Define Initialise Message Class calling Initialise.vi; message data includes everything you need to pass

b.) Make sure, Initialise.vi is dynamic dispatch

c.) Make sure, all the required data from the message is transferred into Parent properites.

2.) Create Child

a.) Implement Initialise.vi to call parent and do the rest of required stuff (child specific)

b.) implement the Helper Loop in Child and once you have all needed data available, fire an initialise message to Child Actor

 

Hope I haven't forgot anything....

 

 

 

 

Programming languages don't create bad code, programmers create bad code....
0 Kudos
Message 4 of 11
(325 Views)

Hi,

 

Thanks for your breakdown Oliver, it sounds like you are recommending to launch the helper loop after I have performed the Initialise in the Child. That sounds great, but how can I achieve this? The only way I can see of doing this is to call Initialise as a method on the Child object wire, but then if I have Initialise in the Parent too then it will be called again when the Call Parent Actor Core call occurs! I could test if the interface is already open when the second Initialise gets called, but this seems ugly!

 

I think it would have been helpful to actually describe my use case.

 

I have a set of instruments, they are digitiser/FPGAs made by different manufacturers. I have a Digitiser parent and children representing the manufacturers. The children each have different methods to communicate with their digitisers. For instance, one type requires a method to be called to pull the data, while the other puts data into network stream. The first type has a helper loop that requires a valid reference (generated in Initialise) to operate it's pull method. The second type just waits for the data to appear in a buffer.

 

All the Digitisers have Initialise methods around menu population and creation of control/display for each channel (these are actors inserted into subpanels in the parent Digitiser Actor Core.

 

So, I use the child's Actor Core to create the helper loop for the specific class, but show the FP of the parental Digitser Actor Core to get the reuse/consistency of the control/display.

 

In my example, I have all four solutions implemented at the same time. This is probably a little confusing! If you hit run you will see that the Initialise method is called several times!

 

CLA - Kudos is how we show our appreciation for comments that helped us!
0 Kudos
Message 5 of 11
(316 Views)

@MaxJoseph wrote:

Hi,

 

Thanks for your breakdown Oliver, it sounds like you are recommending to launch the helper loop after I have performed the Initialise in the Child.

 


No, sorry. I'll recheck your use case. Need to go to a meeting

Will answer asap

Programming languages don't create bad code, programmers create bad code....
0 Kudos
Message 6 of 11
(314 Views)

Ok, I was thinking the other way round: initialization initiated by the helper loop...

 

If all you need is a helper loop, which can be activated while the Actors' MHL is processed, you might want to take a look at Jörgs' Blogpost. The basic idea is setting the Helper Loop to idle using timeout settings

 

Does this help?

 

Programming languages don't create bad code, programmers create bad code....
Message 7 of 11
(310 Views)
Solution
Accepted by topic author MaxJoseph
04-25-2019 12:03 AM

I'll fully admit to not *quite* following what you're doing based on your description as I tried to skim the thread, but I'll try. Let me see if I can summarize what you're doing:

 

-You have an abstract "Digitizer" class with concrete child classes ("Agilent", "HP", etc)

-Each child must be initialized in a unique way

-Each child has a unique helper loop that communicates with the instrument in unique ways

 

I think your best solution is to override Pre-Launch Init in the child class, then use Call Parent Method to make sure the parent's Pre-Launch Init fires as well. You could use Call Parent Method either before or after the child's Init fires, depending on how you're using the references. You can load the references to the Parent's FP items into the Parent's private data, then use accessors in the Child's PLI to get those references (if you need them).

 

I like having hardware Initialize functions happen in the Pre-Launch Init since it's blocking and will prevent the launch of the actor if a specified resource isn't available. That way your Actor can start up and know it has access to your hardware, and your "what do I do if the hardware isn't available" code can be handled in whatever is trying to launch the actor.

Message 8 of 11
(305 Views)
Solution
Accepted by topic author MaxJoseph
04-25-2019 12:03 AM

Hi Bert,

 

Thanks for taking the time to have a look, I probably didn't explain myself properly but you have summarised the system pretty well. I like the idea of using the Pre-Launch Init but I am unclear on how to add the Parent's Actor Core FP references to the private data prior to Pre-Launch Init being called.

 

The reason I need the reference available is that the Initialise launches a series of Control/Display actors that will be inserted into a subpanel on Parent's Actor Core. I want to give these Control/Display actors the subpanel reference when they are launched so they can insert themselves at will.

 

I suppose that I could modify the Control/Display actors to receive their subpanel reference after launch. This would mean that I could get away without needing the subpanel reference when they launch. Is this how most people work with Subpanel Actors? Thinking about it, I should just refactor my subpanel actor to avoid this problem. Thanks!

 


You can load the references to the Parent's FP items into the Parent's private data, then use accessors in the Child's PLI to get those references (if you need them).

Apologies, I do not understand what PLI means in this context.

CLA - Kudos is how we show our appreciation for comments that helped us!
0 Kudos
Message 9 of 11
(293 Views)
Solution
Accepted by topic author MaxJoseph
04-26-2019 12:13 AM

PLI= Pre Launch Init, I got tired of typing it out Smiley Happy

 

I now understand your issue, you can't get to the Actor Core references in PLI since Actor Core doesn't exist yet. Also, remember you can't launch new actors in PLI, since PLI is a non-reentrant function. Can you launch the display actors in the child's Actor Core?

 

Also, if you haven't, I'd highly suggest checking out MGI's Panel Actors. They help with a bunch of the "little stuff" dealing with subpanels and all, and if you ever decide to change your UI later on to be popups instead of subpanels (for example) they can change things quickly.

 

One other thing- you mention you could have the subpanels receive their subpanel reference after launch. This is a perfectly valid option, but I'll throw out a couple thoughts (some of which you know, but I'll include for future readers).

 

-Launch the actor after the subpanel reference is created (I think this is what you're doing), meaning launch the display actors once the core actor has launched and knows that the hardware resources are available. A benefit is that, if the basic hardware isn't available, don't try to launch the controller actors since there's nothing to control.

 

-Decouple the actual hardware control from the displays- basically, have your "hardware controller actor" be one thing, and the display actor be a child of that actor with a display on it. It sounds like more work, but abstracting the *display of* the data from the *generation of* the data can make things easier to debug and test. Changing the display now becomes trivial, in case you want to use a different style of indicator, or use a chart instead of a numeric, or if you want a more "full featured" control panel you can use in debug but you can swap out to the "simplified" view for the final UI.

 

-Going along with the above, MGI's Panel Actors do a good job of decoupling the "display logic" from the "UI logic" in that they handle inserting into subpanels, showing/hiding things, etc. It's not hard to implement an Actor as a Subpanel Actor, launch it, then send a message to stick it in a subpanel later on after it launches. This is beneficial in that you can have *multiple* actors running concurrently, then put different ones into subpanels depending on the user's selections. Say you have 3 tests running, each of which is their own actor; the user can pick which one to display via dropdown, and send each one a message to stick that specific one into the main display subpanel. Panel Actors helps greatly with this, and if later on the user says "But I want to view two at once!" you can change the main UI to send "Open in new window" instead of "Stick it in subpanel" and your underlying "business logic" doesn't change at all.

 

Good luck with your project. There are certainly lots of ways to skin this cat and I certainly don't claim to be an expert on this, just wanted to share some things I've had good luck with. Hopefully if I said something dumb I can invoke Cunningham's Law to get a real expert in here Smiley Happy

Message 10 of 11
(277 Views)