Skip to content

Instantly share code, notes, and snippets.

@leegrey
Created September 15, 2012 07:48
Show Gist options
  • Save leegrey/3726860 to your computer and use it in GitHub Desktop.
Save leegrey/3726860 to your computer and use it in GitHub Desktop.
SignalHub.as is a Signal manager for AS3
/*
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' );
//use class as key:
var cmd = Commander.getInstance( MyClass );
//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 );
//Cache references to signals for performance crucial 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 );
*/
// Should I require defineSignal to be called first? That would give the best type safety....
package com.lgrey {
public class Commander {
private static var instances:Dictionary = new Dictionary();
private var signals:Dictionary = new Dictionary();
public var Commander()
{
}
//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 );
}
public function getSignal( 'key' ):void
{
var signal:Signal = signals[ key ];
if( !signal ) signal = signals[ key ] = new Signal();
return signal;
}
public static function getInstance( key:* = Commander ):void
{
var cmd:Commander = instances[ key ];
if( !cmd ) cmd = new Commander();
return cmd;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment