as3signals 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|