as3signals 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.textile +51 -0
- data/Gemfile +6 -0
- data/MIT-LICENSE.txt +22 -0
- data/README.textile +43 -0
- data/Rakefile +52 -0
- data/as3-signals.as3proj +87 -0
- data/as3-signals.docproj +9 -0
- data/as3signals.gemspec +24 -0
- data/build-asunit.properties +7 -0
- data/build-asunit.xml +34 -0
- data/build.properties +20 -0
- data/build.xml +53 -0
- data/lib/as3signals.rb +15 -0
- data/src/org/osflash/signals/DeluxeSignal.as +260 -0
- data/src/org/osflash/signals/IDeluxeSignal.as +34 -0
- data/src/org/osflash/signals/IDispatcher.as +15 -0
- data/src/org/osflash/signals/ISignal.as +44 -0
- data/src/org/osflash/signals/ISignalOwner.as +13 -0
- data/src/org/osflash/signals/Signal.as +206 -0
- data/src/org/osflash/signals/events/GenericEvent.as +44 -0
- data/src/org/osflash/signals/events/IBubbleEventHandler.as +14 -0
- data/src/org/osflash/signals/events/IEvent.as +27 -0
- data/src/org/osflash/signals/natives/INativeDispatcher.as +34 -0
- data/src/org/osflash/signals/natives/NativeMappedSignal.as +230 -0
- data/src/org/osflash/signals/natives/NativeRelaySignal.as +71 -0
- data/src/org/osflash/signals/natives/NativeSignal.as +176 -0
- data/tests/org/osflash/signals/AllTests.as +44 -0
- data/tests/org/osflash/signals/AllTestsRunner.as +19 -0
- data/tests/org/osflash/signals/AmbiguousRelationshipTest.as +60 -0
- data/tests/org/osflash/signals/DeluxeSignalAmbiguousRelationshipTest.as +60 -0
- data/tests/org/osflash/signals/DeluxeSignalDispatchExtraArgsTest.as +43 -0
- data/tests/org/osflash/signals/DeluxeSignalDispatchNoArgsTest.as +55 -0
- data/tests/org/osflash/signals/DeluxeSignalDispatchNonEventTest.as +67 -0
- data/tests/org/osflash/signals/DeluxeSignalSplitInterfacesTest.as +41 -0
- data/tests/org/osflash/signals/DeluxeSignalTest.as +134 -0
- data/tests/org/osflash/signals/DeluxeSignalWithBubblingEventTest.as +129 -0
- data/tests/org/osflash/signals/DeluxeSignalWithCustomEventTest.as +84 -0
- data/tests/org/osflash/signals/DeluxeSignalWithGenericEventTest.as +190 -0
- data/tests/org/osflash/signals/GenericEventTest.as +62 -0
- data/tests/org/osflash/signals/PriorityListenersTest.as +68 -0
- data/tests/org/osflash/signals/RedispatchedEventTest.as +51 -0
- data/tests/org/osflash/signals/SignalDispatchArgsTest.as +74 -0
- data/tests/org/osflash/signals/SignalDispatchNoArgsTest.as +55 -0
- data/tests/org/osflash/signals/SignalDispatchNonEventTest.as +81 -0
- data/tests/org/osflash/signals/SignalSplitInterfacesTest.as +47 -0
- data/tests/org/osflash/signals/SignalTest.as +267 -0
- data/tests/org/osflash/signals/SignalWithCustomEventTest.as +107 -0
- data/tests/org/osflash/signals/natives/AmbiguousRelationshipInNativeSignalTest.as +63 -0
- data/tests/org/osflash/signals/natives/NativeMappedSignalBoundaryUseTest.as +100 -0
- data/tests/org/osflash/signals/natives/NativeMappedSignalDefaultsTest.as +78 -0
- data/tests/org/osflash/signals/natives/NativeMappedSignalFunctionArgTest.as +148 -0
- data/tests/org/osflash/signals/natives/NativeMappedSignalFunctionNoArgsTest.as +95 -0
- data/tests/org/osflash/signals/natives/NativeMappedSignalObjectArgTest.as +85 -0
- data/tests/org/osflash/signals/natives/NativeRelaySignalTest.as +174 -0
- data/tests/org/osflash/signals/natives/NativeSignalTest.as +312 -0
- metadata +152 -0
@@ -0,0 +1,230 @@
|
|
1
|
+
package org.osflash.signals.natives
|
2
|
+
{
|
3
|
+
import flash.events.Event;
|
4
|
+
import flash.events.IEventDispatcher;
|
5
|
+
|
6
|
+
/**
|
7
|
+
* <p>
|
8
|
+
* The NativeMappedSignal class is used to map/transform a native Event,
|
9
|
+
* relayed from an IEventDispatcher, into other forms of data,
|
10
|
+
* which are dispatched to all listeners.
|
11
|
+
* </p>
|
12
|
+
* <p>This can be used to form a border where native flash Events do not cross.</p>
|
13
|
+
*/
|
14
|
+
public class NativeMappedSignal extends NativeRelaySignal
|
15
|
+
{
|
16
|
+
/**
|
17
|
+
* @default is initialized to flash.events.Event in constructor if omitted as parameter
|
18
|
+
*/
|
19
|
+
protected var _eventClass:Class;
|
20
|
+
|
21
|
+
public function get eventClass ():Class
|
22
|
+
{
|
23
|
+
return _eventClass;
|
24
|
+
}
|
25
|
+
|
26
|
+
/**
|
27
|
+
* @default is null, no mapping will occur
|
28
|
+
*/
|
29
|
+
private var _mappingFunction:Function = null;
|
30
|
+
|
31
|
+
/*open for extension but closed for modifications*/
|
32
|
+
protected function get mappingFunction ():Function
|
33
|
+
{
|
34
|
+
return _mappingFunction;
|
35
|
+
}
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Creates a new NativeMappedSignal instance to map/transform a native Event,
|
39
|
+
* relayed from an IEventDispatcher, into other forms of data,
|
40
|
+
* which are dispatched to all listeners.
|
41
|
+
*
|
42
|
+
* @param target An object that implements the flash.events.IEventDispatcher interface.
|
43
|
+
* @param eventType The event string name that would normally be passed to IEventDispatcher.addEventListener().
|
44
|
+
* @param eventClass An optional class reference that enables an event type check in dispatch().
|
45
|
+
* @param mappedTypes an optional list of types that enables the checking of the types mapped from an Event.
|
46
|
+
*/
|
47
|
+
public function NativeMappedSignal(target:IEventDispatcher, eventType:String, eventClass:Class=null, ... mappedTypes)
|
48
|
+
{
|
49
|
+
_eventClass = eventClass || Event;
|
50
|
+
super(target, eventType);
|
51
|
+
setValueClasses(mappedTypes);
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Sets the mapping function or literal object list.
|
56
|
+
* If the argument is a list of object literals then this list is dispatched to listeners.
|
57
|
+
*
|
58
|
+
* <listing version="3.0">
|
59
|
+
* signal = new NativeMappedSignal(button, MouseEvent.CLICK, MouseEvent, String).mapTo("ping")
|
60
|
+
* signal.add(function(arg:String):void { trace(arg) }) // prints "ping"
|
61
|
+
* </listing>
|
62
|
+
*
|
63
|
+
* And an example passing a list of literals:
|
64
|
+
*
|
65
|
+
* <listing version="3.0">
|
66
|
+
* signal = new NativeMappedSignal(button, MouseEvent.CLICK, MouseEvent, String, int, Number).mapTo("ping", 3, 3.1415)
|
67
|
+
* signal.add(function(arg1:String, arg2:int, arg3:Number):void { trace(arg1, arg2, arg3) }) // prints "ping", 3, 3.1415
|
68
|
+
* </listing>
|
69
|
+
*
|
70
|
+
* If the argument is a function then it is called when the event this NativeMappedSignal is listeneing for is dispatched.
|
71
|
+
* The function should return an Array or a single object. The data returned from the function is passed along as arguemnts in the Signal dispatch.
|
72
|
+
* Lets look at some examples of mapping functions and the function that is called back:
|
73
|
+
*
|
74
|
+
* <listing version="3.0">
|
75
|
+
* signal = new NativeMappedSignal(button, MouseEvent.CLICK, MouseEvent, String).mapTo(function():void {
|
76
|
+
* return "ping"
|
77
|
+
* })
|
78
|
+
* signal.add(function(arg:String):void { trace(arg) }) // prints "ping"
|
79
|
+
* </listing>
|
80
|
+
*
|
81
|
+
* and here's an example using a list of arguments:
|
82
|
+
*
|
83
|
+
* <listing version="3.0">
|
84
|
+
* signal = new NativeMappedSignal(button, MouseEvent.CLICK, MouseEvent, String, int, Number).mapTo(function():void {
|
85
|
+
* return ["ping", 3, 3.1415]
|
86
|
+
* })
|
87
|
+
* signal.add(function(arg1:String, arg2:int, arg3:Number):void { trace(arg1, arg2, arg3) }) // prints "ping", 3, 3.1415
|
88
|
+
* </listing>
|
89
|
+
*
|
90
|
+
* You can also state your wish to receive the native Event in th mapping function by simply including an argument of type Event:
|
91
|
+
*
|
92
|
+
* <listing version="3.0">
|
93
|
+
* signal = new NativeMappedSignal(button, MouseEvent.CLICK, MouseEvent, Point).mapTo(function(event:MouseEvent):void {
|
94
|
+
* return new Point(event.localX, event.localY)
|
95
|
+
* })
|
96
|
+
* signal.add(function(arg:Point):void { trace(arg) }) // prints "(x=128, y=256)"
|
97
|
+
* </listing>
|
98
|
+
*
|
99
|
+
* @param objectListOrFunction This can either be a list of object literals or a function that returns list of objects.
|
100
|
+
* @return The NativeMappedSignal object this method was called on. This allows the Signal to be defined and mapped in one statement.
|
101
|
+
*/
|
102
|
+
public function mapTo(...objectListOrFunction):NativeMappedSignal
|
103
|
+
{
|
104
|
+
if (isArgumentListAFunction(objectListOrFunction))
|
105
|
+
{
|
106
|
+
_mappingFunction = objectListOrFunction[0] as Function;
|
107
|
+
|
108
|
+
if (hasFunctionMoreThanOneArgument(_mappingFunction))
|
109
|
+
{
|
110
|
+
throw new ArgumentError('Mapping function has ' + _mappingFunction.length
|
111
|
+
+ ' arguments but it needs zero or one of type Event');
|
112
|
+
}
|
113
|
+
}
|
114
|
+
else
|
115
|
+
{
|
116
|
+
_mappingFunction = function ():Object { return objectListOrFunction; };
|
117
|
+
}
|
118
|
+
|
119
|
+
return this;
|
120
|
+
}
|
121
|
+
|
122
|
+
private function isArgumentListAFunction(argList:Array):Boolean
|
123
|
+
{
|
124
|
+
return argList.length == 1 && argList[0] is Function;
|
125
|
+
}
|
126
|
+
|
127
|
+
private function hasFunctionMoreThanOneArgument(f:Function):Boolean
|
128
|
+
{
|
129
|
+
return f.length > 1;
|
130
|
+
}
|
131
|
+
|
132
|
+
/**
|
133
|
+
* This is used as eventHandler for target or can be called directly with the parameters specified by valueClasses.
|
134
|
+
* <p>If used as eventHandler the data mapping system is used to supply the super.dispatch with alternative data to dispatch.</p>
|
135
|
+
*
|
136
|
+
* @see #mapEvent()
|
137
|
+
* @see #mapTo()
|
138
|
+
* @see org.osflash.signals.NativeRelaySignal#dispatch()
|
139
|
+
*/
|
140
|
+
override public function dispatch (... valueObjects):void
|
141
|
+
{
|
142
|
+
if (areValueObjectValidForMapping(valueObjects))
|
143
|
+
{
|
144
|
+
var mappedData:Object = mapEvent(valueObjects[0] as Event);
|
145
|
+
dispatchMappedData(mappedData);
|
146
|
+
}
|
147
|
+
else
|
148
|
+
{
|
149
|
+
super.dispatch.apply(null, valueObjects);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
private function areValueObjectValidForMapping(valueObjects:Array):Boolean
|
154
|
+
{
|
155
|
+
return valueObjects.length == 1 && valueObjects[0] is _eventClass;
|
156
|
+
}
|
157
|
+
|
158
|
+
private function dispatchMappedData(mappedData:Object):void
|
159
|
+
{
|
160
|
+
if (mappedData is Array)
|
161
|
+
{
|
162
|
+
if (shouldArrayBePassedWithoutUnrolling)
|
163
|
+
{
|
164
|
+
super.dispatch.call(null, mappedData);
|
165
|
+
}
|
166
|
+
else
|
167
|
+
{
|
168
|
+
super.dispatch.apply(null, mappedData);
|
169
|
+
}
|
170
|
+
}
|
171
|
+
else
|
172
|
+
{
|
173
|
+
super.dispatch.call(null, mappedData);
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
private function get shouldArrayBePassedWithoutUnrolling():Boolean
|
178
|
+
{
|
179
|
+
return _valueClasses.length == 1 && _valueClasses[0] == Array;
|
180
|
+
}
|
181
|
+
|
182
|
+
protected function get mappingFunctionWantsEvent():Boolean
|
183
|
+
{
|
184
|
+
return _mappingFunction.length == 1;
|
185
|
+
}
|
186
|
+
|
187
|
+
protected function get mappingFunctionExists():Boolean
|
188
|
+
{
|
189
|
+
return _mappingFunction != null;
|
190
|
+
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
* For usage without extension, instances of <code>NativeMappedSignal</code> that are dispatching any values ( <code>valueClasses.length > 0</code> ),
|
194
|
+
* needs to be provided with a either a mapping function or a list of object literals.
|
195
|
+
* See <code>mapTo</code> for more info.
|
196
|
+
*
|
197
|
+
* Subcclasses could override this one instead of letting the environment set the mapTo,
|
198
|
+
* MAKE SURE to also override <code>mapTo(...)</code> if it should not be allowed.
|
199
|
+
*
|
200
|
+
* @parameter eventFromTarget the event that was dispatched from target.
|
201
|
+
* @return An object or Array of objects mapped from an Event. The mapping of Event to data will be performed by the mapping function
|
202
|
+
* if it is set. A list of object literals can also be supplied in place of the mapping function.
|
203
|
+
* If no mapping function or object literals are supplied then an empty Array is returned or
|
204
|
+
* if <code>valueClasses.length > 0</code> an ArgumentError is thrown.
|
205
|
+
*
|
206
|
+
* @see #mapTo()
|
207
|
+
*/
|
208
|
+
protected function mapEvent (eventFromTarget:Event):Object
|
209
|
+
{
|
210
|
+
if (mappingFunctionExists)
|
211
|
+
{
|
212
|
+
if (mappingFunctionWantsEvent)
|
213
|
+
{
|
214
|
+
return _mappingFunction(eventFromTarget);
|
215
|
+
}
|
216
|
+
else
|
217
|
+
{
|
218
|
+
return _mappingFunction();
|
219
|
+
}
|
220
|
+
}
|
221
|
+
else if (valueClasses.length == 0)
|
222
|
+
{
|
223
|
+
return [];
|
224
|
+
}
|
225
|
+
|
226
|
+
throw new ArgumentError("There are valueClasses set to be dispatched <" + valueClasses
|
227
|
+
+ "> but mappingFunction is null.");
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
package org.osflash.signals.natives
|
2
|
+
{
|
3
|
+
import org.osflash.signals.DeluxeSignal;
|
4
|
+
|
5
|
+
import flash.events.Event;
|
6
|
+
import flash.events.IEventDispatcher;
|
7
|
+
|
8
|
+
/**
|
9
|
+
* The NativeRelaySignal class is used to relay events from an IEventDispatcher
|
10
|
+
* to listeners.
|
11
|
+
* The difference as compared to NativeSignal is that
|
12
|
+
* NativeRelaySignal has its own dispatching code,
|
13
|
+
* whereas NativeSignal uses the IEventDispatcher to dispatch.
|
14
|
+
*/
|
15
|
+
public class NativeRelaySignal extends DeluxeSignal
|
16
|
+
{
|
17
|
+
protected var _eventType:String;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Creates a new NativeRelaySignal instance to relay events from an IEventDispatcher.
|
21
|
+
* @param target An object that implements the flash.events.IEventDispatcher interface.
|
22
|
+
* @param name The event string name that would normally be passed to IEventDispatcher.addEventListener().
|
23
|
+
* @param eventClass An optional class reference that enables an event type check in dispatch().
|
24
|
+
* Because the target is an IEventDispatcher,
|
25
|
+
* eventClass needs to be flash.events.Event or a subclass of it.
|
26
|
+
*/
|
27
|
+
public function NativeRelaySignal(target:IEventDispatcher, eventType:String, eventClass:Class = null)
|
28
|
+
{
|
29
|
+
super(target, eventClass || Event);
|
30
|
+
_eventType = eventType;
|
31
|
+
}
|
32
|
+
|
33
|
+
/** @inheritDoc */
|
34
|
+
override public function addWithPriority(listener:Function, priority:int = 0):Function
|
35
|
+
{
|
36
|
+
var prevListenerCount:uint = listenerBoxes.length;
|
37
|
+
// Try to add first because it may throw an exception.
|
38
|
+
super.addWithPriority(listener);
|
39
|
+
// Account for cases where the same listener is added twice.
|
40
|
+
if (prevListenerCount == 0 && listenerBoxes.length == 1)
|
41
|
+
IEventDispatcher(_target).addEventListener(_eventType, dispatch, false, priority);
|
42
|
+
|
43
|
+
return listener;
|
44
|
+
}
|
45
|
+
|
46
|
+
/** @inheritDoc */
|
47
|
+
override public function addOnceWithPriority(listener:Function, priority:int = 0):Function
|
48
|
+
{
|
49
|
+
var prevListenerCount:uint = listenerBoxes.length;
|
50
|
+
// Try to add first because it may throw an exception.
|
51
|
+
super.addOnceWithPriority(listener);
|
52
|
+
// Account for cases where the same listener is added twice.
|
53
|
+
if (prevListenerCount == 0 && listenerBoxes.length == 1)
|
54
|
+
IEventDispatcher(_target).addEventListener(_eventType, dispatch, false, priority);
|
55
|
+
|
56
|
+
return listener;
|
57
|
+
}
|
58
|
+
|
59
|
+
/** @inheritDoc */
|
60
|
+
override public function remove(listener:Function):Function
|
61
|
+
{
|
62
|
+
var prevListenerCount:uint = listenerBoxes.length;
|
63
|
+
super.remove(listener);
|
64
|
+
if (prevListenerCount == 1 && listenerBoxes.length == 0)
|
65
|
+
IEventDispatcher(_target).removeEventListener(_eventType, dispatch);
|
66
|
+
|
67
|
+
return listener;
|
68
|
+
}
|
69
|
+
|
70
|
+
}
|
71
|
+
}
|
@@ -0,0 +1,176 @@
|
|
1
|
+
package org.osflash.signals.natives
|
2
|
+
{
|
3
|
+
import org.osflash.signals.IDeluxeSignal;
|
4
|
+
|
5
|
+
import flash.errors.IllegalOperationError;
|
6
|
+
import flash.events.Event;
|
7
|
+
import flash.events.IEventDispatcher;
|
8
|
+
|
9
|
+
/**
|
10
|
+
* The NativeSignal class provides a strongly-typed facade for an IEventDispatcher.
|
11
|
+
* A NativeSignal is essentially a mini-dispatcher locked to a specific event type and class.
|
12
|
+
* It can become part of an interface.
|
13
|
+
*/
|
14
|
+
public class NativeSignal implements IDeluxeSignal, INativeDispatcher
|
15
|
+
{
|
16
|
+
protected var _target:IEventDispatcher;
|
17
|
+
protected var _eventType:String;
|
18
|
+
protected var _eventClass:Class;
|
19
|
+
protected var listenerBoxes:Array;
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Creates a NativeSignal instance to dispatch events on behalf of a target object.
|
23
|
+
* @param target The object on whose behalf the signal is dispatching events.
|
24
|
+
* @param eventType The type of Event permitted to be dispatched from this signal. Corresponds to Event.type.
|
25
|
+
* @param eventClass An optional class reference that enables an event type check in dispatch(). Defaults to flash.events.Event if omitted.
|
26
|
+
*/
|
27
|
+
public function NativeSignal(target:IEventDispatcher, eventType:String, eventClass:Class = null)
|
28
|
+
{
|
29
|
+
_target = target;
|
30
|
+
_eventType = eventType;
|
31
|
+
_eventClass = eventClass || Event;
|
32
|
+
listenerBoxes = [];
|
33
|
+
}
|
34
|
+
|
35
|
+
/** @inheritDoc */
|
36
|
+
public function get eventType():String { return _eventType; }
|
37
|
+
|
38
|
+
/** @inheritDoc */
|
39
|
+
public function get eventClass():Class { return _eventClass; }
|
40
|
+
|
41
|
+
/** @inheritDoc */
|
42
|
+
public function get valueClasses():Array { return [_eventClass]; }
|
43
|
+
|
44
|
+
/** @inheritDoc */
|
45
|
+
public function get numListeners():uint { return listenerBoxes.length; }
|
46
|
+
|
47
|
+
/** @inheritDoc */
|
48
|
+
public function get target():IEventDispatcher { return _target; }
|
49
|
+
|
50
|
+
/** @inheritDoc */
|
51
|
+
public function set target(value:IEventDispatcher):void
|
52
|
+
{
|
53
|
+
if (value == _target) return;
|
54
|
+
removeAll();
|
55
|
+
_target = value;
|
56
|
+
}
|
57
|
+
|
58
|
+
/** @inheritDoc */
|
59
|
+
//TODO: @throws
|
60
|
+
public function add(listener:Function):Function
|
61
|
+
{
|
62
|
+
return addWithPriority(listener)
|
63
|
+
}
|
64
|
+
|
65
|
+
/** @inheritDoc */
|
66
|
+
//TODO: @throws
|
67
|
+
public function addWithPriority(listener:Function, priority:int = 0):Function
|
68
|
+
{
|
69
|
+
registerListener(listener, false, priority);
|
70
|
+
return listener;
|
71
|
+
}
|
72
|
+
|
73
|
+
public function addOnce(listener:Function):Function
|
74
|
+
{
|
75
|
+
return addOnceWithPriority(listener)
|
76
|
+
}
|
77
|
+
|
78
|
+
/** @inheritDoc */
|
79
|
+
public function addOnceWithPriority(listener:Function, priority:int = 0):Function
|
80
|
+
{
|
81
|
+
registerListener(listener, true, priority);
|
82
|
+
return listener;
|
83
|
+
}
|
84
|
+
|
85
|
+
/** @inheritDoc */
|
86
|
+
public function remove(listener:Function):Function
|
87
|
+
{
|
88
|
+
var listenerIndex:int = indexOfListener(listener);
|
89
|
+
if (listenerIndex == -1) return listener;
|
90
|
+
var listenerBox:Object = listenerBoxes.splice(listenerIndex, 1)[0];
|
91
|
+
// For once listeners, execute is a wrapper function around the listener.
|
92
|
+
_target.removeEventListener(_eventType, listenerBox.execute);
|
93
|
+
return listener;
|
94
|
+
}
|
95
|
+
|
96
|
+
/** @inheritDoc */
|
97
|
+
public function removeAll():void
|
98
|
+
{
|
99
|
+
for (var i:int = listenerBoxes.length; i--; )
|
100
|
+
{
|
101
|
+
remove(listenerBoxes[i].listener as Function);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* Unlike other signals, NativeSignal does not dispatch null
|
107
|
+
* because it causes an exception in EventDispatcher.
|
108
|
+
* @inheritDoc
|
109
|
+
*/
|
110
|
+
public function dispatch(event:Event):Boolean
|
111
|
+
{
|
112
|
+
if (!(event is _eventClass))
|
113
|
+
throw new ArgumentError('Event object '+event+' is not an instance of '+_eventClass+'.');
|
114
|
+
|
115
|
+
if (event.type != _eventType)
|
116
|
+
throw new ArgumentError('Event object has incorrect type. Expected <'+_eventType+'> but was <'+event.type+'>.');
|
117
|
+
|
118
|
+
return _target.dispatchEvent(event);
|
119
|
+
}
|
120
|
+
|
121
|
+
protected function registerListener(listener:Function, once:Boolean = false, priority:int = 0):void
|
122
|
+
{
|
123
|
+
// function.length is the number of arguments.
|
124
|
+
if (listener.length != 1)
|
125
|
+
throw new ArgumentError('Listener for native event must declare exactly 1 argument.');
|
126
|
+
|
127
|
+
var prevListenerIndex:int = indexOfListener(listener);
|
128
|
+
if (prevListenerIndex >= 0)
|
129
|
+
{
|
130
|
+
// If the listener was previously added, definitely don't add it again.
|
131
|
+
// But throw an exception in some cases, as the error messages explain.
|
132
|
+
var prevlistenerBox:Object = listenerBoxes[prevListenerIndex];
|
133
|
+
if (prevlistenerBox.once && !once)
|
134
|
+
{
|
135
|
+
throw new IllegalOperationError('You cannot addOnce() then add() the same listener without removing the relationship first.');
|
136
|
+
}
|
137
|
+
else if (!prevlistenerBox.once && once)
|
138
|
+
{
|
139
|
+
throw new IllegalOperationError('You cannot add() then addOnce() the same listener without removing the relationship first.');
|
140
|
+
}
|
141
|
+
// Listener was already added, so do nothing.
|
142
|
+
return;
|
143
|
+
}
|
144
|
+
|
145
|
+
var listenerBox:Object = { listener:listener, once:once, execute:listener };
|
146
|
+
|
147
|
+
if (once)
|
148
|
+
{
|
149
|
+
var signal:NativeSignal = this;
|
150
|
+
// For once listeners, create a wrapper function to automatically remove the listener.
|
151
|
+
listenerBox.execute = function(event:Event):void
|
152
|
+
{
|
153
|
+
signal.remove(listener);
|
154
|
+
listener(event);
|
155
|
+
};
|
156
|
+
}
|
157
|
+
|
158
|
+
listenerBoxes[listenerBoxes.length] = listenerBox;
|
159
|
+
_target.addEventListener(_eventType, listenerBox.execute, false, priority);
|
160
|
+
}
|
161
|
+
|
162
|
+
/**
|
163
|
+
*
|
164
|
+
* @param listener A handler function that may have been added previously.
|
165
|
+
* @return The index of the listener in the listenerBoxes array, or -1 if not found.
|
166
|
+
*/
|
167
|
+
protected function indexOfListener(listener:Function):int
|
168
|
+
{
|
169
|
+
for (var i:int = listenerBoxes.length; i--; )
|
170
|
+
{
|
171
|
+
if (listenerBoxes[i].listener == listener) return i;
|
172
|
+
}
|
173
|
+
return -1;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
package org.osflash.signals
|
2
|
+
{
|
3
|
+
import org.osflash.signals.natives.AmbiguousRelationshipInNativeSignalTest;
|
4
|
+
import org.osflash.signals.natives.NativeMappedSignalBoundaryUseTest;
|
5
|
+
import org.osflash.signals.natives.NativeMappedSignalDefaultsTest;
|
6
|
+
import org.osflash.signals.natives.NativeMappedSignalFunctionArgTest;
|
7
|
+
import org.osflash.signals.natives.NativeMappedSignalFunctionNoArgsTest;
|
8
|
+
import org.osflash.signals.natives.NativeMappedSignalObjectArgTest;
|
9
|
+
import org.osflash.signals.natives.NativeRelaySignalTest;
|
10
|
+
import org.osflash.signals.natives.NativeSignalTest;
|
11
|
+
|
12
|
+
[Suite]
|
13
|
+
public class AllTests
|
14
|
+
{
|
15
|
+
public var _AmbiguousRelationshipTest:AmbiguousRelationshipTest;
|
16
|
+
public var _AmbiguousRelationshipInNativeSignalTest:AmbiguousRelationshipInNativeSignalTest;
|
17
|
+
public var _GenericEventTest:GenericEventTest;
|
18
|
+
public var _NativeRelaySignalTest:NativeRelaySignalTest;
|
19
|
+
public var _NativeSignalTest:NativeSignalTest;
|
20
|
+
public var _NativeMappedSignalDefaultsTest:NativeMappedSignalDefaultsTest;
|
21
|
+
public var _NativeMappedSignalObjectArgTest:NativeMappedSignalObjectArgTest;
|
22
|
+
public var _NativeMappedSignalFunctionNoArgsTest:NativeMappedSignalFunctionNoArgsTest;
|
23
|
+
public var _NativeMappedSignalFunctionArgTest:NativeMappedSignalFunctionArgTest;
|
24
|
+
public var _NativeMappedSignalBoundaryUseTest:NativeMappedSignalBoundaryUseTest;
|
25
|
+
public var _PriorityListenersTest:PriorityListenersTest;
|
26
|
+
public var _RedispatchedEventTest:RedispatchedEventTest;
|
27
|
+
public var _DeluxeSignalAmbiguousRelationshipTest:DeluxeSignalAmbiguousRelationshipTest;
|
28
|
+
public var _DeluxeSignalTest:DeluxeSignalTest;
|
29
|
+
public var _DeluxeSignalDispatchExtraArgsTest:DeluxeSignalDispatchExtraArgsTest;
|
30
|
+
public var _DeluxeSignalDispatchNoArgsTest:DeluxeSignalDispatchNoArgsTest;
|
31
|
+
public var _DeluxeSignalDispatchNonEventTest:DeluxeSignalDispatchNonEventTest;
|
32
|
+
public var _DeluxeSignalSplitInterfacesTest:DeluxeSignalSplitInterfacesTest;
|
33
|
+
public var _DeluxeSignalWithBubblingEventTest:DeluxeSignalWithBubblingEventTest;
|
34
|
+
public var _DeluxeSignalWithCustomEventTest:DeluxeSignalWithCustomEventTest;
|
35
|
+
public var _DeluxeSignalWithGenericEventTest:DeluxeSignalWithGenericEventTest;
|
36
|
+
|
37
|
+
public var _SignalDispatchExtraArgsTest:SignalDispatchArgsTest;
|
38
|
+
public var _SignalDispatchNoArgsTest:SignalDispatchNoArgsTest;
|
39
|
+
public var _SignalDispatchNonEventTest:SignalDispatchNonEventTest;
|
40
|
+
public var _SignalSplitInterfacesTest:SignalSplitInterfacesTest;
|
41
|
+
public var _SignalTest:SignalTest;
|
42
|
+
public var _SignalWithCustomEventTest:SignalWithCustomEventTest;
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
package org.osflash.signals
|
2
|
+
{
|
3
|
+
import asunit.core.TextCore;
|
4
|
+
|
5
|
+
import flash.display.MovieClip;
|
6
|
+
|
7
|
+
[SWF(width='1000', height='800', backgroundColor='#333333', frameRate='31')]
|
8
|
+
public class AllTestsRunner extends MovieClip
|
9
|
+
{
|
10
|
+
private var core:TextCore;
|
11
|
+
|
12
|
+
public function AllTestsRunner()
|
13
|
+
{
|
14
|
+
core = new TextCore();
|
15
|
+
core.start(AllTests, null, this);
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
package org.osflash.signals
|
2
|
+
{
|
3
|
+
import asunit.asserts.*;
|
4
|
+
|
5
|
+
public class AmbiguousRelationshipTest
|
6
|
+
{
|
7
|
+
private var target:Object;
|
8
|
+
|
9
|
+
private var instance:Signal;
|
10
|
+
|
11
|
+
[Before]
|
12
|
+
public function setUp():void
|
13
|
+
{
|
14
|
+
target = {};
|
15
|
+
instance = new Signal();
|
16
|
+
}
|
17
|
+
|
18
|
+
[After]
|
19
|
+
public function tearDown():void
|
20
|
+
{
|
21
|
+
instance = null;
|
22
|
+
}
|
23
|
+
|
24
|
+
[Test(expects="flash.errors.IllegalOperationError")]
|
25
|
+
public function add_then_addOnce_throws_error():void
|
26
|
+
{
|
27
|
+
instance.add(failIfCalled);
|
28
|
+
instance.addOnce(failIfCalled);
|
29
|
+
}
|
30
|
+
|
31
|
+
[Test(expects="flash.errors.IllegalOperationError")]
|
32
|
+
public function addOnce_then_add_should_throw_error():void
|
33
|
+
{
|
34
|
+
instance.addOnce(failIfCalled);
|
35
|
+
instance.add(failIfCalled);
|
36
|
+
}
|
37
|
+
|
38
|
+
[Test]
|
39
|
+
public function add_then_add_should_not_throw_error():void
|
40
|
+
{
|
41
|
+
instance.add(failIfCalled);
|
42
|
+
instance.add(failIfCalled);
|
43
|
+
assertEquals(1, instance.numListeners);
|
44
|
+
}
|
45
|
+
|
46
|
+
[Test]
|
47
|
+
public function addOnce_then_addOnce_should_not_throw_error():void
|
48
|
+
{
|
49
|
+
instance.addOnce(failIfCalled);
|
50
|
+
instance.addOnce(failIfCalled);
|
51
|
+
assertEquals(1, instance.numListeners);
|
52
|
+
}
|
53
|
+
|
54
|
+
private function failIfCalled():void
|
55
|
+
{
|
56
|
+
fail("if this listener is called, something horrible is going on");
|
57
|
+
}
|
58
|
+
|
59
|
+
}
|
60
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
package org.osflash.signals
|
2
|
+
{
|
3
|
+
import asunit.asserts.*;
|
4
|
+
|
5
|
+
public class DeluxeSignalAmbiguousRelationshipTest
|
6
|
+
{
|
7
|
+
private var target:Object;
|
8
|
+
|
9
|
+
private var instance:DeluxeSignal;
|
10
|
+
|
11
|
+
[Before]
|
12
|
+
public function setUp():void
|
13
|
+
{
|
14
|
+
target = {};
|
15
|
+
instance = new DeluxeSignal(target);
|
16
|
+
}
|
17
|
+
|
18
|
+
[After]
|
19
|
+
public function tearDown():void
|
20
|
+
{
|
21
|
+
instance = null;
|
22
|
+
}
|
23
|
+
|
24
|
+
[Test(expects="flash.errors.IllegalOperationError")]
|
25
|
+
public function add_then_addOnce_throws_error():void
|
26
|
+
{
|
27
|
+
instance.add(failIfCalled);
|
28
|
+
instance.addOnce(failIfCalled);
|
29
|
+
}
|
30
|
+
|
31
|
+
[Test(expects="flash.errors.IllegalOperationError")]
|
32
|
+
public function addOnce_then_add_should_throw_error():void
|
33
|
+
{
|
34
|
+
instance.addOnce(failIfCalled);
|
35
|
+
instance.add(failIfCalled);
|
36
|
+
}
|
37
|
+
|
38
|
+
[Test]
|
39
|
+
public function add_then_add_should_not_throw_error():void
|
40
|
+
{
|
41
|
+
instance.add(failIfCalled);
|
42
|
+
instance.add(failIfCalled);
|
43
|
+
assertEquals(1, instance.numListeners);
|
44
|
+
}
|
45
|
+
|
46
|
+
[Test]
|
47
|
+
public function addOnce_then_addOnce_should_not_throw_error():void
|
48
|
+
{
|
49
|
+
instance.addOnce(failIfCalled);
|
50
|
+
instance.addOnce(failIfCalled);
|
51
|
+
assertEquals(1, instance.numListeners);
|
52
|
+
}
|
53
|
+
|
54
|
+
private function failIfCalled():void
|
55
|
+
{
|
56
|
+
fail("if this listener is called, something horrible is going on");
|
57
|
+
}
|
58
|
+
|
59
|
+
}
|
60
|
+
}
|