diff --git a/bin/RelaxedEventMapRunner.swf b/bin/RelaxedEventMapRunner.swf index b6a352e..9d6cd3c 100644 Binary files a/bin/RelaxedEventMapRunner.swf and b/bin/RelaxedEventMapRunner.swf differ diff --git a/src/org/robotlegs/base/RelaxedEventMap.as b/src/org/robotlegs/base/RelaxedEventMap.as index 6da541e..c2f3814 100644 --- a/src/org/robotlegs/base/RelaxedEventMap.as +++ b/src/org/robotlegs/base/RelaxedEventMap.as @@ -10,10 +10,12 @@ package org.robotlegs.base { public class RelaxedEventMap extends EventMap implements IRelaxedEventMap { protected var eventsReceivedByClass:Dictionary; + protected var emptyListeners:Array; public function RelaxedEventMap(eventDispatcher:IEventDispatcher) { super(eventDispatcher); eventsReceivedByClass = new Dictionary(); + emptyListeners = []; } public function mapRelaxedListener(type:String, listener:Function, eventClass:Class = null, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = true):void @@ -29,6 +31,13 @@ package org.robotlegs.base { mapListener(this.eventDispatcher, type, listener, eventClass, useCapture, priority, useWeakReference); } + + public function rememberEvent(type:String, eventClass:Class = null):void + { + var emptyListener:Function = function():void { }; + emptyListeners.push(emptyListener); + mapListener(this.eventDispatcher, type, emptyListener, eventClass); + } override protected function routeEventToListener(event:Event, listener:Function, originalEventClass:Class):void { @@ -36,7 +45,16 @@ package org.robotlegs.base { { eventsReceivedByClass[originalEventClass] ||= new Dictionary(); eventsReceivedByClass[originalEventClass][event.type] = event; - listener(event); + + if(emptyListeners.indexOf(listener) == -1) + { + listener(event); + } + else + { + unmapListener(this.eventDispatcher, event.type, listener, originalEventClass); + emptyListeners.splice(emptyListeners.indexOf(listener), 1); + } } } diff --git a/src/org/robotlegs/core/IRelaxedEventMap.as b/src/org/robotlegs/core/IRelaxedEventMap.as index eb7db24..9003a30 100644 --- a/src/org/robotlegs/core/IRelaxedEventMap.as +++ b/src/org/robotlegs/core/IRelaxedEventMap.as @@ -5,6 +5,8 @@ import flash.events.IEventDispatcher; public interface IRelaxedEventMap { function mapRelaxedListener(type:String, listener:Function, eventClass:Class = null, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = true):void; + + function rememberEvent(type:String, eventClass:Class = null):void; } } \ No newline at end of file diff --git a/test/org/robotlegs/base/RelaxedEventMapTest.as b/test/org/robotlegs/base/RelaxedEventMapTest.as index 9f3755b..063c528 100644 --- a/test/org/robotlegs/base/RelaxedEventMapTest.as +++ b/test/org/robotlegs/base/RelaxedEventMapTest.as @@ -56,6 +56,23 @@ package org.robotlegs.base { eventDispatcher.dispatchEvent(new SampleEventA(SampleEventA.SOMETHING_HAPPENED)); } + public function test_rememberEvent_stores_the_event():void { + instance.rememberEvent(SampleEventA.SOMETHING_HAPPENED, SampleEventA); + eventDispatcher.dispatchEvent(new SampleEventA(SampleEventA.SOMETHING_HAPPENED)); + var handler:Function = addAsync(check_past_event_fired_when_listener_added, 100); + instance.mapRelaxedListener(SampleEventA.SOMETHING_HAPPENED, handler, SampleEventA); + } + + public function test_rememberEvent_listener_is_cleaned_up():void { + instance.rememberEvent(SampleEventA.SOMETHING_HAPPENED, SampleEventA); + eventDispatcher.dispatchEvent(new SampleEventA(SampleEventA.SOMETHING_HAPPENED)); + eventDispatcher.dispatchEvent(new SampleEventA(SampleEventA.SOMETHING_HAPPENED)); + // unfortunately because the listener is by design empty, I can't find a way to test this automatically + // so it's a trace based confirmation + assertTrue("Manually verified that when a trace is placed in the null function used it doesn't trace", true); + } + + private function somethingHappenedHandler(e:SampleEventA):void { // nada