Search code examples
actionscript-3eventsaddeventlistenerdispatch

AS3 - Event listener that only fires once


I'm looking for a way to add an EventListener which will automatically removes itself after the first time it fires, but I can't figure a way of doing this the way I want to.

I found this function (here) :

public class EventUtil
{
    public static function addOnceEventListener(dispatcher:IEventDispatcher,eventType:String,listener:Function):void
    {
         var f:Function = function(e:Event):void
         {
              dispatcher.removeEventListener(eventType,f);
              listener(e);
          }
          dispatcher.addEventListener(eventType,f);
    }
}


But instead of having to write :

EventUtil.addOnceEventListener( dispatcher, eventType, listener );

I would like to use it the usual way :

dispatcher.addOnceEventListener( eventType, listener );


Has anybody got an idea of how this could be done?
Any help would be greatly apprecitated.


(I know that Robert Penner's Signals can do this, but I can't use them since it would mean a lot of code rewriting that I can't afford for my current project)


Solution

  • I find the cleanest way without using statics or messing up your code with noise is to defining a global function (in a file called removeListenerWhenFired.as) like so:

    package your.package
    {
        import flash.events.Event;
        import flash.events.IEventDispatcher;
    
        public function removeListenerWhenFired(callback:Function, useCapture:Boolean = false):Function
        {
            return function (event:Event):void
            {
                var eventDispatcher:IEventDispatcher = IEventDispatcher(event.target)
                eventDispatcher.removeEventListener(event.type, arguments.callee, useCapture)
                callback(event)
            }
        }
    }
    

    Then you can listen for events like so:

    import your.package.removeListenerWhenFired
    
    // ... class definition
    
        sprite.addEventListener(MouseEvent.CLICKED, 
            removeListenerWhenFired(
                function (event:MouseEvent):void {
                    ... do something
                }
            )
        )