Created
September 15, 2012 07:48
-
-
Save leegrey/3726860 to your computer and use it in GitHub Desktop.
SignalHub.as is a Signal manager for AS3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Commander: | |
Created on Sat 15th Sep, 2012 | |
by Lee Grey | |
Commander solves the problem of object-creation order by using lazy initialisation - whoever | |
makes the first request for a Signal with a given key will bring about it's creation. | |
Listeners can be added to a Signal even before the dispatching class | |
has optionally defined the type-signature of the Signal | |
Usage: | |
// create Commander instances by key, or use the default instance | |
//default: | |
var cmd = Commander.getInstance(); | |
//string key: | |
var cmd = Commander.getInstance( 'specificCommander' ); | |
var cmd = Commander.getInstance( 'ui' ); | |
var cmd = Commander.getInstance( 'sfx' ); | |
//use class as key: | |
var cmd = Commander.getInstance( MyClass ); | |
//use instace as key: | |
var cmd = Commander.getInstance( someInstance ); | |
//optional Signal definition for type safety: | |
cmd.defineSignal( 'someEvent', Number, Number ); | |
//Cache references to signals for performance-critical situations | |
var someEventSignal:Signal = cmd.defineSignal( 'someEvent', Number, Number ); | |
var someEventSignal:Signal = cmd.getSignal( 'someEvent' ); | |
//add listeners: | |
cmd.add( 'someEvent', onSomeEventHandler ); | |
cmd.addOnce( 'someEvent', onSomeEventHandler ); | |
//add listener to a particular instance: | |
Commander.getInstance( instance ).add( 'someEvent', onSomeEventHandler ); | |
//Cache references to signals for performance-critical situations: | |
var someEventSignal:Signal = cmd.defineSignal( 'someEvent', Number, Number ); | |
var someEventSignal:Signal = cmd.getSignal( 'someEvent' ); | |
//dispatch through Commander: | |
cmd.dispatch( 'someEvent', x, y ); | |
// dispatch the cached signal: | |
someEventSignal.dispatch( x, y ); | |
// dispatch for a specific instance: | |
Commander.getInstance( this ).dispatch( x, y ); | |
Static signal groups: | |
Using statc groups ensures that signals are created and | |
available to the application immediately | |
//for class XYZ, create a static instance of a group of signals: | |
class XYZSignalGroup { | |
//use the class XYZ as a key: | |
private const cmd:Commander = Commander.getInstance( XYZ ); | |
public const aSignal:Signal = cmd.defineSignal( 'someEvent', Number, Number ); | |
public const bSignal:Signal = cmd.defineSignal( 'someOtherEvent', Number, Number ); | |
} | |
// within XYZ class: | |
public static const signals:XYZSignalGroup = new XYZSignalGroup(); | |
// now access signals like this: | |
XYZ.signals.aSignal.add( 'someEvent', handler ); | |
// or... | |
Commander.getInstance( XYZ ).add( 'someEvent', handler ); | |
// Alternatively, a group with static members: | |
class XYZSignals { | |
//use the class XYZSignals as a key: | |
private static const cmd:Commander = Commander.getInstance( XYZSignalGroup ); | |
public static const aSignal:Signal = cmd.defineSignal( 'someEvent', Number, Number ); | |
public static const bSignal:Signal = cmd.defineSignal( 'someOtherEvent', Number, Number ); | |
} | |
//access like this: | |
XYZSignals.aSignal.add( 'someEvent', handler ); | |
*/ | |
package com.lgrey.signal { | |
import flash.utils.Dictionary; | |
import org.osflash.signals.Signal; | |
public class Commander { | |
private static var instances:Dictionary = new Dictionary(); | |
private var signals:Dictionary = new Dictionary(); | |
public function Commander() | |
{ | |
} | |
/*public static function defineSignal( key:*, ...types ):Signal | |
{ | |
}*/ | |
//use defineSignal to create type safe signals | |
public function defineSignal( key:*, ...types ):Signal | |
{ | |
var signal:Signal = signals[ key ]; | |
//warn if overwriting | |
if( signal ) { // assert( signals[ key ], 'warning....' ) | |
trace( 'Commander::defineSignal() - Warning, signal already existed for this key.' | |
+ ' Overwriting valueClasses.' ); | |
} else { | |
signal = signals[ key ] = new Signal(); | |
} | |
//set / update valueClasses | |
signal.valueClasses = types; | |
return signal | |
} | |
public function add( key:*, closure:Function ):Signal | |
{ | |
var signal:Signal = signals[ key ]; | |
if( !signal ) signal = signals[ key ] = new Signal(); | |
signal.add( closure ); | |
return signal; | |
} | |
public function addOnce( key:*, closure:Function ):Signal | |
{ | |
var signal:Signal = signals[ key ]; | |
if( !signal ) signal = signals[ key ] = new Signal(); | |
signal.addOnce( closure ); | |
return signal; | |
} | |
public function remove( key:*, closure:Function ):Signal | |
{ | |
var signal:Signal = signals[ key ]; | |
if( signal ) signal.remove( closure ); | |
return signal; | |
} | |
// using apply() results in a significant performance hit | |
// in performance-critical situations, cache the Signal reference | |
// returned by defineSignal() and getSignal() | |
public function dispatch( key:*, ...args ):Signal | |
{ | |
var signal:Signal = signals[ key ]; | |
if( signal ) signal.dispatch.apply( null, args ); | |
else trace( 'Commander::dispatch() - Warning, no signal with key:', key ); | |
return signal; | |
} | |
public function getSignal( key:* ):Signal | |
{ | |
var signal:Signal = signals[ key ]; | |
if( !signal ) signal = signals[ key ] = new Signal(); | |
return signal; | |
} | |
public static function getInstance( key:* = 'defaultInstance' ):Commander | |
{ | |
var cmd:Commander = instances[ key ]; | |
if( !cmd ) cmd = instances[ key ] = new Commander(); | |
return cmd; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment