diff --git a/src/org/osflash/signals/ISignalBindingSlot.as b/src/org/osflash/signals/ISignalBindingSlot.as
new file mode 100644
index 0000000..97815bf
--- /dev/null
+++ b/src/org/osflash/signals/ISignalBindingSlot.as
@@ -0,0 +1,53 @@
+package org.osflash.signals
+{
+ /**
+ * @author Simon Richardson - simon@ustwo.co.uk
+ */
+ public interface ISignalBindingSlot
+ {
+
+ /**
+ * Executes a listener of arity 0
.
+ */
+ function execute0():void;
+
+ /**
+ * Executes a listener of arity 1
.
+ *
+ * @param value1 The argument for the listener.
+ */
+ function execute1(value:Object):void;
+
+ /**
+ * Executes a listener of arity 2
.
+ *
+ * @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 3
.
+ *
+ * @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 n
.
+ *
+ * @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;
+ }
+}
diff --git a/src/org/osflash/signals/SignalBinding.as b/src/org/osflash/signals/SignalBinding.as
index 412d0b7..327db8d 100644
--- a/src/org/osflash/signals/SignalBinding.as
+++ b/src/org/osflash/signals/SignalBinding.as
@@ -70,7 +70,9 @@ package org.osflash.signals
// 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;
+ _strict = signal.strict;
+
+ verifyListener(listener);
}
/**
diff --git a/src/org/osflash/signals/SignalBindingSlot.as b/src/org/osflash/signals/SignalBindingSlot.as
new file mode 100644
index 0000000..85fedce
--- /dev/null
+++ b/src/org/osflash/signals/SignalBindingSlot.as
@@ -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 listener
property.
+ * @private
+ */
+ private var _listener : Function;
+
+ /**
+ * Private backing variable for the numArguments
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; }
+ }
+}
diff --git a/src/org/osflash/signals/SlotSignal.as b/src/org/osflash/signals/SlotSignal.as
new file mode 100644
index 0000000..8ab0bf7
--- /dev/null
+++ b/src/org/osflash/signals/SlotSignal.as
@@ -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);
+ }
+ }
+}
diff --git a/src/org/osflash/signals/SlotSignalBinding.as b/src/org/osflash/signals/SlotSignalBinding.as
new file mode 100644
index 0000000..b587e88
--- /dev/null
+++ b/src/org/osflash/signals/SlotSignalBinding.as
@@ -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 signal
property.
+ * @private
+ */
+ private var _signal:ISignal;
+
+ /**
+ * Private backing variable for the enabled
property.
+ * @private
+ */
+ private var _enabled:Boolean = true;
+
+ /**
+ * Private backing variable for the strict
property.
+ * @private
+ */
+ private var _strict:Boolean = true;
+
+ /**
+ * Private backing variable for the once
property.
+ *
+ * Visible in the signals package for fast access.
+ * @private
+ */
+ private var _once:Boolean;
+
+ /**
+ * Private backing variable for the priority
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 null
.
+ */
+ 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.');
+ }
+ }
+ }
+}
diff --git a/src/org/osflash/signals/natives/NativeSignal.as b/src/org/osflash/signals/natives/NativeSignal.as
index ba8386c..ce36953 100644
--- a/src/org/osflash/signals/natives/NativeSignal.as
+++ b/src/org/osflash/signals/natives/NativeSignal.as
@@ -181,8 +181,7 @@ package org.osflash.signals.natives
protected function registerListener(listener:Function, once:Boolean = false, priority:int = 0):ISignalBinding
{
- //TODO: Consider removing this check to allow ...args listeners.
- if (listener.length != 1)
+ if (_strict && listener.length != 1)
throw new ArgumentError('Listener for native event must declare exactly 1 argument.');
if (registrationPossible(listener, once))