Can you please save the project for 2017?
Good point, I have updated the first post with the 2017 version!
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....
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!
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
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?
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.
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.
PLI= Pre Launch Init, I got tired of typing it out
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