tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/395-mediator-removal-issueRobotlegs: Discussion 2018-10-18T16:35:33Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T10:42:05Z2011-10-12T10:42:05Zmediator removal issue<div><p>Hi James,</p>
<p>that is an interesting problem - and one that's so obvious that
I'm<br>
surprised no-one else seems to have stumbled over it before
(including<br>
myself).</p>
<p>The reason for mediators not being removed immediately is that
we<br>
can't detect whether a display object is really removed from stage
or<br>
only re-parented to another part of the display list. To work
around<br>
that, we store the mediators for removed views in a list and
only<br>
really remove them in the next frame. If they are only
reparented,<br>
they get removed from that list immediately.</p>
<p>I think the best way to work around this would be to set some
sort of<br>
flag on the mediator, but that's not too small a change, so
we'll<br>
probably not do it for Robotlegs 1, because version 2 should be out
in<br>
a couple of months. Therefore, I'd suggest you use the workaround
you<br>
described.</p>
<p>hope that helps,<br>
till</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T10:54:21Z2011-10-12T10:54:22Zmediator removal issue<div><p>Hi Till,</p>
<p>thanks a lot for the quick reply.</p>
<p>I've been using RL for over 18 months now and thought exactly
the same thing when i came across the problem. It's what made me
wonder whether it was something i was doing wrong, as i was
surprised i've not come across it before.</p>
<p>I had a poke around in the source and noticed that they're being
removed once an ENTER_FRAME is run. Now that you've explained why,
that makes complete sense.</p>
<p>The flag sounds like a good idea, as it could just be set when
the view and Mediator are mapped if you know the view won't be
re-parented.</p>
<p>Thanks again,</p>
<p>James</p></div>jamestag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T11:03:38Z2011-10-12T11:03:38Zmediator removal issue<div><p>I've created a ticket in the robotlegs github project so that we
don't<br>
forget about the issue. Thanks for bringing it to attention.</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T11:09:41Z2011-10-12T11:09:42Zmediator removal issue<div><p>Nice one, thanks Till. Glad i could be of help, RL really is a
pleasure to work with!</p>
<p>This is probably pretty obvious, but i'll post it here just
incase anyone else comes across this issue. So much for my rant
about extra code...</p>
<p>I've just stuck this line of code in the onRegister method of
the offending Mediator,</p>
<p><code>eventMap.mapListener( view, Event.REMOVED_FROM_STAGE,
viewRemovedHandler, Event );</code></p>
<p>Then i simply clear the _eventMap in the handler,</p>
<p><code>private function viewRemovedHandler( event:Event
):void<br>
{</code></p>
<pre>
<code> _eventMap.unmapListeners();</code>
</pre>
<p>}</p></div>jamestag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T11:11:39Z2011-10-12T11:11:39Zmediator removal issue<div><p>Hi James,</p>
<p>Another quick fix for that specific mediator would be to add a
guard clause in your handlers that checks that the view.parent !=
null.</p>
<p>eg:</p>
<pre>
<code>protected function someHandler(e:Event):void
{
if(viewHasLeftTheStage)
{
return;
}
... carry on and do stuff
}
protected function get viewHasLeftTheStage():Boolean
{
return (view.parent == null);
}</code>
</pre>
<p>Or - you could create a version of the event map to put this
clause around your handlers automatically. I'd probably go that
route as it's most composition friendly...</p>
<p>To implement that, you'd override your eventMap setter in the
mediator:</p>
<pre>
<code> override protected function get eventMap():IEventMap
{
return _eventMap || (_eventMap = new ViewOnStageDependentEventMap(eventDispatcher, viewComponent));
}</code>
</pre>
<p>viewComponent is what the mediator generically uses to refer to
your view internally (as a DisplayObject).</p>
<p>Then, you'd just add this check to your special event map (which
has stored the viewComponent property that you passed it) - by
overriding 'routeEventToListener':</p>
<pre>
<code>protected function routeEventToListener(event:Event, listener:Function, originalEventClass:Class):void
{
if (event is originalEventClass && viewComponent.parent)
{
listener(event);
}
}</code>
</pre>
<p>That <em>should</em> be all that is required... if it's a bit
befuddling let me know and I can whip it up into a utility on
github (with tests) today.</p>
<p>Nice find - we like these corner cases (especially, as Till
pointed out, during the pre-release phase for RL2!)</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T11:12:54Z2011-10-12T11:12:54Zmediator removal issue<div><p>Ah... and what you have will work as well!</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T11:27:15Z2011-10-12T11:27:15Zmediator removal issue<div><p>Thanks Stray, that makes sense and a least i don't have to keep
implementing the same logic throughout my offending Mediators.</p>
<p>So just to clarify, i subclass Mediator and override the
eventMap accessor and then subclass EventMap and override the
routeEventToListener method?</p>
<p>James</p></div>jamestag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T11:54:47Z2011-10-12T11:54:47Zmediator removal issue<div><p>One last thing, where would be the best place in the EventMap
subclass to clean up the reference to the viewComponent? Override
unmapListeners() ?</p>
<p>James</p></div>jamestag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T12:29:36Z2011-10-12T12:29:36Zmediator removal issue<div><p>Exactly :)</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T12:30:57Z2011-10-12T12:30:57Zmediator removal issue<div><p>Hi James, that shouldn't be necessary - as the eventMap is only
a property of the mediator, and the mediator will be GC'd, you
should be fine without explicit clean up.</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/105536422011-10-12T12:36:22Z2011-10-12T12:36:23Zmediator removal issue<div><p>Cheers Stray, that's all now up and running. Thanks again for
your help.</p>
<p>James</p></div>james