1  /**
     2   * com.sekati.events.EventBroadcaster
     3   * @version 1.0.1
     4   * @author jason m horwitz | sekati.com
     5   * Copyright (C) 2007  jason m horwitz, Sekat LLC. All Rights Reserved.
     6   * Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
     7   * 
     8   * based on ca.nectere.events.Broadcaster
     9   */
    10  
    11  import com.sekati.core.CoreObject;
    12  import com.sekati.core.KeyFactory;
    13  import com.sekati.events.IEventBroadcastable;
    14  import com.sekati.except.Catcher;
    15  import com.sekati.except.IllegalOperationException;
    16  import com.sekati.validate.TypeValidation;
    17  
    18  /**
    19   * EventBroadcaster 
    20   */
    21  class com.sekati.events.EventBroadcaster extends CoreObject implements IEventBroadcastable {
    22  
    23  	private static var _instance:EventBroadcaster;
    24  	private var _listeners:Array;
    25  
    26  	/**
    27  	 * Singleton Private Constructor.
    28  	 * @return Void
    29  	 */
    30  	private function EventBroadcaster() {
    31  		super( );
    32  		_listeners = new Array( );
    33  	}
    34  
    35  	/**
    36  	 * Singleton Accessor.
    37  	 * @return EventBroadcaster
    38  	 */
    39  	public static function getInstance():EventBroadcaster {
    40  		if (!_instance) _instance = new EventBroadcaster( );
    41  		return _instance;
    42  	}
    43  
    44  	/**
    45  	 * Shorthand Singleton accessor getter.
    46  	 * @return EventBroadcaster
    47  	 */
    48  	public static function get $():EventBroadcaster {
    49  		return EventBroadcaster.getInstance( );	
    50  	}
    51  
    52  	/**
    53  	 * Add an EventListener object
    54  	 * @param o (Object)
    55  	 * @param event (String)
    56  	 * @param handler (Function)
    57  	 * @return Void
    58  	 */
    59  	public function addEventListener(o:Object, event:String, handler:Function):Void {
    60  		var index:Object = getIndex( o );
    61  		if( !_listeners[index] ) _listeners[index] = new Array( );
    62  		if( !_listeners[index][event] ) _listeners[index][event] = new Array( );
    63  		_listeners[index][event].push( handler );
    64  	}
    65  
    66  	/**
    67  	 * Remove an EventListener object
    68  	 * @param o (Object)
    69  	 * @param event (String)
    70  	 * @param handler (Function)
    71  	 * @return Void
    72  	 */
    73  	public function removeEventListener(o:Object, event:String, handler:Function):Void {
    74  		var index:Object = getIndex( o );
    75  		var e:Array = _listeners[index][event];
    76  		for(var i in e) {
    77  			if(e[i] === handler) delete _listeners[index][event][i];
    78  		}
    79  	}
    80  
    81  	/**
    82  	 * Remove all listeners and reset the broadcaster
    83  	 * @return Void
    84  	 */
    85  	public function reset():Void {
    86  		_listeners = new Array( );
    87  	}
    88  
    89  	/**
    90  	 * Remove all listeners that are listening to a specific broadcaster
    91  	 * @param o (Object)
    92  	 * @return Void
    93  	 */
    94  	public function removeAllFromBroadcaster(o:Object):Void {
    95  		var index:Object = getIndex( o );
    96  		delete _listeners[index];
    97  	}
    98  
    99  	/**
   100  	 * Remove all listeners that are listening to a specific broadcaster and a specific event
   101  	 * @param o (Object)
   102  	 * @param event (String)
   103  	 * @return Void
   104  	 */
   105  	public function removeAllFromBroadcasterAndEvent(o:Object, event:String):Void {
   106  		var index:Object = getIndex( o );
   107  		delete _listeners[index][event];
   108  	}
   109  
   110  	/**
   111  	 * Broadcast to all listeners (can accept extra args)
   112  	 * @param o (Object)
   113  	 * @param event (String)
   114  	 * @return Void
   115  	 */
   116  	public function broadcastEvent(o:Object, event:String):Void {
   117  		broadcastArrayArgs( o, event, arguments.slice( 2 ) );
   118  	}
   119  
   120  	/**
   121  	 * Broadcast to all listeners (can accept extra args as array)
   122  	 * @param o (Object)
   123  	 * @param event (String)
   124  	 * @param args (Array)
   125  	 * @return Void
   126  	 */
   127  	public function broadcastArrayArgs(o:Object, event:String, args:Array):Void {
   128  		var index:Object = getIndex( o );
   129  		var e:Array = _listeners[index][event];
   130  		for(var i in e) e[i].getFunction( ).apply( this, args );
   131  	}
   132  
   133  	/**
   134  	 * Gets index to use, and will inject key in object if needed
   135  	 * This allows using objects or strings/numbers as channel for the broadcaster
   136  	 * Will return either a number or a string
   137  	 * @param o (Object)
   138  	 * @return Object
   139  	 */
   140  	private function getIndex(o:Object):Object {
   141  		try {
   142  			if (TypeValidation.isString( o ) || TypeValidation.isNumber( o )) {
   143  				return String( o );
   144  			} else if (TypeValidation.isObject( o ) || TypeValidation.isMovieClip( o ) || TypeValidation.isFunction( o )) {
   145  				return KeyFactory.getKey( o );
   146  			} else {
   147  				throw new IllegalOperationException( this, "Unsupported broadcaster type (must be object, clip, function, string or number).", arguments );
   148  			}
   149  		} catch (e:IllegalOperationException) {
   150  			Catcher.handle( e );
   151  		}
   152  	}
   153  }