Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Passive UI (Model View Presenter)

Solved!
Go to solution

Hi,

This is a follow on from a previous thread that I started: http://forums.ni.com/t5/LabVIEW/Model-View-Presenter-Passive-View-pattern/td-p/2408016

I have started to learn about the Actor Framework after porting the framework and the message maker tool to LV2009, but have come unstuck with reading data back from a child actor (wrong term, but can't think of the correct one; callee?).

I want the UI to only be updated by the presenter/controller (i.e. not the Model View Controller pattern).

Scenario:

A Presenter actor is launched which then launches the View actor (I am doing it this way round so the View can be swapped at runtime).

Within the View's 'Pre Launch Init.vi' several events are created, one set for internal use by the UI which are triggered by messages that the Presenter knows about (such as 'change status text') and the other set to be registered by the Presenter (such as 'UI button pressed').

Once the View actor has been launched I can successfully update the View's state via the Presenter, but don't know how to get the event refnums intended for the Presenter out of the View (e.g. the 'UI button pressed' event ref). I want to get these event refnums just after the View has been launched in order to register them in the Presenter.

What is the best way to do this? I have looked at sending messages upstream from the View to the Presenter, but I don't understand how to implement it (and I'm assuming it would be asynchronous).

Or do I need to approach this differently. The main/end goal is to be able to re-use the UI with another Presenter and have the option of inseting this into another View's subpanel.

Thanks

Matt

0 Kudos
Message 1 of 7
(6,413 Views)

> a child actor (wrong term, but can't think of the correct one; callee?).

We use the terms "caller actor" and "nested actor". If the caller is not an actor, then just "caller".

In general, I strongly advise against using any communication between actors other than the Enqueuer for that actor. Very strongly. That means my first answer to "how do I get these event refnums to this other actor" is "Don't do this." When those events fire, send a message to the caller actor that is the contents of those events and let the caller actor handle those messages. Trying to introduce a second communications channel generally introduces timing problems involving the stability of the receiving actor and problems of sporadic errors during shutdown caused by ill-defined shutdown sequences.

If you decide to do this anyway, my next advice is to have the actor that will be the handler of the events be the one that creates the refnums and then give them to the actor that will generate the events. That way the refnums have the same lifetime as the reciever, following the same reasoning as with the Message Queues for the actor framework itself. In your case, this means that the presenter would create the refnums and give them to the view (either by setting them into the view before the view is launched or by sending a message to the view). Also, it is the presenter that is the right one to be defining the interface that all the views, no matter which one gets launched, should use.

If you decide that you still have to have the event refnums created by the view, then just package them into a message and send them to the presenter. You will need to have state in the presenter that says, "I do not yet have my event refnums" and it will handle any messages that arrive in the meantime appropriately (perhaps by ignoring them, perhaps by batching them up, perhaps other things...). Note that this timing hole does not exist if you follow either of my two previous recommendations.

Message 2 of 7
(3,711 Views)

Many thanks for your in-depth reply AristosQueue.

I am keen to go with the first option you suggested; it makes sense to keep a single comuniaction channel.

Do you have any examples or documentation on creating very low coupled messages from the nested caller to the caller actor. I don't understand how to implement it. (Does the 'Asynchronous Messaging explained as a coffee shop' use this?)

Also, if I implemented the above using events, the presenter would know what events it needs to handle/support (from the register for events terminal). However, if I use messages how can I make sure that I don't miss any of the required messages. Would I need to create a 'view handler' class that defines 'must override' requirements and then have the presenter inherit from this and override the message's 'Do' implementation? I need to keep the view knowing as little as possible about the presenter.

Thanks

0 Kudos
Message 3 of 7
(3,711 Views)
Solution
Accepted by topic author mattb-5906

Take a look at the white paper where it talks about "zero coupling" and "low coupling" solutions. There are various implementations of these around, including I think one in the coffee shop and I know in the evaporative cooler.

0 Kudos
Message 4 of 7
(3,711 Views)

The coffee shop uses a zero-coupled self-addressed callback message to let a customer know their order is ready. 

Cheers,

Matt Pollock
National Instruments
0 Kudos
Message 5 of 7
(3,711 Views)

Thanks both. I will have another look at these.

0 Kudos
Message 6 of 7
(3,711 Views)

I spent ages trying to figure out how to implement this looking at the evaporative cooler example, only to find I have been looking at the wrong one (The NIWeek 2012 Hands-On Session solution folder). Looked at the sample project in LV2012 and It all makes sense now. *Facepalm*

Resolved

0 Kudos
Message 7 of 7
(3,711 Views)