Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Idea for allowing less arguments than the dispatching Signal
- Loading branch information
Simon Richardson
committed
Apr 11, 2011
1 parent
bd94583
commit 76a48c9
Showing
6 changed files
with
363 additions
and
3 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.osflash.signals | ||
{ | ||
/** | ||
* @author Simon Richardson - simon@ustwo.co.uk | ||
*/ | ||
public interface ISignalBindingSlot | ||
{ | ||
|
||
/** | ||
* Executes a listener of arity <code>0</code>. | ||
*/ | ||
function execute0():void; | ||
|
||
/** | ||
* Executes a listener of arity <code>1</code>. | ||
* | ||
* @param value1 The argument for the listener. | ||
*/ | ||
function execute1(value:Object):void; | ||
|
||
/** | ||
* Executes a listener of arity <code>2</code>. | ||
* | ||
* @param value1 The argument for the listener. | ||
* @param value2 The argument for the listener. | ||
*/ | ||
function execute2(value1:Object, value2:Object):void; | ||
|
||
/** | ||
* Executes a listener of arity <code>3</code>. | ||
* | ||
* @param value1 The argument for the listener. | ||
* @param value2 The argument for the listener. | ||
* @param value3 The argument for the listener. | ||
*/ | ||
function execute3(value1:Object, value2:Object, value3:Object):void; | ||
|
||
/** | ||
* Executes a listener of arity <code>n</code>. | ||
* | ||
* @param args The argument for the listener. | ||
*/ | ||
function execute(...args) : void; | ||
|
||
/** | ||
* The listener associated with this slot binding. | ||
*/ | ||
function get listener() : Function; | ||
function set listener(value : Function) : void; | ||
|
||
function get numArguments() : int; | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package org.osflash.signals | ||
{ | ||
/** | ||
* @author Simon Richardson - simon@ustwo.co.uk | ||
*/ | ||
public class SignalBindingSlot implements ISignalBindingSlot | ||
{ | ||
|
||
/** | ||
* Private backing variable for the <code>listener</code> property. | ||
* @private | ||
*/ | ||
private var _listener : Function; | ||
|
||
/** | ||
* Private backing variable for the <code>numArguments</code> property. | ||
* @private | ||
*/ | ||
private var _numArguments : int; | ||
|
||
public function SignalBindingSlot(listener : Function) | ||
{ | ||
_listener = listener; | ||
// Use the listener length to generate the numArguments | ||
_numArguments = listener.length; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function execute0() : void | ||
{ | ||
_listener(); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function execute1(valueObject1:Object) : void | ||
{ | ||
_listener(valueObject1); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function execute2(valueObject1:Object, valueObject2:Object) : void | ||
{ | ||
_listener(valueObject1, valueObject2); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function execute3(valueObject1:Object, valueObject2:Object, valueObject3:Object) : void | ||
{ | ||
_listener(valueObject1, valueObject2, valueObject3); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function execute(...args) : void | ||
{ | ||
_listener.apply(null, args); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function get listener() : Function { return _listener; } | ||
public function set listener(value : Function) : void { _listener = value; } | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function get numArguments() : int { return _numArguments; } | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.osflash.signals | ||
{ | ||
/** | ||
* @author Simon Richardson - simon@ustwo.co.uk | ||
*/ | ||
public class SlotSignal extends Signal | ||
{ | ||
/** | ||
* Creates a SlotSignal instance to dispatch arguments that are less than the ammount of | ||
* valueClasses passed in via the constructor. | ||
* @param valueClasses Any number of class references that enable type checks in dispatch(). | ||
* For example, var signal : SlotSignal = new SlotSignal(String, uint) | ||
* would allow: signal.add(function(s:String):void{}) | ||
* | ||
* | ||
* NOTE: Subclasses cannot call super.apply(null, valueClasses), | ||
* but this constructor has logic to support super(valueClasses). | ||
*/ | ||
public function SlotSignal(...valueClasses) | ||
{ | ||
// Cannot use super.apply(null, valueClasses), so allow the subclass to call super(valueClasses). | ||
valueClasses = (valueClasses.length == 1 && valueClasses[0] is Array) ? valueClasses[0]:valueClasses; | ||
|
||
super(valueClasses); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
override protected function registerListener(listener:Function, once:Boolean = false):ISignalBinding | ||
{ | ||
if (registrationPossible(listener, once)) | ||
{ | ||
const binding:ISignalBinding = new SlotSignalBinding(listener, once, this); | ||
bindings = new SignalBindingList(binding, bindings); | ||
return binding; | ||
} | ||
|
||
return bindings.find(listener); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
package org.osflash.signals | ||
{ | ||
/** | ||
* @author Simon Richardson - simon@ustwo.co.uk | ||
*/ | ||
public class SlotSignalBinding implements ISignalBinding | ||
{ | ||
/** | ||
* Private backing variable for the <code>signal</code> property. | ||
* @private | ||
*/ | ||
private var _signal:ISignal; | ||
|
||
/** | ||
* Private backing variable for the <code>enabled</code> property. | ||
* @private | ||
*/ | ||
private var _enabled:Boolean = true; | ||
|
||
/** | ||
* Private backing variable for the <code>strict</code> property. | ||
* @private | ||
*/ | ||
private var _strict:Boolean = true; | ||
|
||
/** | ||
* Private backing variable for the <code>once</code> property. | ||
* | ||
* Visible in the signals package for fast access. | ||
* @private | ||
*/ | ||
private var _once:Boolean; | ||
|
||
/** | ||
* Private backing variable for the <code>priority</code> property. | ||
* | ||
* Visible in the signals package for fast access. | ||
* @private | ||
*/ | ||
private var _priority:int; | ||
|
||
/** | ||
* @private | ||
*/ | ||
private var _slot:ISignalBindingSlot; | ||
|
||
/** | ||
* Creates and returns a new SignalBinding object. | ||
* | ||
* @param listener The listener associated with the binding. | ||
* @param once Whether or not the listener should be executed only once. | ||
* @param signal The signal associated with the binding. | ||
* @param priority The priority of the binding. | ||
* | ||
* @throws ArgumentError An error is thrown if the given listener closure is <code>null</code>. | ||
*/ | ||
public function SlotSignalBinding(listener:Function, once:Boolean = false, signal:ISignal = null, priority:int = 0) | ||
{ | ||
_once = once; | ||
_signal = signal; | ||
_priority = priority; | ||
|
||
// Work out what the strict mode is from the signal and set it here. You can change | ||
// the value of strict mode on the binding itself at a later date. | ||
_strict = signal.strict; | ||
|
||
verifyListener(listener); | ||
|
||
_slot = new SignalBindingSlot(listener); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function execute(valueObjects:Array):void | ||
{ | ||
if (!_enabled) return; | ||
if (_once) remove(); | ||
|
||
// Here we're using what the listener.length is to provide the correct arguments. | ||
const numArguments : int = _slot.numArguments; | ||
if(numArguments == 0) | ||
{ | ||
_slot.execute0(); | ||
} | ||
else if(numArguments == 1) | ||
{ | ||
_slot.execute1(valueObjects[0]); | ||
} | ||
else if(numArguments == 2) | ||
{ | ||
_slot.execute2(valueObjects[0], valueObjects[1]); | ||
} | ||
else if(numArguments == 3) | ||
{ | ||
_slot.execute3(valueObjects[0], valueObjects[1], valueObjects[2]); | ||
} | ||
else | ||
{ | ||
_slot.execute.apply(null, valueObjects); | ||
} | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function get listener():Function | ||
{ | ||
return _slot.listener; | ||
} | ||
|
||
public function set listener(value:Function):void | ||
{ | ||
if (null == value) throw new ArgumentError( | ||
'Given listener is null.\nDid you want to call pause() instead?'); | ||
|
||
verifyListener(value); | ||
|
||
_slot.listener = value; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function get once():Boolean { return _once; } | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function get priority():int { return _priority; } | ||
|
||
/** | ||
* Creates and returns the string representation of the current object. | ||
* | ||
* @return The string representation of the current object. | ||
*/ | ||
public function toString():String | ||
{ | ||
return "[SlotSignalBinding listener: "+listener+", once: "+_once | ||
+", priority: "+_priority+", enabled: "+_enabled+"]"; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function get enabled():Boolean { return _enabled; } | ||
|
||
public function set enabled(value:Boolean):void { _enabled = value; } | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function get strict():Boolean { return _strict; } | ||
|
||
public function set strict(value:Boolean):void | ||
{ | ||
_strict = value; | ||
|
||
// Check that when we move from one strict mode to another strict mode and verify the | ||
// listener again. | ||
verifyListener(listener); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function remove():void | ||
{ | ||
_signal.remove(_slot.listener); | ||
} | ||
|
||
protected function verifyListener(listener:Function): void | ||
{ | ||
if (null == listener) | ||
{ | ||
throw new ArgumentError('Given listener is null.'); | ||
} | ||
|
||
if (null == _signal) | ||
{ | ||
throw new Error('Internal signal reference has not been set yet.'); | ||
} | ||
} | ||
} | ||
} |
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