Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

XControl in Actor Core override Problem

I'm using two XControls in an Actor Core VI and everything was working fine until I tried to make an override for Actor Core in a subclass of the Actor. When I tried to create the override from the right-click menu in the project explorer, a message about resetting an XControl's Init.vi proxy was displayed and would not go away; I had to kill LabVIEW in the Windows task manager. I tried unlocking the XControls first, but that didn't work either.

I was able to create the override VI from the dynamic dispatch template and so far everything is fine. It's just the convenient "New->VI for Override..." that doesn't work.

I didn't use XControls in my first version of the Actor Core, but I didn't like the way the event handler was growing. Perhaps this trouble means I should reconsider.

0 Kudos
Message 1 of 12
(5,056 Views)

To get this right... the ancestor Actor Core.vi has a XControl on its FP and you want to override Actor Core.vi using the XControl as well?

Correct me if I'm wrong but I don't think this will work. FP for Actors are implemented at child level, since ancestor classes don't display their FPs.

Oli

0 Kudos
Message 2 of 12
(4,287 Views)

Once the actors are made, it works fine. It's just that making that override from the menu that doesn't work. I should have mentioned I'm still running LabVIEW 2014.

Every actor core can have an FP. Which one is displayed depends on how you do it. I have in this instance a number of fluorescence detectors for which I have almost identical FPs. Each has a list of ROIs, a display of a collected spectrum, and a couple of controls for calibration. They differ only in whether and how some factors like gain and shaping time can be set. The base class FP has all the common elements. The child class FPs take a little space for their special controls and use the rest for a subpanel which displays the base class FP.

Communication is by events and messages. (No poking around control refs.) Before invoking the parent class Actor Core, a This VI reference is added to an array in the my most basic class. This array grows as each parent adds it's own FP to the array. When my base class actor core is finally invoked, it generates a user event for which any one of its child classes can register. The event data is the array of FPs.

The actor which launches these and other detectors can request by message the array of FPs for each detector. It can then display the last child FP. In this way if there is a detector that needs no special controls, its Actor Core doesn't even need a front panel. (Except, of course, as every VI does.) This unspecial detector just does not add its FP to the array, and the launching actor will display the parent class FP.

I may later restrict which FP is available to the launching actor to be just the last child FP. For now I find it useful to be able to select which one is displayed. I can have, for example, one class which has a complicated FP for debugging, fine tuning, whatever I might need, and then a child class FP which gives only the controls my users might need.

0 Kudos
Message 3 of 12
(4,287 Views)

Every Actor Core VI has a frontpanel and you are right, IMHO you can force to show a frontpanel at every level of inheritance. By default, as Oli already has mentioned, you have the show front panel boolean parameter for the Start Actor VI and the inheritance acestors do not show their frontpanels.

This behaviour is default, since inheritance extends or changes the definition of something and does not create another instance of something.

It seems to me, that you rather want to create and launch subactor instances which register their front panel to their calling actor, that is the parent actor within the communication graph in terms of graph theory.

I would not do this either, since the FP reference of actor core is a very sensitive information you do not want to share with the calling actor. If its about starting and stopping front panels you should do this in the actor where the front panel lives by sending it a message. Instead of maintaining an array of vi refs, you should mantain an array of enqueuer. If you want to embed it in some sub panel of the calling actor, you can send the subpanel ref to the callee. This is the way I am solving this problem at the moment. You implicitly share the vi ref information since you can regain the vi ref from the subpanel ref. This breaks the law of information hiding. I do not feel comfortable with this, but it works at the moment for me.

I prefer to put the frontpanel with the event loop in a dedicated vi which is called by actor core by reference.

If an actor runs mad and you are not able to stop, it can have several reasons. Usually some loop is not finished and usually it is a (the!!) event loop. First you should find out which loop is still running and why the stop event was not thrown. It should be thrown before the main wire of actor core finishes.

0 Kudos
Message 4 of 12
(4,287 Views)

The "Feedback Evaporative Cooler" demo features passing Actor Core VI references to another actor for swappable user interfaces.

The array of VI refs is to the actor cores in the class hierarchy of a single actor; there's only one enqueuer.

0 Kudos
Message 5 of 12
(4,287 Views)

The main thing here is that there seems to be a bug in LabVIEW 2014's "New->VI for Override..." implementation which causes LabVIEW to hang. The end result of having a Actor Core override the parent class's Actor Core when the parent class's FP has an XControl can be achieved by other means.

0 Kudos
Message 6 of 12
(4,287 Views)

I am also using Labview 2014 but I never looked at the examples. What I wrote about passing Vi Refs was a personal recommendation. Information hiding is one of the principles of object oriented programming. You can break every law if you want. Just make sure that you know what you are doing. I also did a lot of nasty things in my programming carreer, so I will not judge you.

As far as I understood, you are building a class hierarchy of actors, each one inheriting from its parent and each one has an override for actor core. You want to use the actor core front panel as user interface and in order to do so,in each actor core you have a event loop which is running in parallel to the actor of the parent class actor core method.

I am sorry if I am misunderstanding you, but this would be an reallly extreme example of an anti pattern:

Swapping user interfaces is a symmetric problem und you are trying to solve with a hierachical approach.

If you call one actor core, you start the event loops in all parent actor cores even if you do not show the front panel. The event loops from vis with front panels which are not shown do not react on button press events. You have to stop them with a user event. They are running although they are not needed.

My recommendation to use separate actors (which can have a common parent, that controls showing or hiding the FP) is for the case you want to modularize the UI. I like this because it keeps things small and easy to find, so it makes sense to use it for a single frontpanel. Another approach is to define several methods with different actors in you actor class. In your actor core, you start the FP you want by calling the method by reference. You even can embed it into a subpanel.

Usually I do not like automatic code generation, but "New -> VI for Override" works fine for me and I am using it all the time.

Since you have a bigger hierarchy do you have some VI which is not a Dynamic Dispatch VI but has a method with the same name in the child class? 

0 Kudos
Message 7 of 12
(4,287 Views)

In this case, swapping interfaces is a bonus of the actor framework. Before December, when I started converting to the AF, these were regular classes with a static UI in the main program. The UI was static because we needed the code running and I hadn't had time to do more. (I'm the only programmer and only lately is it my primary duty.) Changing which classes were used required editing a serialized array of objects, because I hadn't even had time to handle dynamic loading. While I could load any class, the UI didn't necessarily match. The interface to the particular instruments is not the primary purpose of the program. The primary purpose of the program is X-ray absorption spectroscopy: I repeatedly change the energy of an beam of photons and collect data from all the instruments at each energy.

The more I can automate calibration, tuning, and other settings of instruments, the less I'll need user interfaces to any of them. Until then, I have (in addition to the main program, and handled by Actor Core FPs): two UIs that rarely change because the hardware rarely changes; a 3rd UI for a class of detectors which may be changed or not even used; and additional UIs for cryostats, furnaces, GCMSs, and other instruments which we've never been able to integrate into the main program before.

Swapping interfaces in an actor's class hierarchy is a convenience for me while I'm working on this. If the mostly idle event loops of the ancestors are a problem during data collection, I can always disable them during normal operation

Before switching to AF, I was going to use a special VI for each class to provide a UI as needed. Because the event loop of a subpanel VI did nothing when the top-level VI had an event loop, I was looking at having to poll it, among other issues.

I'm looking at maybe four levels of class hierarchy beyond the Actor class. I have my base Instrument class which does most of the communication with the main program. At the moment I have two general sublasses of that: Monochromator (Mono) and Fluorescence Detector (FD). I also have one subclass of Instrument that is actually a hardware interface. Mono and FD have each a few subclasses that are hardware interfaces. That's it for now, just 3 levels. I can imagine I might have another level, but I'd be very surprised to need more than that.

Maybe at some point I'll need something more elaborate like the Measurement Utility, but for now this suffices. When I'm "done", I hope to have made something that allows my users create functioning Instruments with very little effort. Creating a new FD subclass right now would only require overriding three methods. That would suffice to set ROIs and acquire data. No Actor Core override would be needed because the FD class Actor Core FP provides a UI to set the ROIs. Simpler instruments can be implemented with just two method overrides. I think when I'm done the most complex instruments will need maybe 8 overrides, including Actor Core, for complete integration into the main program. They'll still need whatever methods and internal messages they need, but the main program doesn't deal with that.

"New->VI for Override..." works here too, except when there's an XControl on the FP.

I do not have any static methods duplicating parent class methods.

I feel like this reply should have been a blog post. I'll have a write-up in the future, but there's still a lot to do now.

0 Kudos
Message 8 of 12
(4,287 Views)

I see. I wish you good luck. Your approach seems uncoventional to me.

 

I would prefer to create instrument classes by the factory method introduced by E. Kerry. 

 

I seem to have a different understanding of object oriented programming.

0 Kudos
Message 9 of 12
(4,287 Views)

That document basically describes what you had to do with LabVIEW before the Actor Framework was released.

You really should look at the provided demo and the measurement utility.

0 Kudos
Message 10 of 12
(4,287 Views)