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 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
/* | |
SignalHub: | |
Created on Sat 15th Sep, 2012 | |
by Lee Grey | |
SignalHub 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 SignalHub instances by key, or use the default instance | |
//default: | |
var signalHub = SignalHub.getHub(); | |
//string key: | |
var signalHub = SignalHub.getHub( 'specificHub' ); | |
var signalHub = SignalHub.getHub( 'ui' ); | |
var signalHub = SignalHub.getHub( 'soundFX' ); | |
//use class as key: | |
var signalHub = SignalHub.getHub( MyClass ); | |
//use instace as key: | |
var signalHub = SignalHub.getHub( someInstance ); | |
//optional Signal definition for type safety: | |
signalHub.defineSignal( 'someEvent', Number, Number ); | |
//Cache references to signals for performance-critical situations | |
var someEventSignal:Signal = signalHub.defineSignal( 'someEvent', Number, Number ); | |
var someEventSignal:Signal = signalHub.getSignal( 'someEvent' ); | |
//add listeners: | |
signalHub.add( 'someEvent', onSomeEventHandler ); | |
signalHub.addOnce( 'someEvent', onSomeEventHandler ); | |
//add listener to a particular instance: | |
SignalHub.getHub( instance ).add( 'someEvent', onSomeEventHandler ); | |
//Cache references to signals for performance-critical situations: | |
var someEventSignal:Signal = signalHub.defineSignal( 'someEvent', Number, Number ); | |
var someEventSignal:Signal = signalHub.getSignal( 'someEvent' ); | |
//dispatch through SignalHub: | |
signalHub.dispatch( 'someEvent', x, y ); | |
// dispatch the cached signal: | |
someEventSignal.dispatch( x, y ); | |
// dispatch for a specific instance: | |
SignalHub.getHub( 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 signalHub:SignalHub = SignalHub.getHub( XYZ ); | |
public const aSignal:Signal = signalHub.defineSignal( 'someEvent', Number, Number ); | |
public const bSignal:Signal = signalHub.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... | |
SignalHub.getHub( XYZ ).add( 'someEvent', handler ); | |
Note that any instance of XYZSignalGroup created will point to the same | |
signals, no matter where or when it is created. | |
// Alternatively, a group with static members: | |
class XYZSignals { | |
//use the class XYZSignals as a key: | |
private static const signalHub:SignalHub = SignalHub.getHub( XYZSignalGroup ); | |
public static const aSignal:Signal = signalHub.defineSignal( 'someEvent', Number, Number ); | |
public static const bSignal:Signal = signalHub.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 SignalHub { | |
private static var instances:Dictionary = new Dictionary(); | |
private var signals:Dictionary = new Dictionary(); | |
public function SignalHub() | |
{ | |
} | |
//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( 'SignalHub::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( 'SignalHub::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 getHub( key:* = 'defaultInstance' ):SignalHub | |
{ | |
var signalHub:SignalHub = instances[ key ]; | |
if( !signalHub ) signalHub = instances[ key ] = new SignalHub(); | |
return signalHub; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment