PureMVC Architects Lounge

Announcements and General Discussion => General Discussion => Topic started by: eliatlas on January 10, 2012, 04:08:44



Title: One notification - multiple actors handling it
Post by: eliatlas on January 10, 2012, 04:08:44
Hi Forum

I have a bunch of notifications, that a lot of actors are registered to.
Think of a control button which fires a notification which has more than 5 different listeners.

My question is, should I make a command that will handle the notification and operate all the actors, or should I handle this notification in each place separately?


Thanks


Title: Re: One notification - multiple actors handling it
Post by: puremvc on January 10, 2012, 08:17:28
Avoid retrieving a Mediator from a Command and operating on it. Notifications decouple the actors, this is good. Let the Mediators receive and act on the notes themselves.

-=Cliff>


Title: Re: One notification - multiple actors handling it
Post by: eliatlas on January 12, 2012, 03:57:38
Thanks Cliff

That makes me wonder though:
Avoid retrieving a Mediator from a Command and operating on it.

Shouldn't commands handle the business logic of the application? Sometimes mediators hold the information that command needs.
For example, let's say we have two buttons in our veiw - 'start' and 'start_and_jump'.
Both of them are firing the same notification ANIMATE_BEFORE_START, which will start an animation in different view component.
After the animation ends I will fire "START_GAME" which will invoke "START_COMMAND".
In the "START_COMMAND" I would like to be able to know whether I should jump or not after I start, so my solution is to ask the initial mediator about what happened.
Naturally the perfect solution was to have 2 different notifications, or to pass an additional parameter with the notification, but sadly I can't do it in this case, since the actions are asynchronous.



Title: Re: One notification - multiple actors handling it
Post by: puremvc on January 12, 2012, 08:30:21
Well, in your scenario, either

1) The initial mediator either needs to keep state (which button was initially pressed) - not good: outside the mediator's clearly defined responsibilities.
or
2) The view component needs to hang onto the information about which button was pressed (and possibly clear it after you've checked it again - kind of a hassle.

Instead, consider using a transient Proxy.

You've got some info you need to hang onto for an indeterminate amount of time while you do some other, asynchronous stuff. In your simple scenario you may 'know' where the original event / notification came from, but in other such situations you may not. The transient Proxy allows you to decouple the source of the event / notification from the processing of it later.

It goes something like this:

Inside your Mediator:
:
private function handleStartAndJumpEvent(event:Event):void
{
    facade.registerProxy( new Proxy( AppConstants.START_ACTION, AppConstants.START_AND_JUMP ) );
    sendNotification(AppConstants.ANIMATE_BEFORE_START);
}

private function handleStartEvent(event:Event):void
{
    facade.registerProxy( new Proxy( AppConstants.START_ACTION, AppConstants.START ) );
    sendNotification(AppConstants.ANIMATE_BEFORE_START);
}

Later in your StartCommand, which needs to know how you started, simply retrieve the transient Proxy:
:
var startHow:String = facade.retrieveProxy(AppConstants.START_ACTION).getData() as String;
QED.
-=Cliff>


Title: Re: One notification - multiple actors handling it
Post by: eliatlas on January 15, 2012, 02:22:45
This is great concept Cliff. I found it in the book too.
In this case, should I unregister the proxy after I use it?

The thing is that this process is naturally happening a lot, so I will have to initiate it a lot of times.
So shouldn't I instead have an instance of this proxy all the time, and just change the data when needed?

For example, continuing the example you gave:
:
var startHow:String = facade.retrieveProxy(AppConstants.START_ACTION).getData() as String;
handleStartAction();
facade.registerProxy(new Proxy(AppConstants.START_ACTION, AppConstants.IDLE) );
This way I will be able to know what is the status of the game all the time.


Title: Re: One notification - multiple actors handling it
Post by: puremvc on January 15, 2012, 10:00:13
So shouldn't I instead have an instance of this proxy all the time, and just change the data when needed?
Yes, you probably want to reuse the already registered proxy if it is there...

In your Command
:
var startProxy:Proxy;
if ( facade.hasProxy(AppConstants.START_ACTION) ) {
    // use the currently stored start action stored
    startProxy = facade.retrieveProxy( AppConstants.START_ACTION );
} else {
    // no stored action, so store and use default,
    startProxy = new Proxy( AppConstants.START_ACTION, AppConstants.START  );
    facade.registerProxy( startProxy );
}

// do something with the data
handleStartAction( startProxy.getData() as String );

 // change the stored data
startProxy.setData( AppConstants.IDLE );

This way I will be able to know what is the status of the game all the time.

Yes, you can keep state in your game by storing/querying data like this in transient Proxy, and you are also treading close to the territory of the PureMVC StateMachine utility. It acts in a different manner but allows you to break your app into discrete states, with defined actions that allow transitions to other states. A key difference between the transient Proxy approach and the StateMachine approach is that you don't retrieve the current state from the StateMachine, you send action notes to it and it sends out notes that tell the system when the state is about to change, or has changed. A running status as opposed to a stored status. The two approaches can be used together, however.

PureMVC AS3/Flex StateMachine Utility
http://trac.puremvc.org/Utility_AS3_StateMachine

StateMachine Utility Overview Presentation
http://puremvc.tv/#P003/