[AS3] Dispatch Events with Values

I wanted to be able to pass arguments along with my events, that would propogate through to the listeners, so I came up with this EventManager class:

[AS]
package net.duncanhall.events
{

/**
 * @author Duncan Hall
 */

import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.utils.Dictionary;     

public class EventManager

{
    private static var targetMap:Dictionary = new Dictionary();

    /** PUBLIC METHODS ************************************************************************/
    /**
     * Adds an event listener of the specified type, to the object given, and
     * allows for an undefined number of arguments to be passed to the listener
     * 
     * @param target    The object to listen to
     * @param type        The type of event to listen for
     * @param listener    The function to call when the event is dispatched
     * @param args        [Optional] list of arguments to pass to listener
     */
    public static function addEvent ( 
        target:IEventDispatcher, type:String, listener:Function, ...args ) : void
    {
        var targetEventMap:Dictionary;
            targetEventMap = targetMap[target] == undefined ? new Dictionary : targetMap[target];
            targetEventMap[type] = { listener:listener, args:args };

        targetMap[target] = targetEventMap;
        
        target.addEventListener( type, onEvent );
    }
    
    /**
     * Remove an event add by the EventManager and destroys any associated keys
     * in the targets event map
     * 
     * @param target    The object to remove the listener from
     * @param type        The type of listener to remove
     */
    public static function removeEvent ( target:IEventDispatcher, type:String ) : void
    {
        var targetEventMap:Dictionary = targetMap[target];
        delete targetEventMap[type];
        
        target.removeEventListener( type, onEvent );
    }
    
    /** EVENT HANDLERS ************************************************************************/
    /**
     * Handles all events dispatched through the EventManager. 
     * Calls the associated listener, and applies the given arguments 
     * (with the event object prepended to the start of the array)
     * 
     * @param e    The Event that was dispatched
     */
    private static function onEvent ( e:Event ) : void
    {
        var target:IEventDispatcher        =     e.currentTarget as IEventDispatcher;
        var targetEventMap:Dictionary     =     targetMap[target];
        var eventType:String            =    e.type;
        
        var listener:Function    =     targetEventMap[eventType].listener;
        var args:Array            =     targetEventMap[eventType].args;
        
        if (args[0] is Event) args.shift();
        
        args.unshift( e );

        listener.apply( target, args );
    }
}

}
[/AS]

Useage is very simple:

[AS]

EventManager.addEvent( someButton, MouseEvent.CLICK, onClick, “duncan”, 22, 45 );

protected function onClick( e:MouseEvent, name:String, rand1:int, rand2:int ) : void
{
trace( name + " is awesome" );
trace( "here are some random numbers: " + rand1 + ", " + rand2 );
}

[/AS]

Thanks, thats the thing i’m looking for too but i’ve got error

5000: The class ‘EventManager’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.

i have added import flash.display.MovieClip in the class but still got the same error
any ideas please?

nice one Duncan. Although I guess technically it goes against the event model, I think it’s a really useful class :wink:

nice one! that class is sure to come in very useful from time to time!

Cheers guys, glad to see more people are finding this useful. Sekasi, I agree it’s not the most orthodox of methods, but the pragmatic approach can often get you (or maybe just me :|) out of some otherwise sticky situations.

Kik, I’m not sure why you’re getting that error, the class should not need to subclass any DisplayObject as it would never be added to the display list. Make sure you don’t have a MovieClip in your library with a linkage Class set to “EventManager” as this may cause the problem you are seeing.

Top work m8 … Much appreciated

I think what TheCanadian was talking about was something like this:

http://evolve.reintroducing.com/2007/10/23/as3/as3-custom-events/

except i put a params object in my custom events and pass the parameters in there. not strictly typed, i know, but you could change it to pass in params directly instead of a params object if you so choose.