1  /**
     2   * com.sekati.events.Broadcaster
     3   * @version 3.6.7
     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  
     9  import com.sekati.core.CoreObject;
    10  import com.sekati.log.Logger;
    11  import com.sekati.events.IBroadcastable;
    12  
    13  /**
    14   * Singleton Broadcaster with bulk subscribe/unsubscribe & the 
    15   * ability to pass arguments through broadcast events.
    16   * 
    17   * {@code Usage:
    18   * var bc:Broadcaster = Broadcaster.getInstance ();
    19   * bc.subscribe (fooMc);
    20   * bc.broadcast ("onChangeAlpha", 50);
    21   * }
    22   * @see {@link com.sekati.events.Dispatcher}
    23   */
    24  class com.sekati.events.Broadcaster extends CoreObject implements IBroadcastable {
    25  
    26  	private static var _instance:Broadcaster;
    27  	private var _listeners:Array;
    28  
    29  	/**
    30  	 * Singleton Private Constructor
    31  	 */
    32  	private function Broadcaster() {
    33  		super( );
    34  		_listeners = new Array( );
    35  	}
    36  
    37  	/**
    38  	 * Singleton Accessor
    39  	 * @return Broadcaster
    40  	 */
    41  	public static function getInstance():Broadcaster {
    42  		if (!_instance) _instance = new Broadcaster( );
    43  		return _instance;
    44  	}
    45  
    46  	/**
    47  	 * shorthand singleton accessor getter
    48  	 */
    49  	public static function get $():Broadcaster {
    50  		return Broadcaster.getInstance( );	
    51  	}	
    52  
    53  	/**
    54  	 * subscribe an object or array of objects as listeners to the Broadcaster.
    55  	 * Note: movieclips will automatically unsubscribe onUnload
    56  	 * @param o (Object) Object or Array of Object to subscribe
    57  	 * @return Void
    58  	 * {@code Usage:
    59  	 * Broadcaster.getInstance().subscribe( [fooMc, barMc] );
    60  	 * }
    61  	 */
    62  	public function subscribe(o:Object):Void {
    63  		if (o instanceof Array) {
    64  			for (var i:Number = 0; i < o.length ; i++) {
    65  				addListener( o[i] );
    66  				if (typeof (o[i]) == "movieclip") {
    67  					o[i].onUnload = function ():Void {
    68  						removeListener( o[i] );
    69  					};
    70  				}
    71  			}
    72  		} else {
    73  			addListener( o );
    74  		}
    75  	}
    76  
    77  	/**
    78  	 * unsubscribe an object or array of objects from  Broadcaster 
    79  	 * @param o (Object) Object or Array of Object to unsubscribe
    80  	 * @return Void
    81  	 * {@code Usage:
    82  	 * Broadcaster.getInstance().unsubscribe( [fooMc, barMc] );
    83  	 * }
    84  	 */
    85  	public function unsubscribe(o:Object):Void {
    86  		if (o instanceof Array) {
    87  			for (var i:Number = 0; i < o.length ; i++) {
    88  				removeListener( o[i] );
    89  			}
    90  		} else {
    91  			removeListener( o );
    92  		}
    93  	}
    94  
    95  	/**
    96  	 * Clear all listeners and reset the broadcaster.
    97  	 * @return Void
    98  	 */
    99  	public function reset():Void {
   100  		_listeners = new Array( );
   101  	}
   102  
   103  	/**
   104  	 * Broadcast event message to all subscribed listeners
   105  	 * @param e (String) event name to broadcast to subscribed listeners (extra arguments will be passed to listener event methods!)
   106  	 * @return Void
   107  	 */
   108  	public function broadcast():Void {
   109  		var e:String = String( arguments.shift( ) );
   110  		var a:Array = this._listeners.concat( );
   111  		var l:Number = a.length;
   112  		var m:String = "@@@ Broadcast: \"" + e + "\"";
   113  		Logger.$.notice( _instance, m );
   114  		for (var i:Number = 0; i < l ; i++) {
   115  			a[i][e].apply( a[i], arguments );
   116  		}
   117  	}
   118  
   119  	/**
   120  	 * add listener to broadcaster
   121  	 * @param o (Object)
   122  	 * @return Number
   123  	 */
   124  	public function addListener(o:Object):Number {
   125  		this.removeListener( o );
   126  		return this._listeners.push( o );
   127  	}
   128  
   129  	/**
   130  	 * remove listener from broadcaster
   131  	 * @param o (Object)
   132  	 * @return Boolean
   133  	 */
   134  	public function removeListener(o:Object):Boolean {
   135  		var a:Array = this._listeners;
   136  		var i:Number = a.length;
   137  		while (i--) {
   138  			if (a[i] == o) {
   139  				a.splice( i, 1 );
   140  				return true;
   141  			}
   142  		}
   143  		return false;
   144  	}
   145  
   146  	/**
   147  	 * Destroy singleton instance.
   148  	 * @return Void
   149  	 */
   150  	public function destroy():Void {
   151  		delete _listeners;
   152  		delete _instance;
   153  		super.destroy( );
   154  	}	
   155  }