Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Can I write a generic message class using VIM or VIM-like qualities?

I'm currently (re-)writing my Settings/Configuration component for my AF-based project.

 

I've now written a parent "Settings Node.lvclass" which can be sent via message to a "Configuration.lvclass" which basically just embeds chosen nodes in a subpanel and allows changes to be made via the subpanel.

 

The parent "Settings Node" handles events for displaying, registration, unregistration, and sending an "Apply" event which is registered for by the parent, but should be handled by Child "XYZ Module Settings Node.lvclass" classes.

Spoiler
Side note - perhaps this is a bad design - should I register for events in a parent class and pass the registration reference only (via protected accessor) or is this a silly idea?

The "problem" occurs in my child classes. These each have to define an Actor Core (or similar) to embed in the subpanel (this is fine), they have a typedef'd control for the settings to be changed, which is stored in private data (for comparison when applying) and an "Update Setting Data.vi" which carries out the comparison, then sends a message to the "XYZ Module.lvclass".

 

The module receives the message, fires a user event to itself, then in its own Actor Core handles the event with the new data to apply. The comes out as an Enum for "Setting Type" and a variant (the Update Setting Data.vi takes care of unbundling the appropriate value and then using To Variant to be able to send it). (Additional side note - I don't really like variants but this seemed my best option here. Suggestions from those with more experience/imagination appreciated!)

 

The result is I have a collection of similar VIs in the module classes, and fairly similar VIs in the Settings Node child classes, and I'd like to move some of this into the parent class, rather than having 2 messages and a few VIs that are largely the same each time.

 

Since the different children have different settings, I can't seem to define a message that carries the clustered data from the parent. Any thoughts?

 

Some block diagram pictures.

SimDat ActCore.PNG

Simulated Data's Actor Core. An event is created an handled here - this is generated by a class member VI, called by message, from the Settings Node VI which is called by the other message defined for each module.

 

SimDat SettingsNode UpdateSettingData.PNG

The Settings Node child's "Update Settings Data.vi". Here, the settings are compared (the simple Not Equals with a boolean array output is sufficient here - other modules have a VI to compare if the settings are more complicated) and then a For loop using the Number to Enum VIM and the type typedef output an unbundled element (one case per setting) as a variant (to get it out of the case structure despite type differences) then sends the "Generate Update Event" message, which triggers the modules Update Event (seen in the first picture).

 

SimDat SettingsNode ActCore.PNG

The Actor Core for the child Settings Node. Here, the Settings control can be changed via the Configuration subpanel. When the parent sends the Apply/Discard event, the child handles the event and sends itself a message, which calls the VI in the second picture. The false case uses the strict cluster reference to set the values back to those held in private data. The other event handled is a Stop event. The Actor Core here doesn't need anything else, and the two VIs at the top register the front panel for the subpanel, and read the parent's event registration.


GCentral
0 Kudos
Message 1 of 4
(2,795 Views)

Naturally as soon as you post you realise something important...

 

Changing the inputs to "Update Setting Data.vi" from a typedef'd cluster and reference to a more generic Cluster reference and a Variant allows me to make this VI dynamic dispatch and move the message to the parent, reducing the amount of work needed to add a new module by a decent chunk.

 

Variant to Data is easily achieved using the private data of the child class.

updatedVersion.PNG


GCentral
0 Kudos
Message 2 of 4
(2,777 Views)

And going a step further with a coercion dot at the generation of a User Event directly using the primitive, rather than messaging the module class (which was bad, since it forced users to be Actors) allows movement of the Create User Event into the parent Settings Node class, outputting a registration reference to the module to check for applied settings during registration (of the node).

 

The User Event now has data type {I16, Variant} and requires an additional use of Number to Enum.vim in the calling/using module, but this removes any need to create child messages, or add VIs to the calling module (now, it just has to handle the "Update Event" given by registration reference. (Updated version below, compare with first image)

SimDat ActCore Updated.PNG

 

Although I'd still prefer a solution with fewer Variants, I think this might be the best I'm going to manage with this idea.

 


GCentral
0 Kudos
Message 3 of 4
(2,771 Views)

@cbutcher wrote:

 

Although I'd still prefer a solution with fewer Variants, I think this might be the best I'm going to manage with this idea.


I’d suggest you consider MORE Variants.   Looking at your "Update Settings Data.vi”, one could easily write code that compares arbitrary Clusters in Variants and generates messages containing the names and values of changes cluster elements.  You could ditch the settings-identifying enum, also, and just use cluster-element names.

Message 4 of 4
(2,762 Views)