Stray / robotlegs-utilities-RelaxedEventMap

Just what it says - a robotlegs eventMap that lets you be a little more relaxed about race conditions and late-arriving views
17 stars 2 forks source link

Some more clarification on the dummyHandler stuff #1

Closed rickcr closed 13 years ago

rickcr commented 13 years ago

Stray, can you provide a bit more clarification about this part in the docs. I'm a bit confused what's going on and what's necessary. What does that even mean "handler for any events that aren't being listened to on the relaxedEventMap elsewhere." Thanks.

(from docs):

It is also necessary to add a dummy handler for any events that aren't being listened to on the relaxedEventMap elsewhere. You can do this in your context startup, or in a dedicated bootstrap Command.

// using a dedicated method that creates an empty listener and cleans it up for you relaxedEventMap.rememberEvent(SomeDataEvent.DATA_SET_UPDATED, SomeDataEvent);

// or manually - for example so you can trace or log the event in the function passed here relaxedEventMap.mapRelaxedListener(SomeDataEvent.DATA_SET_UPDATED, function():void{}, SomeDataEvent);

Stray commented 13 years ago

Hi there, basically the event has to have passed through the map in order to be available. If you have a parentView which is always on the stage, and this happens to already listen for this particular event on the relaxedEventMap then it'll be picked up when it fires there.

But if you don't have another 'real' listener elsewhere, then you have to ask the relaxedEventMap to pick up that particular event as it happens. Obviously it won't pick up every single event because that would be nuts. (Remember that your onRegister where you listen for this even later may not run until after the event has fired - so this is a heads up to the relaxedEventMap that you're going to ask for this event type later).

So - use

relaxedEventMap.rememberEvent(SomeEvent.SOMETHING, SomeEvent) to make sure that the relaxedEventMap keeps track of that event.

If you need to do some debugging, you can add it manually with a function that just traces or logs the event. (Like the second example).

Let me know if that still doesn't make sense.

rickcr commented 13 years ago

Ok thanks Stray.. I think I have it working correctly in my code. Cool stuff.

I think this small modification in the docs might make it a bit more clear for newbies ...

After the "In your context:" section I'd actually mention the 3rd section before the 2nd.

So section two starts ... "Where you want to ensure the mediator receives the event,"

Now, in the 3rd section possibly reword it to:

"In order for the "rememberEvent" functionality that you just implemented to work, you need to also be sure a dummy listener, (for the same event you used in rememberEvent,) is added to the relaxedEventMap . You can do this in your context startup, or in a dedicated bootstrap Command."

//Let the relaxedEventMap create the dummy listener for you relaxedEventMap.rememberEvent(SomeDataEvent.DATA_SET_UPDATED, SomeDataEvent);

or

//manually provide the listener...for example so you can trace or log the event in the function relaxedEventMap.mapRelaxedListener(SomeDataEvent.DATA_SET_UPDATED, function():void{}, SomeDataEvent);

Maybe not a big deal, switching the order around.

This part is still a bit confusing... "for any events that aren't being listened to on the relaxedEventMap elsewhere. " Do you mean there are cases where you do NOT need to register the dummy listener? It sounds like you're saying if you registered that event with the relaxedEventMap in an onRegister that you "KNOW" fires on time than you are ok? But in that case why would you need to even use the relaxedEventMap for that event in the first place?

Stray commented 13 years ago

You're right - it is confusing!

You don't need to register the dummy listener if you have a mediator on the stage that is always there and listens to that event from the start. For example - a mediator for your main view. If that also listens for the event on the relaxedEventMap then it'll be picked up because it has been told to listen for it there.

An example: a screen view contains a login panel. When the user has logged in, the parent view receives the UserLoginEvent.LOGIN_COMPLETED event - and this event carries the vo for the logged in user details. The parent view handler for this event removes the login panel and attaches a different view. Elsewhere, there's a button that produces a popup view (not inside the parent view) that needs to display the user's name if they are logged in.

Because there is a view that is already registering for the UserLoginEvent.LOGIN_COMPLETED event, if you use the relaxedEventMap instead of the eventMap for this listener, the last loginCompleted event will already be available for the mediator of the view that just arrived on stage to pick up.

You've made me realise though that it's probably clearer, in terms of intent, to always register a dummy listener to show that this event is being tracked, rather than rely on a persistent (and early) listener being added elsewhere.

rickcr commented 13 years ago

I see.

Yea I think it's not only clearer, in terms of intent, to always register the dummy listener, but it's also cleaner in regard to loose coupling. Without having the coupling just tied to the Context class, you could end up coupling components to other components due to the registration of events to the relaxedEventMap...

What if later on someone removes the component that is always listening for the event (eg in the MainView mediator above?) Well, now it seems like your other components will break since you didn't register a dummy listener and you removed the original component that forced it being listened to.

Not too big a deal, but I think as a best practice, it would seem that always registering the dummy listener would be a good idea.

I hope this map sees it introduced into RL core because it's extremely useful. Excellent work.

Stray commented 13 years ago

You're right about the coupling. Things that work because of coincidence and then stop working later are the hardest to debug as well. So - we'll keep it our little secret that the registering isn't always necessary!

Oh - and thanks for the compliment!

You should update to the version I uploaded yesterday btw - because of this discussion, I realised that the dummy listener was being removed after the first pick up, which is wrong because you may have future firings that the mediator isn't around for but still wants to receive when the view hits the stage. Now it persists but is never fired, so the event always gets collected.

rickcr commented 13 years ago

Just pulled the latest. Thanks. By the way, I thought if I'm set to 'watch,' that I'd be notified of updates to the code base in github?