├── .gitignore
├── CHANGELOG.textile
├── MIT-LICENSE.txt
├── README.textile
├── TODO.textile
├── as3-signals.as3proj
├── build.properties
├── build.xml
├── libs
├── asunit4-alpha.swc
├── flexUnitTasks.jar
└── hamcrest-as3.swc
├── performance-test
└── org
│ └── osflash
│ └── signals
│ ├── AddOncePerformance.as
│ ├── DispatchPerformance.as
│ ├── MassDispatchPerformance.as
│ └── RemovePerformance.as
├── src
└── org
│ └── osflash
│ └── signals
│ ├── DeluxeSignal.as
│ ├── IOnceSignal.as
│ ├── IPrioritySignal.as
│ ├── ISignal.as
│ ├── ISlot.as
│ ├── MonoSignal.as
│ ├── OnceSignal.as
│ ├── PrioritySignal.as
│ ├── Promise.as
│ ├── Signal.as
│ ├── Slot.as
│ ├── SlotList.as
│ ├── events
│ ├── GenericEvent.as
│ ├── IBubbleEventHandler.as
│ └── IEvent.as
│ └── natives
│ ├── INativeDispatcher.as
│ ├── NativeMappedSignal.as
│ ├── NativeRelaySignal.as
│ ├── NativeSignal.as
│ ├── base
│ ├── SignalBitmap.as
│ ├── SignalMovieClip.as
│ ├── SignalShape.as
│ ├── SignalSocket.as
│ ├── SignalSprite.as
│ ├── SignalTextField.as
│ ├── SignalTimer.as
│ ├── SignalURLLoader.as
│ └── SignalXMLSocket.as
│ └── sets
│ ├── DisplayObjectSignalSet.as
│ ├── EventDispatcherSignalSet.as
│ ├── FileReferenceListSignalSet.as
│ ├── FileReferenceSignalSet.as
│ ├── InteractiveObjectSignalSet.as
│ ├── LoaderInfoSignalSet.as
│ ├── MicrophoneSignalSet.as
│ ├── NativeSignalSet.as
│ ├── NetConnectionSignalSet.as
│ ├── NetStreamSignalSet.as
│ ├── SharedObjectSignalSet.as
│ ├── SocketSignalSet.as
│ ├── SoundChannelSignalSet.as
│ ├── SoundSignalSet.as
│ ├── StageSignalSet.as
│ ├── TextFieldSignalSet.as
│ ├── TimerSignalSet.as
│ ├── URLLoaderSignalSet.as
│ ├── URLStreamSignalSet.as
│ └── XMLSocketSignalSet.as
└── tests
└── org
└── osflash
└── signals
├── AllTests.as
├── AllTestsCIRunner.as
├── AllTestsRunner.as
├── AmbiguousRelationshipTest.as
├── DeluxeSignalWithBubblingEventTest.as
├── DeluxeSignalWithGenericEventTest.as
├── GenericEventTest.as
├── ISignalTestBase.as
├── ISlotTestBase.as
├── MXMLDeluxeSignalTest.as
├── MXMLSignalTest.as
├── MonoSignalDispatchArgsTest.as
├── MonoSignalDispatchExtraArgsTest.as
├── MonoSignalDispatchNoArgsTest.as
├── MonoSignalDispatchNonEventTest.as
├── MonoSignalDispatchVarArgsTest.as
├── MonoSignalSlotTest.as
├── MonoSignalTest.as
├── PriorityListenersTest.as
├── PrioritySignalTest.as
├── PrioritySignalTestSuite.as
├── PrioritySignalTestsRunner.as
├── PromiseTest.as
├── RedispatchedEventTest.as
├── SignalDispatchArgsTest.as
├── SignalDispatchExtraArgsTest.as
├── SignalDispatchNoArgsTest.as
├── SignalDispatchNonEventTest.as
├── SignalDispatchVarArgsTest.as
├── SignalTest.as
├── SignalWithCustomEventTest.as
├── SlotListTest.as
├── SlotTest.as
├── natives
├── AmbiguousRelationshipInNativeSignalTest.as
├── INativeDispatcherTestBase.as
├── MXMLNativeSignalTest.as
├── NativeMappedSignalBoundaryUseTest.as
├── NativeMappedSignalDefaultsTest.as
├── NativeMappedSignalFunctionArgTest.as
├── NativeMappedSignalFunctionNoArgsTest.as
├── NativeMappedSignalObjectArgTest.as
├── NativeRelaySignalTest.as
├── NativeSignalSlotTest.as
├── NativeSignalTest.as
├── base
│ └── SignalSpriteTest.as
└── sets
│ ├── DisplayObjectSignalSetTest.as
│ ├── EventDispatcherSignalSetTest.as
│ └── NativeSignalSetTest.as
└── support
├── SpriteWithDeluxeSignals.mxml
├── SpriteWithNativeSignals.mxml
└── SpriteWithSignals.mxml
/.gitignore:
--------------------------------------------------------------------------------
1 | html-template/*
2 | bin-debug/*
3 | bin-release/*
4 | bin/*
5 | doc/*
6 | docs/*
7 | obj/*
8 | dist/*
9 | report/*
10 | out/*
11 | target/*
12 |
13 | .idea/dictionaries/*
14 | .idea/uiDesigner.xml
15 | .idea/workspace.xml
16 |
17 | .settings/*
18 | .actionScriptProperties
19 | .flexProperties
20 | .flexLibProperties
21 | .FlexUnitSettings
22 | .project
23 |
24 | Icon
25 | Thumbs.db
26 | .DS_Store
27 |
--------------------------------------------------------------------------------
/CHANGELOG.textile:
--------------------------------------------------------------------------------
1 | h2. AS3 Signals Changelog:
2 |
3 | h3. v0.9 - NeufGun
4 |
5 | h4. API Additions
6 | * ISlot: listener registration object with many features.
7 | ** A slot stores values of *once* and *priority*, replacing the untyped "listener box" objects.
8 | ** A slot can *remove()* its listener from the signal.
9 | ** Has *enabled* toggle to temporarily disconnect the listener without removing it.
10 | ** The slot's *listener* can be changed on the fly.
11 | ** Has optional array of *params* which are appended to the signal's dispatched values before reaching the listener. Similar to delegates that store extra args.
12 | * IOnceSignal: has *addOnce()* but not *add()*. Useful for completion signals that discard all listeners on dispatch. Idea by @alecmce.
13 | * MonoSignal: can have only one listener. Useful for callbacks and SignalCommandMap request signals. Originally implemented as SingleSignal by @stickupkid.
14 | * PrioritySignal: like DeluxeSignal without bubbling (thanks @neilmanuell).
15 | * Native Signal Sets:
16 | ** @jonopus developed an easy way to snap on NativeSignals to Sprite, Timer, etc. See *org.osflash.signals.natives.sets* package.
17 | ** Created SignalSprite, SignalTimer, etc. as example base classes. See *org.osflash.signals.natives.base* package.
18 |
19 | h4. API Changes
20 | * Removed ISignalOwner, INativeSignalOwner and IDispatcher. They became annoying, e.g. casting ISignal to Signal just to dispatch. Moved their methods into ISignal.
21 | * *add()*, *addOnce()* and *remove()* now return ISlot.
22 |
23 | h4. Implementation Changes
24 | * add() no longer checks listener.length because ...varargs listeners cannot be detected.
25 | * Dispatching
26 | ** @joa created a new, faster dispatching engine (SlotList) using an immutable recursive linked list (inspired by Scala). The list is like a snake which gets eaten by a snake, which gets eaten by a larger snake, and so on.
27 | ** NOTE: Listeners are now called in reverse order, for best performance. If precise order is needed, use an IPrioritySignal.
28 | * Enhanced MXML friendliness (ArrayElementType, better examples).
29 | * More inheritance between signals to reduce code duplication.
30 |
31 | h4. Fixes
32 | * DeluxeSignal: now handles subclass super() calls properly (thanks @stickupkid).
33 | * NativeRelaySignal: better checks for null (thanks @stickupkid).
34 |
35 | h4. Tests
36 | * Increased test coverage significantly. Many tests from @stickupkid.
37 | * Refactored duplicated test code into base classes, e.g. ISignalTestBase. This greatly increased coverage across various implementations.
38 |
39 | h4. Build
40 | * Build now has a "package" target to zip SWC and source together.
41 | * Build now has a "clean" target to remove generated folders.
42 | * Flash Player executes on Linux (thanks @joa).
43 |
44 | h3. v0.8 - Maximilian - 2010-11-14
45 |
46 | h4. API Changes
47 | * Signals are now MXML-friendly! Example:
48 |
49 |
51 | ** Constructors are now nullable.
52 | ** valueClasses and eventClass are now writable.
53 | ** Exceptions: NativeMappedSignal and NativeRelaySignal are not yet MXML-friendly.
54 | * Renamed IDeluxeSignal to IPrioritySignal, a more functional name.
55 | * New interfaces to grant access to methods that affect all listeners:
56 | ** ISignalOwner: extends ISignal, IDispatcher, adds removeAll().
57 | ** INativeSignalOwner: extends IPrioritySignal, INativeDispatcher, adds removeAll().
58 | ** These 2 interfaces cannot be merged because dispatch(event:Event) conflicts with dispatch(...valueObjects).
59 | ** Thanks to "Brian Heylin":http://github.com/brianheylin for getting the ball rolling.
60 |
61 | h4. Fixes
62 | * "#24 - Changing NativeSignal.target wasn't removing listeners from target.":http://github.com/robertpenner/as3-signals/issues/closed#issue/24
63 | * "#32 - FIX: Setting NativeSignal.eventClass to null and dispatching causes null exception.":http://github.com/robertpenner/as3-signals/issues/closed#issue/32
64 |
65 | h4. Build
66 | * Added continuous integration and unit test execution Ant targets: "ci" and "test".
67 | * Updated AsUnit 4 SWC: test failure call stack is more concise and readable.
68 | * Removed build-asunit.xml as its functionality has been merged into build.xml.
69 |
70 |
71 | h3. v0.7 - Bubblap - 2010-05-27
72 |
73 | h4. API Changes
74 | * Added NativeMappedSignal class from "Brian Heylin":http://github.com/brianheylin, with great "test coverage":http://github.com/brianheylin/as3-signals/tree/master/tests/org/osflash/signals/natives/.
75 | ** Addresses "#16 - Add ability to map native events to signals":http://github.com/robertpenner/as3-signals/issues/closed#issue/16
76 | * DeluxeSignal has a simpler way to continue bubbling without re-dispatching the event.
77 | ** IBubbleEventHandler.onEventBubbled() now returns true/false to continue/cancel bubbling.
78 | ** Thanks to "secoif":http://github.com/secoif for the original code and "dehash":http://www.dehash.com/?p=241h for helping with the merge.
79 | * ISignal and IDeluxeSignal: add(), addOnce() and remove() now return the listener.
80 | ** Thanks to "sammyt":http://github.com/sammyt for the contribution with unit tests.
81 |
82 | h4. Fixes
83 | * Improved error message for Signal.dispatch() with too few arguments.
84 |
85 | h4. Test Changes
86 | * The test suite is migrated to a newer version of AsUnit 4.
87 | ** Tests now receive an IAsync using [Inject]. No more Asyncleton!
88 | ** The migration pattern can be seen in "commit f6878.":http://github.com/robertpenner/as3-signals/commit/f6878dbbff95e0bd7832cc2d1cc2e7d55fb18098
89 | ** AllTestsRunner uses a "new composition pattern":http://github.com/robertpenner/as3-signals/commit/866a99570152b7399aa34839fd5c30789db67f3c instead of inheritance.
90 | ** Many thanks to "Luke Bayes":http://github.com/lukebayes and the "Bay Area Computer Club":http://github.com/bayareacomputerclub.
91 | * Added more tests for argument dispatching and consolidated in SignalDispatchArgsTest.
92 |
93 | h3. v0.6 - GreenDay - 2010-03-17
94 |
95 | h4. API Changes
96 | * "#15 - IDeluxeSignal and NativeSignal now have valueClasses property":http://github.com/robertpenner/as3-signals/issues/closed#issue/15
97 |
98 | h4. Fixes
99 | * "#14 - NativeSignal.addOnce() can't be reused after native event dispatched":http://github.com/robertpenner/as3-signals/issues/closed#issue/14
100 |
101 | h4. Implementation Changes
102 | * Optimized listeners array cloning to use slice(), which is faster than concat().
103 | * Optimized dispatch() by moving the cloning of listeners to add(), addOnce(), and remove().
104 | * Signal.removeAll() now uses remove() on every listener, instead of fast array clearing. This is intended to avoid possible issues with subclass overrides (as happened before with NativeRelaySignal.remove()).
105 | * Renamed createListenerRelationship() to registerListener().
106 | * Consolidated add() and addOnce() logic in registerListener().
107 | * Removed onceListeners Dictionary from DeluxeSignal and NativeSignal.
108 | * DeluxeSignal and NativeSignal are now more unified in their "once listeners" internal implementations.
109 | * Removed an extra semicolon which made FDT cry (thanks "vitch":http://github.com/vitch).
110 |
111 | h4. Test Changes
112 | * Removed async [Test] metadata because AsUnit 4 no longer uses it.
113 | * Updated the AsUnit 4 SWC to newer version which avoids slowdown of Timers in Flash Player 10.1.
114 | * Added tests for ambiguous relationships in Signal.
115 | * Added tests for adding a listener during a dispatch().
116 |
117 | h3. v0.5 - GlassHalfFull - 2010-02-08
118 |
119 | * Added versioning to the Ant build, starting at 0.5.
120 |
--------------------------------------------------------------------------------
/MIT-LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009 Robert Penner
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.textile:
--------------------------------------------------------------------------------
1 | h1. Signals: Think Outside the Event.
2 |
3 | *Signals* are light-weight, strongly-typed AS3 messaging tools.
4 | Wire your application with better APIs and less boilerplate than AS3 Events.
5 |
6 | h2. Concept
7 |
8 | * A *Signal* is essentially a mini-dispatcher specific to one event, with its own array of listeners.
9 | * A Signal gives an event a concrete membership in a class.
10 | * Listeners subscribe to real objects, not to string-based channels.
11 | * Event string constants are no longer needed.
12 | * Signals are inspired by "C# events":http://en.wikipedia.org/wiki/C_Sharp_syntax#Events and "signals/slots":http://en.wikipedia.org/wiki/Signals_and_slots in Qt.
13 |
14 | h2. Syntax
15 |
16 |
// with EventDispatcher
17 | button.addEventListener(MouseEvent.CLICK, onClick);
18 |
19 | // Signal equivalent; past tense is recommended
20 | button.clicked.add(onClicked);
21 |
22 |
23 | I am still looking for impressions, critiques and suggestions.
24 | My email is robert _at_ robertpenner.com.
25 | I'm "@robpenner on Twitter":http://twitter.com/robpenner.
26 |
27 | h2. Background on AS3 Events
28 |
29 | * "My Critique of AS3 Events - Part 1":http://flashblog.robertpenner.com/2009/08/my-critique-of-as3-events-part-1.html
30 | * "AS3 Events - 7 things I've learned from community":http://flashblog.robertpenner.com/2009/09/as3-events-7-things-ive-learned-from.html
31 | * "My Critique of AS3 Events - Part 2":http://flashblog.robertpenner.com/2009/09/my-critique-of-as3-events-part-2.html
32 |
--------------------------------------------------------------------------------
/TODO.textile:
--------------------------------------------------------------------------------
1 | h1. AS3 Signals TODO
2 |
3 | h2. v0.9
4 |
5 | h3. High Priority
6 |
7 | * finish base classes using signal sets, e.g. SignalSprite
8 | * ask community about impact of reversing order of listeners
9 |
10 | h3. Medium Priority
11 |
12 | * fill in asdocs
13 |
14 | h3. Low Priority
15 |
16 | * add MXML support for NativeMappedSignal, NativeRelaySignal
17 |
--------------------------------------------------------------------------------
/as3-signals.as3proj:
--------------------------------------------------------------------------------
1 |
2 | ArgumentError
: Incorrect number of arguments.
59 | * @throws ArgumentError ArgumentError
: Value object is not an instance of the appropriate valueClasses Class.
60 | */
61 | override public function dispatch(...valueObjects):void
62 | {
63 | // Validate value objects against pre-defined value classes.
64 | const numValueClasses:int = _valueClasses.length;
65 | const numValueObjects:int = valueObjects.length;
66 |
67 | if (numValueObjects < numValueClasses)
68 | {
69 | throw new ArgumentError('Incorrect number of arguments. '+
70 | 'Expected at least '+numValueClasses+' but received '+
71 | numValueObjects+'.');
72 | }
73 |
74 | // Cannot dispatch differently typed objects than declared classes.
75 | for (var i:int = 0; i < numValueClasses; i++)
76 | {
77 | // Optimized for the optimistic case that values are correct.
78 | if (valueObjects[i] is _valueClasses[i] || valueObjects[i] === null)
79 | continue;
80 |
81 | throw new ArgumentError('Value object <'+valueObjects[i]
82 | +'> is not an instance of <'+_valueClasses[i]+'>.');
83 | }
84 |
85 | // Extract and clone event object if necessary.
86 | var event:IEvent = valueObjects[0] as IEvent;
87 | if (event)
88 | {
89 | if (event.target)
90 | {
91 | event = event.clone();
92 | valueObjects[0] = event;
93 | }
94 |
95 | event.target = target;
96 | event.currentTarget = target;
97 | event.signal = this;
98 | }
99 |
100 | // Broadcast to listeners.
101 | var slotsToProcess:SlotList = slots;
102 | while (slotsToProcess.nonEmpty)
103 | {
104 | slotsToProcess.head.execute(valueObjects);
105 | slotsToProcess = slotsToProcess.tail;
106 | }
107 |
108 | // Bubble the event as far as possible.
109 | if (!event || !event.bubbles) return;
110 |
111 | var currentTarget:Object = target;
112 |
113 | while (currentTarget && currentTarget.hasOwnProperty("parent"))
114 | {
115 | currentTarget = currentTarget["parent"];
116 | if (!currentTarget) break;
117 |
118 | if (currentTarget is IBubbleEventHandler)
119 | {
120 | // onEventBubbled() can stop the bubbling by returning false.
121 | if (!IBubbleEventHandler(event.currentTarget = currentTarget).onEventBubbled(event))
122 | break;
123 | }
124 | }
125 | }
126 |
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/IOnceSignal.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | /**
4 | *
5 | */
6 | public interface IOnceSignal
7 | {
8 | /**
9 | * An optional array of classes defining the types of parameters sent to listeners.
10 | */
11 | function get valueClasses():Array;
12 | function set valueClasses(value:Array):void;
13 |
14 | /** The current number of listeners for the signal. */
15 | function get numListeners():uint;
16 |
17 | /**
18 | * Subscribes a one-time listener for this signal.
19 | * The signal will remove the listener automatically the first time it is called,
20 | * after the dispatch to all listeners is complete.
21 | * @param listener A function with arguments
22 | * that matches the value classes dispatched by the signal.
23 | * If value classes are not specified (e.g. via Signal constructor), dispatch() can be called without arguments.
24 | * @return a ISlot, which contains the Function passed as the parameter
25 | */
26 | function addOnce(listener:Function):ISlot;
27 |
28 | /**
29 | * Dispatches an object to listeners.
30 | * @param valueObjects Any number of parameters to send to listeners. Will be type-checked against valueClasses.
31 | * @throws ArgumentError ArgumentError
: valueObjects are not compatible with valueClasses.
32 | */
33 | function dispatch(...valueObjects):void;
34 |
35 | /**
36 | * Unsubscribes a listener from the signal.
37 | * @param listener
38 | * @return a ISlot, which contains the Function passed as the parameter
39 | */
40 | function remove(listener:Function):ISlot;
41 |
42 | /**
43 | * Unsubscribes all listeners from the signal.
44 | */
45 | function removeAll():void
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/IPrioritySignal.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | /**
4 | *
5 | */
6 | public interface IPrioritySignal extends ISignal
7 | {
8 | /**
9 | * Subscribes a listener for the signal.
10 | * After you successfully register an event listener,
11 | * you cannot change its priority through additional calls to add().
12 | * To change a listener's priority, you must first call remove().
13 | * Then you can register the listener again with the new priority level.
14 | * @param listener A function with an argument
15 | * that matches the type of event dispatched by the signal.
16 | * If eventClass is not specified, the listener and dispatch() can be called without an argument.
17 | * @return a ISlot, which contains the Function passed as the parameter
18 | * @see ISlot
19 | */
20 | function addWithPriority(listener:Function, priority:int = 0):ISlot
21 |
22 | /**
23 | * Subscribes a one-time listener for this signal.
24 | * The signal will remove the listener automatically the first time it is called,
25 | * after the dispatch to all listeners is complete.
26 | * @param listener A function with an argument
27 | * that matches the type of event dispatched by the signal.
28 | * If eventClass is not specified, the listener and dispatch() can be called without an argument.
29 | * @param priority The priority level of the event listener.
30 | * The priority is designated by a signed 32-bit integer.
31 | * The higher the number, the higher the priority.
32 | * All listeners with priority n are processed before listeners of priority n-1.
33 | * @return a ISlot, which contains the Function passed as the parameter
34 | * @see ISlot
35 | */
36 | function addOnceWithPriority(listener:Function, priority:int = 0):ISlot
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/ISignal.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | /**
4 | *
5 | */
6 | public interface ISignal extends IOnceSignal
7 | {
8 | /**
9 | * Subscribes a listener for the signal.
10 | * @param listener A function with arguments
11 | * that matches the value classes dispatched by the signal.
12 | * If value classes are not specified (e.g. via Signal constructor), dispatch() can be called without arguments.
13 | * @return a ISlot, which contains the Function passed as the parameter
14 | */
15 | function add(listener:Function):ISlot;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/ISlot.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | /**
4 | * The ISlot interface defines the basic properties of a
5 | * listener associated with a Signal.
6 | *
7 | * @author Joa Ebert
8 | * @author Robert Penner
9 | */
10 | public interface ISlot
11 | {
12 | /**
13 | * The listener associated with this slot.
14 | */
15 | function get listener():Function;
16 | function set listener(value:Function):void;
17 |
18 | /**
19 | * Allows the ISlot to inject parameters when dispatching. The params will be at
20 | * the tail of the arguments and the ISignal arguments will be at the head.
21 | *
22 | * var signal:ISignal = new Signal(String);
23 | * signal.add(handler).params = [42];
24 | * signal.dispatch('The Answer');
25 | * function handler(name:String, num:int):void{}
26 | */
27 | function get params():Array;
28 | function set params(value:Array):void;
29 |
30 | /**
31 | * Whether this slot is automatically removed after it has been used once.
32 | */
33 | function get once():Boolean;
34 |
35 | /**
36 | * The priority of this slot should be given in the execution order.
37 | * An IPrioritySignal will call higher numbers before lower ones.
38 | * Defaults to 0.
39 | */
40 | function get priority():int;
41 |
42 | /**
43 | * Whether the listener is called on execution. Defaults to true.
44 | */
45 | function get enabled():Boolean;
46 | function set enabled(value:Boolean):void;
47 |
48 | /**
49 | * Executes a listener without arguments.
50 | * Existing params
are appended before the listener is called.
51 | */
52 | function execute0():void;
53 |
54 | /**
55 | * Dispatches one argument to a listener.
56 | * Existing params
are appended before the listener is called.
57 | * @param value The argument for the listener.
58 | */
59 | function execute1(value:Object):void;
60 |
61 | /**
62 | * Executes a listener of arity n
where n
is
63 | * valueObjects.length
.
64 | * Existing params
are appended before the listener is called.
65 | * @param valueObjects The array of arguments to be applied to the listener.
66 | */
67 | function execute(valueObjects:Array):void;
68 |
69 | /**
70 | * Removes the slot from its signal.
71 | */
72 | function remove():void;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/MonoSignal.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import flash.errors.IllegalOperationError;
4 | import flash.utils.getQualifiedClassName;
5 |
6 | /**
7 | * Allows the valueClasses to be set in MXML, e.g.
8 | * ArgumentError
: Invalid valueClasses argument: item at index should be a Class but was not.
41 | */
42 | [ArrayElementType("Class")]
43 | public function get valueClasses():Array { return _valueClasses; }
44 |
45 | public function set valueClasses(value:Array):void
46 | {
47 | // Clone so the Array cannot be affected from outside.
48 | _valueClasses = value ? value.slice() : [];
49 | for (var i:int = _valueClasses.length; i--; )
50 | {
51 | if (!(_valueClasses[i] is Class))
52 | {
53 | throw new ArgumentError('Invalid valueClasses argument: ' +
54 | 'item at index ' + i + ' should be a Class but was:<' +
55 | _valueClasses[i] + '>.' + getQualifiedClassName(_valueClasses[i]));
56 | }
57 | }
58 | }
59 |
60 | /** @inheritDoc */
61 | public function get numListeners():uint { return slot ? 1 : 0; }
62 |
63 | /**
64 | * @inheritDoc
65 | * @throws flash.errors.IllegalOperationError IllegalOperationError
: You cannot add or addOnce with a listener already added, remove the current listener first.
66 | * @throws ArgumentError ArgumentError
: Given listener is null
.
67 | */
68 | public function add(listener:Function):ISlot
69 | {
70 | return registerListener(listener);
71 | }
72 |
73 | /**
74 | * @inheritDoc
75 | * @throws flash.errors.IllegalOperationError IllegalOperationError
: You cannot add or addOnce with a listener already added, remove the current listener first.
76 | * @throws ArgumentError ArgumentError
: Given listener is null
.
77 | */
78 | public function addOnce(listener:Function):ISlot
79 | {
80 | return registerListener(listener, true);
81 | }
82 |
83 | /** @inheritDoc */
84 | public function remove(listener:Function):ISlot
85 | {
86 | if (slot && slot.listener == listener)
87 | {
88 | const theSlot:ISlot = slot;
89 | slot = null;
90 | return theSlot;
91 | }
92 |
93 | return null;
94 | }
95 |
96 | /** @inheritDoc */
97 | public function removeAll():void
98 | {
99 | if (slot) slot.remove();
100 | }
101 |
102 | /**
103 | * @inheritDoc
104 | * @throws ArgumentError ArgumentError
: Incorrect number of arguments.
105 | * @throws ArgumentError ArgumentError
: Value object is not an instance of the appropriate valueClasses Class.
106 | */
107 | public function dispatch(...valueObjects):void
108 | {
109 | // If valueClasses is empty, value objects are not type-checked.
110 | const numValueClasses:int = _valueClasses.length;
111 | const numValueObjects:int = valueObjects.length;
112 |
113 | // Cannot dispatch fewer objects than declared classes.
114 | if (numValueObjects < numValueClasses)
115 | {
116 | throw new ArgumentError('Incorrect number of arguments. '+
117 | 'Expected at least '+numValueClasses+' but received '+
118 | numValueObjects+'.');
119 | }
120 |
121 | // Cannot dispatch differently typed objects than declared classes.
122 | for (var i:int = 0; i < numValueClasses; i++)
123 | {
124 | // Optimized for the optimistic case that values are correct.
125 | if (valueObjects[i] is _valueClasses[i] || valueObjects[i] === null)
126 | continue;
127 |
128 | throw new ArgumentError('Value object <'+valueObjects[i]
129 | +'> is not an instance of <'+_valueClasses[i]+'>.');
130 | }
131 |
132 | // Broadcast to the one listener.
133 | if (slot)
134 | {
135 | slot.execute(valueObjects);
136 | }
137 | }
138 |
139 | protected function registerListener(listener:Function, once:Boolean = false):ISlot
140 | {
141 | if (slot)
142 | {
143 | // If the listener exits previously added, definitely don't add it.
144 | throw new IllegalOperationError('You cannot add or addOnce with a listener already added, remove the current listener first.');
145 | }
146 |
147 | return (slot = new Slot(listener, this, once));
148 | }
149 |
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/OnceSignal.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import flash.errors.IllegalOperationError;
4 | import flash.utils.getQualifiedClassName;
5 |
6 | /**
7 | * Allows the valueClasses to be set in MXML, e.g.
8 | * ArgumentError
: Invalid valueClasses argument: item at index should be a Class but was not.
47 | */
48 | [ArrayElementType("Class")]
49 | public function get valueClasses():Array { return _valueClasses; }
50 |
51 | public function set valueClasses(value:Array):void
52 | {
53 | // Clone so the Array cannot be affected from outside.
54 | _valueClasses = value ? value.slice() : [];
55 | for (var i:int = _valueClasses.length; i--; )
56 | {
57 | if (!(_valueClasses[i] is Class))
58 | {
59 | throw new ArgumentError('Invalid valueClasses argument: ' +
60 | 'item at index ' + i + ' should be a Class but was:<' +
61 | _valueClasses[i] + '>.' + getQualifiedClassName(_valueClasses[i]));
62 | }
63 | }
64 | }
65 |
66 | /** @inheritDoc */
67 | public function get numListeners():uint { return slots.length; }
68 |
69 | /**
70 | * @inheritDoc
71 | * @throws flash.errors.IllegalOperationError IllegalOperationError
: You cannot addOnce() then add() the same listener without removing the relationship first.
72 | * @throws ArgumentError ArgumentError
: Given listener is null
.
73 | */
74 | public function addOnce(listener:Function):ISlot
75 | {
76 | return registerListener(listener, true);
77 | }
78 |
79 | /** @inheritDoc */
80 | public function remove(listener:Function):ISlot
81 | {
82 | const slot:ISlot = slots.find(listener);
83 | if (!slot) return null;
84 |
85 | slots = slots.filterNot(listener);
86 | return slot;
87 | }
88 |
89 | /** @inheritDoc */
90 | public function removeAll():void
91 | {
92 | slots = SlotList.NIL;
93 | }
94 |
95 | /**
96 | * @inheritDoc
97 | * @throws ArgumentError ArgumentError
: Incorrect number of arguments.
98 | * @throws ArgumentError ArgumentError
: Value object is not an instance of the appropriate valueClasses Class.
99 | */
100 | public function dispatch(...valueObjects):void
101 | {
102 |
103 | // If valueClasses is empty, value objects are not type-checked.
104 | const numValueClasses:int = _valueClasses.length;
105 | const numValueObjects:int = valueObjects.length;
106 |
107 | // Cannot dispatch fewer objects than declared classes.
108 | if (numValueObjects < numValueClasses)
109 | {
110 | throw new ArgumentError('Incorrect number of arguments. '+
111 | 'Expected at least '+numValueClasses+' but received '+
112 | numValueObjects+'.');
113 | }
114 |
115 | // Cannot dispatch differently typed objects than declared classes.
116 | for (var i:int = 0; i < numValueClasses; i++)
117 | {
118 | // Optimized for the optimistic case that values are correct.
119 | if (valueObjects[i] is _valueClasses[i] || valueObjects[i] === null)
120 | continue;
121 |
122 | throw new ArgumentError('Value object <'+valueObjects[i]
123 | +'> is not an instance of <'+_valueClasses[i]+'>.');
124 | }
125 |
126 | // Broadcast to listeners.
127 | var slotsToProcess:SlotList = slots;
128 | if(slotsToProcess.nonEmpty)
129 | {
130 | while (slotsToProcess.nonEmpty)
131 | {
132 | slotsToProcess.head.execute(valueObjects);
133 | slotsToProcess = slotsToProcess.tail;
134 | }
135 | }
136 | }
137 |
138 | protected function registerListener(listener:Function, once:Boolean = false):ISlot
139 | {
140 | if (registrationPossible(listener, once))
141 | {
142 | const newSlot:ISlot = new Slot(listener, this, once);
143 | slots = slots.prepend(newSlot);
144 | return newSlot;
145 | }
146 |
147 | return slots.find(listener);
148 | }
149 |
150 | protected function registrationPossible(listener:Function, once:Boolean):Boolean
151 | {
152 | if (!slots.nonEmpty) return true;
153 |
154 | const existingSlot:ISlot = slots.find(listener);
155 | if (!existingSlot) return true;
156 |
157 | if (existingSlot.once != once)
158 | {
159 | // If the listener was previously added, definitely don't add it again.
160 | // But throw an exception if their once values differ.
161 | throw new IllegalOperationError('You cannot addOnce() then add() the same listener without removing the relationship first.');
162 | }
163 |
164 | return false; // Listener was already registered.
165 | }
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/PrioritySignal.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | public class PrioritySignal extends Signal implements IPrioritySignal
4 | {
5 |
6 | public function PrioritySignal(...valueClasses)
7 | {
8 | // Cannot use super.apply(null, valueClasses), so allow the subclass to call super(valueClasses).
9 | valueClasses = (valueClasses.length == 1 && valueClasses[0] is Array) ? valueClasses[0] : valueClasses;
10 |
11 | super(valueClasses);
12 | }
13 |
14 | /**
15 | * @inheritDoc
16 | * @throws flash.errors.IllegalOperationError IllegalOperationError
: You cannot addOnce() then add() the same listener without removing the relationship first.
17 | * @throws ArgumentError ArgumentError
: Given listener is null
.
18 | */
19 | public function addWithPriority(listener:Function, priority:int = 0):ISlot
20 | {
21 | return registerListenerWithPriority(listener, false, priority);
22 | }
23 |
24 | /**
25 | * @inheritDoc
26 | * @throws flash.errors.IllegalOperationError IllegalOperationError
: You cannot addOnce() then add() the same listener without removing the relationship first.
27 | * @throws ArgumentError ArgumentError
: Given listener is null
.
28 | */
29 | public function addOnceWithPriority(listener:Function, priority:int = 0):ISlot
30 | {
31 | return registerListenerWithPriority(listener, true, priority);
32 | }
33 |
34 | override protected function registerListener(listener:Function, once:Boolean = false):ISlot
35 | {
36 | return registerListenerWithPriority(listener, once);
37 | }
38 |
39 | protected function registerListenerWithPriority(listener:Function, once:Boolean = false, priority:int = 0):ISlot
40 | {
41 | if (registrationPossible(listener, once))
42 | {
43 | const slot:ISlot = new Slot(listener, this, once, priority);
44 | slots = slots.insertWithPriority(slot);
45 | return slot;
46 | }
47 |
48 | return slots.find(listener);
49 | }
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/Promise.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import flash.errors.IllegalOperationError;
4 |
5 | import org.osflash.signals.ISlot;
6 | import org.osflash.signals.OnceSignal;
7 |
8 | public class Promise extends OnceSignal
9 | {
10 | private var isDispatched:Boolean;
11 | private var valueObjects:Array;
12 |
13 | /** @inheritDoc */
14 | override public function addOnce(listener:Function):ISlot
15 | {
16 | var slot:ISlot = super.addOnce(listener);
17 | if (isDispatched)
18 | {
19 | slot.execute(valueObjects);
20 | slot.remove();
21 | }
22 |
23 | return slot;
24 | }
25 |
26 | /**
27 | * @inheritDoc
28 | * @throws flash.errors.IllegalOperationError IllegalOperationError
: You cannot dispatch() a Promise more than once
29 | */
30 | override public function dispatch(...valueObjects):void
31 | {
32 | if (isDispatched)
33 | {
34 | throw new IllegalOperationError("You cannot dispatch() a Promise more than once");
35 | }
36 | else
37 | {
38 | isDispatched = true;
39 | this.valueObjects = valueObjects;
40 | super.dispatch.apply(this, valueObjects);
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/Signal.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 |
4 | /**
5 | * Allows the valueClasses to be set in MXML, e.g.
6 | * IllegalOperationError
: You cannot addOnce() then add() the same listener without removing the relationship first.
44 | * @throws ArgumentError ArgumentError
: Given listener is null
.
45 | */
46 | public function add(listener:Function):ISlot
47 | {
48 | return registerListener(listener);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/Slot.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | /**
4 | * The Slot class represents a signal slot.
5 | *
6 | * @author Robert Penner
7 | * @author Joa Ebert
8 | */
9 | public class Slot implements ISlot
10 | {
11 | protected var _signal:IOnceSignal;
12 | protected var _enabled:Boolean = true;
13 | protected var _listener:Function;
14 | protected var _once:Boolean = false;
15 | protected var _priority:int = 0;
16 | protected var _params:Array;
17 |
18 | /**
19 | * Creates and returns a new Slot object.
20 | *
21 | * @param listener The listener associated with the slot.
22 | * @param signal The signal associated with the slot.
23 | * @param once Whether or not the listener should be executed only once.
24 | * @param priority The priority of the slot.
25 | *
26 | * @throws ArgumentError ArgumentError
: Given listener is null
.
27 | * @throws Error Error
: Internal signal reference has not been set yet.
28 | */
29 | public function Slot(listener:Function, signal:IOnceSignal, once:Boolean = false, priority:int = 0)
30 | {
31 | _listener = listener;
32 | _once = once;
33 | _signal = signal;
34 | _priority = priority;
35 |
36 | verifyListener(listener);
37 | }
38 |
39 | /**
40 | * @inheritDoc
41 | */
42 | public function execute0():void
43 | {
44 | if (!_enabled) return;
45 | if (_once) remove();
46 | if (_params && _params.length)
47 | {
48 | _listener.apply(null, _params);
49 | return;
50 | }
51 | _listener();
52 | }
53 |
54 | /**
55 | * @inheritDoc
56 | */
57 | public function execute1(value:Object):void
58 | {
59 | if (!_enabled) return;
60 | if (_once) remove();
61 | if (_params && _params.length)
62 | {
63 | _listener.apply(null, [value].concat(_params));
64 | return;
65 | }
66 | _listener(value);
67 | }
68 |
69 | /**
70 | * @inheritDoc
71 | */
72 | public function execute(valueObjects:Array):void
73 | {
74 | if (!_enabled) return;
75 | if (_once) remove();
76 |
77 | // If we have parameters, add them to the valueObject
78 | // Note: This could be expensive if we're after the fastest dispatch possible.
79 | if (_params && _params.length)
80 | {
81 | valueObjects = valueObjects.concat(_params);
82 | }
83 |
84 | // NOTE: simple ifs are faster than switch: http://jacksondunstan.com/articles/1007
85 | const numValueObjects:int = valueObjects.length;
86 | if (numValueObjects == 0)
87 | {
88 | _listener();
89 | }
90 | else if (numValueObjects == 1)
91 | {
92 | _listener(valueObjects[0]);
93 | }
94 | else if (numValueObjects == 2)
95 | {
96 | _listener(valueObjects[0], valueObjects[1]);
97 | }
98 | else if (numValueObjects == 3)
99 | {
100 | _listener(valueObjects[0], valueObjects[1], valueObjects[2]);
101 | }
102 | else
103 | {
104 | _listener.apply(null, valueObjects);
105 | }
106 | }
107 |
108 | /**
109 | * @inheritDoc
110 | * @throws ArgumentError ArgumentError
: Given listener is null
. Did you want to set enabled to false instead?
111 | * @throws Error Error
: Internal signal reference has not been set yet.
112 | */
113 | public function get listener():Function
114 | {
115 | return _listener;
116 | }
117 |
118 | public function set listener(value:Function):void
119 | {
120 | if (null == value) throw new ArgumentError(
121 | 'Given listener is null.\nDid you want to set enabled to false instead?');
122 |
123 | verifyListener(value);
124 | _listener = value;
125 | }
126 |
127 | /**
128 | * @inheritDoc
129 | */
130 | public function get once():Boolean { return _once; }
131 |
132 | /**
133 | * @inheritDoc
134 | */
135 | public function get priority():int { return _priority; }
136 |
137 | /**
138 | * Creates and returns the string representation of the current object.
139 | *
140 | * @return The string representation of the current object.
141 | */
142 | public function toString():String
143 | {
144 | return "[Slot listener: "+_listener+", once: "+_once
145 | +", priority: "+_priority+", enabled: "+_enabled+"]";
146 | }
147 |
148 | /**
149 | * @inheritDoc
150 | */
151 | public function get enabled():Boolean { return _enabled; }
152 |
153 | public function set enabled(value:Boolean):void { _enabled = value; }
154 |
155 | /**
156 | * @inheritDoc
157 | */
158 | public function get params():Array { return _params; }
159 |
160 | public function set params(value:Array):void { _params = value; }
161 |
162 | /**
163 | * @inheritDoc
164 | */
165 | public function remove():void
166 | {
167 | _signal.remove(_listener);
168 | }
169 |
170 | protected function verifyListener(listener:Function): void
171 | {
172 | if (null == listener)
173 | {
174 | throw new ArgumentError('Given listener is null.');
175 | }
176 |
177 | if (null == _signal)
178 | {
179 | throw new Error('Internal signal reference has not been set yet.');
180 | }
181 |
182 | }
183 | }
184 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/SlotList.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | /**
4 | * The SlotList class represents an immutable list of Slot objects.
5 | *
6 | * @author Joa Ebert
7 | * @author Robert Penner
8 | */
9 | public final class SlotList
10 | {
11 | /**
12 | * Represents an empty list. Used as the list terminator.
13 | */
14 | public static const NIL:SlotList = new SlotList(null, null);
15 |
16 | /**
17 | * Creates and returns a new SlotList object.
18 | *
19 | * A user never has to create a SlotList manually.
20 | * Use the NIL
element to represent an empty list.
21 | * NIL.prepend(value)
would create a list containing value
ArgumentError
: Parameters head and tail are null. Use the NIL element instead.
27 | * @throws ArgumentError ArgumentError
: Parameter head cannot be null.
28 | */
29 | public function SlotList(head:ISlot, tail:SlotList = null)
30 | {
31 | if (!head && !tail)
32 | {
33 | if (NIL)
34 | throw new ArgumentError('Parameters head and tail are null. Use the NIL element instead.');
35 |
36 | //this is the NIL element as per definition
37 | nonEmpty = false;
38 | }
39 | else if (!head)
40 | {
41 | throw new ArgumentError('Parameter head cannot be null.');
42 | }
43 | else
44 | {
45 | this.head = head;
46 | this.tail = tail || NIL;
47 | nonEmpty = true;
48 | }
49 | }
50 |
51 | // Although those variables are not const, they would be if AS3 would handle it correctly.
52 | public var head:ISlot;
53 | public var tail:SlotList;
54 | public var nonEmpty:Boolean = false;
55 |
56 | /**
57 | * The number of slots in the list.
58 | */
59 | public function get length():uint
60 | {
61 | if (!nonEmpty) return 0;
62 | if (tail == NIL) return 1;
63 |
64 | // We could cache the length, but it would make methods like filterNot unnecessarily complicated.
65 | // Instead we assume that O(n) is okay since the length property is used in rare cases.
66 | // We could also cache the length lazy, but that is a waste of another 8b per list node (at least).
67 |
68 | var result:uint = 0;
69 | var p:SlotList = this;
70 |
71 | while (p.nonEmpty)
72 | {
73 | ++result;
74 | p = p.tail;
75 | }
76 |
77 | return result;
78 | }
79 |
80 | /**
81 | * Prepends a slot to this list.
82 | * @param slot The item to be prepended.
83 | * @return A list consisting of slot followed by all elements of this list.
84 | *
85 | * @throws ArgumentError ArgumentError
: Parameter head cannot be null.
86 | */
87 | public function prepend(slot:ISlot):SlotList
88 | {
89 | return new SlotList(slot, this);
90 | }
91 |
92 | /**
93 | * Appends a slot to this list.
94 | * Note: appending is O(n). Where possible, prepend which is O(1).
95 | * In some cases, many list items must be cloned to
96 | * avoid changing existing lists.
97 | * @param slot The item to be appended.
98 | * @return A list consisting of all elements of this list followed by slot.
99 | */
100 | public function append(slot:ISlot):SlotList
101 | {
102 | if (!slot) return this;
103 | if (!nonEmpty) return new SlotList(slot);
104 | // Special case: just one slot currently in the list.
105 | if (tail == NIL)
106 | return new SlotList(slot).prepend(head);
107 |
108 | // The list already has two or more slots.
109 | // We have to build a new list with cloned items because they are immutable.
110 | const wholeClone:SlotList = new SlotList(head);
111 | var subClone:SlotList = wholeClone;
112 | var current:SlotList = tail;
113 |
114 | while (current.nonEmpty)
115 | {
116 | subClone = subClone.tail = new SlotList(current.head);
117 | current = current.tail;
118 | }
119 | // Append the new slot last.
120 | subClone.tail = new SlotList(slot);
121 | return wholeClone;
122 | }
123 |
124 | /**
125 | * Insert a slot into the list in a position according to its priority.
126 | * The higher the priority, the closer the item will be inserted to the list head.
127 | * @params slot The item to be inserted.
128 | *
129 | * @throws ArgumentError ArgumentError
: Parameters head and tail are null. Use the NIL element instead.
130 | * @throws ArgumentError ArgumentError
: Parameter head cannot be null.
131 | */
132 | public function insertWithPriority(slot:ISlot):SlotList
133 | {
134 | if (!nonEmpty) return new SlotList(slot);
135 |
136 | const priority:int = slot.priority;
137 | // Special case: new slot has the highest priority.
138 | if (priority > this.head.priority) return prepend(slot);
139 |
140 | const wholeClone:SlotList = new SlotList(head);
141 | var subClone:SlotList = wholeClone;
142 | var current:SlotList = tail;
143 |
144 | // Find a slot with lower priority and go in front of it.
145 | while (current.nonEmpty)
146 | {
147 | if (priority > current.head.priority)
148 | {
149 | subClone.tail = current.prepend(slot);
150 | return wholeClone;
151 | }
152 | subClone = subClone.tail = new SlotList(current.head);
153 | current = current.tail;
154 | }
155 |
156 | // Slot has lowest priority.
157 | subClone.tail = new SlotList(slot);
158 | return wholeClone;
159 | }
160 |
161 | /**
162 | * Returns the slots in this list that do not contain the supplied listener.
163 | * Note: assumes the listener is not repeated within the list.
164 | * @param listener The function to remove.
165 | * @return A list consisting of all elements of this list that do not have listener.
166 | */
167 | public function filterNot(listener:Function):SlotList
168 | {
169 | if (!nonEmpty || listener == null) return this;
170 |
171 | if (listener == head.listener) return tail;
172 |
173 | // The first item wasn't a match so the filtered list will contain it.
174 | const wholeClone:SlotList = new SlotList(head);
175 | var subClone:SlotList = wholeClone;
176 | var current:SlotList = tail;
177 |
178 | while (current.nonEmpty)
179 | {
180 | if (current.head.listener == listener)
181 | {
182 | // Splice out the current head.
183 | subClone.tail = current.tail;
184 | return wholeClone;
185 | }
186 |
187 | subClone = subClone.tail = new SlotList(current.head);
188 | current = current.tail;
189 | }
190 |
191 | // The listener was not found so this list is unchanged.
192 | return this;
193 | }
194 |
195 | /**
196 | * Determines whether the supplied listener Function is contained within this list
197 | */
198 | public function contains(listener:Function):Boolean
199 | {
200 | if (!nonEmpty) return false;
201 |
202 | var p:SlotList = this;
203 | while (p.nonEmpty)
204 | {
205 | if (p.head.listener == listener) return true;
206 | p = p.tail;
207 | }
208 |
209 | return false;
210 | }
211 |
212 | /**
213 | * Retrieves the ISlot associated with a supplied listener within the SlotList.
214 | * @param listener The Function being searched for
215 | * @return The ISlot in this list associated with the listener parameter through the ISlot.listener property.
216 | * Returns null if no such ISlot instance exists or the list is empty.
217 | */
218 | public function find(listener:Function):ISlot
219 | {
220 | if (!nonEmpty) return null;
221 |
222 | var p:SlotList = this;
223 | while (p.nonEmpty)
224 | {
225 | if (p.head.listener == listener) return p.head;
226 | p = p.tail;
227 | }
228 |
229 | return null;
230 | }
231 |
232 | public function toString():String
233 | {
234 | var buffer:String = '';
235 | var p:SlotList = this;
236 |
237 | while (p.nonEmpty)
238 | {
239 | buffer += p.head + " -> ";
240 | p = p.tail;
241 | }
242 |
243 | buffer += "NIL";
244 |
245 | return "[List "+buffer+"]";
246 | }
247 | }
248 | }
249 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/events/GenericEvent.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.events
2 | {
3 | import org.osflash.signals.IPrioritySignal;
4 |
5 | /**
6 | *
7 | * @see org.osflash.signals.events.IEvent
8 | * Documentation for the event interface being maintained in IEvent to avoid duplication for now.
9 | */
10 | public class GenericEvent implements IEvent
11 | {
12 | protected var _bubbles:Boolean;
13 | protected var _target:Object;
14 | protected var _currentTarget:Object;
15 | protected var _signal:IPrioritySignal;
16 |
17 | public function GenericEvent(bubbles:Boolean = false)
18 | {
19 | _bubbles = bubbles;
20 | }
21 |
22 | /** @inheritDoc */
23 | public function get signal():IPrioritySignal { return _signal; }
24 | public function set signal(value:IPrioritySignal):void { _signal = value; }
25 |
26 | /** @inheritDoc */
27 | public function get target():Object { return _target; }
28 | public function set target(value:Object):void { _target = value; }
29 |
30 | /** @inheritDoc */
31 | public function get currentTarget():Object { return _currentTarget; }
32 | public function set currentTarget(value:Object):void { _currentTarget = value; }
33 |
34 | /** @inheritDoc */
35 | public function get bubbles():Boolean { return _bubbles; }
36 | public function set bubbles(value:Boolean):void { _bubbles = value; }
37 |
38 | /** @inheritDoc */
39 | public function clone():IEvent
40 | {
41 | return new GenericEvent(_bubbles);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/events/IBubbleEventHandler.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.events
2 | {
3 |
4 | public interface IBubbleEventHandler
5 | {
6 | /**
7 | * Handler for event bubbling.
8 | * It's left to the IBubbleEventHandler to decide what to do with the event.
9 | * @param event The event that bubbled up.
10 | * @return whether to continue bubbling this event
11 | */
12 | function onEventBubbled(event:IEvent):Boolean;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/events/IEvent.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.events
2 | {
3 | import org.osflash.signals.IPrioritySignal;
4 |
5 | public interface IEvent
6 | {
7 | /** The object that originally dispatched the event.
8 | * When dispatched from an signal, the target is the object containing the signal. */
9 | function get target():Object;
10 | function set target(value:Object):void;
11 |
12 | /** The object that added the listener for the event. */
13 | function get currentTarget():Object;
14 | function set currentTarget(value:Object):void;
15 |
16 | /** The signal that dispatched the event. */
17 | function get signal():IPrioritySignal;
18 | function set signal(value:IPrioritySignal):void;
19 |
20 | /** Indicates whether the event is a bubbling event. */
21 | function get bubbles():Boolean;
22 | function set bubbles(value:Boolean):void;
23 |
24 | /** Returns a new copy of the instance. */
25 | function clone():IEvent;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/INativeDispatcher.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import org.osflash.signals.IPrioritySignal;
4 |
5 | import flash.events.Event;
6 | import flash.events.IEventDispatcher;
7 |
8 | /**
9 | * Similar to IDispatcher but using strong types specific to Flash's native event system.
10 | */
11 | public interface INativeDispatcher extends IPrioritySignal
12 | {
13 | /**
14 | * The type of event permitted to be dispatched. Corresponds to flash.events.Event.type.
15 | */
16 | function get eventType():String;
17 |
18 | /**
19 | * The class of event permitted to be dispatched. Will be flash.events.Event or a subclass.
20 | */
21 | function get eventClass():Class;
22 |
23 | /**
24 | * The object considered the source of the dispatched events.
25 | */
26 | function get target():IEventDispatcher;
27 |
28 | function set target(value:IEventDispatcher):void;
29 |
30 | /**
31 | * Dispatches an event to listeners.
32 | * @param event An instance of a class that is or extends flash.events.Event.
33 | * @throws ArgumentError ArgumentError
: Event object is null
.
34 | * @throws ArgumentError ArgumentError
: Event object [event] is not an instance of [eventClass].
35 | * @throws ArgumentError ArgumentError
: Event object has incorrect type. Expected [eventType] but was [event.type].
36 | * @throws ArgumentError ArgumentError
: Target object cannot be null
.
37 | */
38 | function dispatchEvent(event:Event):Boolean;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalBitmap.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import org.osflash.signals.natives.sets.DisplayObjectSignalSet;
4 | import flash.display.Bitmap;
5 |
6 | /**
7 | * @author Simon Richardson - me@simonrichardson.info
8 | */
9 | public class SignalBitmap extends Bitmap
10 | {
11 | private var _signals:DisplayObjectSignalSet;
12 |
13 | public function get signals():DisplayObjectSignalSet
14 | {
15 | return _signals ||= new DisplayObjectSignalSet(this);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalMovieClip.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import org.osflash.signals.natives.sets.InteractiveObjectSignalSet;
4 | import flash.display.MovieClip;
5 |
6 | public class SignalMovieClip extends MovieClip
7 | {
8 | private var _signals:InteractiveObjectSignalSet;
9 |
10 | public function get signals():InteractiveObjectSignalSet
11 | {
12 | return _signals ||= new InteractiveObjectSignalSet(this);
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalShape.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import org.osflash.signals.natives.sets.DisplayObjectSignalSet;
4 |
5 | import flash.display.Shape;
6 |
7 | /**
8 | * @author Simon Richardson - me@simonrichardson.info
9 | */
10 | public class SignalShape extends Shape
11 | {
12 |
13 | private var _signals:DisplayObjectSignalSet;
14 |
15 | public function get signals():DisplayObjectSignalSet
16 | {
17 | return _signals ||= new DisplayObjectSignalSet(this);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalSocket.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import flash.net.Socket;
4 | import org.osflash.signals.natives.sets.SocketSignalSet;
5 |
6 | public class SignalSocket extends Socket
7 | {
8 | private var _signals:SocketSignalSet;
9 |
10 | public function get signals():SocketSignalSet
11 | {
12 | return _signals ||= new SocketSignalSet(this);
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalSprite.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import org.osflash.signals.natives.sets.InteractiveObjectSignalSet;
4 | import flash.display.Sprite;
5 |
6 | public class SignalSprite extends Sprite
7 | {
8 | private var _signals:InteractiveObjectSignalSet;
9 |
10 | public function get signals():InteractiveObjectSignalSet
11 | {
12 | return _signals ||= new InteractiveObjectSignalSet(this);
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalTextField.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import flash.text.TextField;
4 | import org.osflash.signals.natives.sets.TextFieldSignalSet;
5 |
6 | public class SignalTextField extends TextField
7 | {
8 | private var _signals:TextFieldSignalSet;
9 |
10 | public function get signals():TextFieldSignalSet
11 | {
12 | return _signals ||= new TextFieldSignalSet(this);
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalTimer.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import flash.utils.Timer;
4 | import org.osflash.signals.natives.sets.TimerSignalSet;
5 |
6 | public class SignalTimer extends Timer
7 | {
8 | private var _signals:TimerSignalSet;
9 |
10 | public function get signals():TimerSignalSet
11 | {
12 | return _signals ||= new TimerSignalSet(this);
13 | }
14 |
15 | public function SignalTimer(delay:Number, repeatCount:int = 0)
16 | {
17 | super(delay, repeatCount);
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalURLLoader.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import flash.net.URLLoader;
4 | import org.osflash.signals.natives.sets.URLLoaderSignalSet;
5 |
6 | public class SignalURLLoader extends URLLoader
7 | {
8 | private var _signals:URLLoaderSignalSet;
9 |
10 | public function get signals():URLLoaderSignalSet
11 | {
12 | return _signals ||= new URLLoaderSignalSet(this);
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/base/SignalXMLSocket.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import flash.net.XMLSocket;
4 | import org.osflash.signals.natives.sets.XMLSocketSignalSet;
5 |
6 | public class SignalXMLSocket extends XMLSocket
7 | {
8 | private var _signals:XMLSocketSignalSet;
9 |
10 | public function get signals():XMLSocketSignalSet
11 | {
12 | return _signals ||= new XMLSocketSignalSet(this);
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/DisplayObjectSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets
2 | {
3 | import org.osflash.signals.natives.NativeSignal;
4 |
5 | import flash.display.DisplayObject;
6 | import flash.events.Event;
7 |
8 | /**
9 | * @author Jon Adams
10 | */
11 | public class DisplayObjectSignalSet extends EventDispatcherSignalSet
12 | {
13 |
14 | public function DisplayObjectSignalSet(target:DisplayObject)
15 | {
16 | super(target);
17 | }
18 |
19 | public function get added():NativeSignal
20 | {
21 | return getNativeSignal(Event.ADDED);
22 | }
23 | public function get addedToStage():NativeSignal
24 | {
25 | return getNativeSignal(Event.ADDED_TO_STAGE);
26 | }
27 | public function get enterFrame():NativeSignal
28 | {
29 | return getNativeSignal(Event.ENTER_FRAME);
30 | }
31 | public function get exitFrame():NativeSignal
32 | {
33 | // Using a string here because we need to target FP9
34 | return getNativeSignal("exitFrame");
35 | }
36 |
37 | public function get frameConstructed():NativeSignal
38 | {
39 | // Using a string here because we need to target FP9
40 | return getNativeSignal("frameConstructed");
41 | }
42 |
43 | public function get removed():NativeSignal
44 | {
45 | return getNativeSignal(Event.REMOVED);
46 | }
47 | public function get removedFromStage():NativeSignal
48 | {
49 | return getNativeSignal(Event.REMOVED_FROM_STAGE);
50 | }
51 | public function get render():NativeSignal
52 | {
53 | return getNativeSignal(Event.RENDER);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/EventDispatcherSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets
2 | {
3 | import org.osflash.signals.natives.NativeSignal;
4 |
5 | import flash.events.Event;
6 | import flash.events.EventDispatcher;
7 |
8 | /**
9 | * @author Jon Adams
10 | */
11 | public class EventDispatcherSignalSet extends NativeSignalSet
12 | {
13 | public function EventDispatcherSignalSet(target:EventDispatcher)
14 | {
15 | super(target);
16 | }
17 |
18 | public function get activate():NativeSignal
19 | {
20 | return getNativeSignal(Event.ACTIVATE);
21 | }
22 |
23 | public function get deactivate():NativeSignal
24 | {
25 | return getNativeSignal(Event.DEACTIVATE);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/FileReferenceListSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.Event;
5 | import flash.net.FileReference;
6 |
7 | /**
8 | * @author Jon Adams
9 | */
10 | public class FileReferenceListSignalSet extends EventDispatcherSignalSet {
11 |
12 | public function FileReferenceListSignalSet(target:FileReference) {
13 | super(target);
14 | }
15 |
16 | public function get cancel():NativeSignal {
17 | return getNativeSignal(Event.CANCEL);
18 | }
19 |
20 | public function get select():NativeSignal {
21 | return getNativeSignal(Event.SELECT);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/FileReferenceSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.DataEvent;
5 | import flash.events.Event;
6 | import flash.events.HTTPStatusEvent;
7 | import flash.events.IOErrorEvent;
8 | import flash.events.ProgressEvent;
9 | import flash.events.SecurityErrorEvent;
10 | import flash.net.FileReference;
11 |
12 | /**
13 | * @author Jon Adams
14 | */
15 | public class FileReferenceSignalSet extends EventDispatcherSignalSet {
16 |
17 | public function FileReferenceSignalSet(target:FileReference) {
18 | super(target);
19 | }
20 |
21 | public function get cancel():NativeSignal {
22 | return getNativeSignal(Event.CANCEL);
23 | }
24 | public function get complete():NativeSignal {
25 | return getNativeSignal(Event.COMPLETE);
26 | }
27 |
28 | public function get httpStatus():NativeSignal {
29 | return getNativeSignal(HTTPStatusEvent.HTTP_STATUS, HTTPStatusEvent);
30 | }
31 |
32 | public function get ioError():NativeSignal {
33 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
34 | }
35 |
36 | public function get open():NativeSignal {
37 | return getNativeSignal(Event.OPEN);
38 | }
39 |
40 | public function get progress():NativeSignal {
41 | return getNativeSignal(ProgressEvent.PROGRESS, ProgressEvent);
42 | }
43 |
44 | public function get securityError():NativeSignal {
45 | return getNativeSignal(SecurityErrorEvent.SECURITY_ERROR, SecurityErrorEvent);
46 | }
47 | public function get select():NativeSignal {
48 | return getNativeSignal(Event.SELECT);
49 | }
50 | public function get uploadCompleteData():NativeSignal {
51 | return getNativeSignal(DataEvent.UPLOAD_COMPLETE_DATA, DataEvent);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/InteractiveObjectSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets
2 | {
3 | import org.osflash.signals.natives.NativeSignal;
4 |
5 | import flash.display.InteractiveObject;
6 | import flash.events.Event;
7 | import flash.events.FocusEvent;
8 | import flash.events.KeyboardEvent;
9 | import flash.events.MouseEvent;
10 | import flash.events.TextEvent;
11 |
12 | /**
13 | * @author Jon Adams
14 | */
15 | public class InteractiveObjectSignalSet extends DisplayObjectSignalSet
16 | {
17 |
18 | public function InteractiveObjectSignalSet(target:InteractiveObject)
19 | {
20 | super(target);
21 | }
22 |
23 | public function get click():NativeSignal
24 | {
25 | return getNativeSignal(MouseEvent.CLICK, MouseEvent);
26 | }
27 |
28 | public function get doubleClick():NativeSignal
29 | {
30 | return getNativeSignal(MouseEvent.DOUBLE_CLICK, MouseEvent);
31 | }
32 |
33 | public function get focusIn():NativeSignal
34 | {
35 | return getNativeSignal(FocusEvent.FOCUS_IN, FocusEvent);
36 | }
37 |
38 | public function get focusOut():NativeSignal
39 | {
40 | return getNativeSignal(FocusEvent.FOCUS_OUT, FocusEvent);
41 | }
42 |
43 | public function get keyDown():NativeSignal
44 | {
45 | return getNativeSignal(KeyboardEvent.KEY_DOWN, KeyboardEvent);
46 | }
47 |
48 | public function get keyFocusChange():NativeSignal
49 | {
50 | return getNativeSignal(FocusEvent.KEY_FOCUS_CHANGE, FocusEvent);
51 | }
52 |
53 | public function get keyUp():NativeSignal
54 | {
55 | return getNativeSignal(KeyboardEvent.KEY_UP, KeyboardEvent);
56 | }
57 |
58 | public function get mouseDown():NativeSignal
59 | {
60 | return getNativeSignal(MouseEvent.MOUSE_DOWN, MouseEvent);
61 | }
62 |
63 | public function get mouseFocusChange():NativeSignal
64 | {
65 | return getNativeSignal(FocusEvent.MOUSE_FOCUS_CHANGE, FocusEvent);
66 | }
67 |
68 | public function get mouseMove():NativeSignal
69 | {
70 | return getNativeSignal(MouseEvent.MOUSE_MOVE, MouseEvent);
71 | }
72 |
73 | public function get mouseOut():NativeSignal
74 | {
75 | return getNativeSignal(MouseEvent.MOUSE_OUT, MouseEvent);
76 | }
77 |
78 | public function get mouseOver():NativeSignal
79 | {
80 | return getNativeSignal(MouseEvent.MOUSE_OVER, MouseEvent);
81 | }
82 |
83 | public function get mouseUp():NativeSignal
84 | {
85 | return getNativeSignal(MouseEvent.MOUSE_UP, MouseEvent);
86 | }
87 |
88 | public function get mouseWheel():NativeSignal
89 | {
90 | return getNativeSignal(MouseEvent.MOUSE_WHEEL, MouseEvent);
91 | }
92 |
93 | public function get rollOut():NativeSignal
94 | {
95 | return getNativeSignal(MouseEvent.ROLL_OUT, MouseEvent);
96 | }
97 |
98 | public function get rollOver():NativeSignal
99 | {
100 | return getNativeSignal(MouseEvent.ROLL_OVER, MouseEvent);
101 | }
102 |
103 | public function get tabChildrenChange():NativeSignal
104 | {
105 | return getNativeSignal(Event.TAB_CHILDREN_CHANGE);
106 | }
107 |
108 | public function get tabEnabledChange():NativeSignal
109 | {
110 | return getNativeSignal(Event.TAB_ENABLED_CHANGE);
111 | }
112 |
113 | public function get tabIndexChange():NativeSignal
114 | {
115 | return getNativeSignal(Event.TAB_INDEX_CHANGE);
116 | }
117 |
118 | public function get textInput():NativeSignal
119 | {
120 | return getNativeSignal(TextEvent.TEXT_INPUT, TextEvent);
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/LoaderInfoSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.display.LoaderInfo;
5 | import flash.events.Event;
6 | import flash.events.HTTPStatusEvent;
7 | import flash.events.IOErrorEvent;
8 | import flash.events.ProgressEvent;
9 |
10 | /**
11 | * @author Jon Adams
12 | */
13 | public class LoaderInfoSignalSet extends EventDispatcherSignalSet {
14 |
15 | public function LoaderInfoSignalSet(target:LoaderInfo) {
16 | super(target);
17 | }
18 |
19 | public function get complete():NativeSignal {
20 | return getNativeSignal(Event.COMPLETE);
21 | }
22 |
23 | public function get httpStatus():NativeSignal {
24 | return getNativeSignal(HTTPStatusEvent.HTTP_STATUS, HTTPStatusEvent);
25 | }
26 |
27 | public function get init():NativeSignal {
28 | return getNativeSignal(Event.INIT);
29 | }
30 | public function get ioError():NativeSignal {
31 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
32 | }
33 |
34 | public function get open():NativeSignal {
35 | return getNativeSignal(Event.OPEN);
36 | }
37 |
38 | public function get progress():NativeSignal {
39 | return getNativeSignal(ProgressEvent.PROGRESS, ProgressEvent);
40 | }
41 |
42 | public function get unload():NativeSignal {
43 | return getNativeSignal(Event.UNLOAD);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/MicrophoneSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.ActivityEvent;
5 | import flash.events.StatusEvent;
6 | import flash.media.Microphone;
7 |
8 | /**
9 | * @author Jon Adams
10 | */
11 | public class MicrophoneSignalSet extends EventDispatcherSignalSet {
12 |
13 | public function MicrophoneSignalSet(target:Microphone) {
14 | super(target);
15 | }
16 |
17 | public function get activity():NativeSignal {
18 | return getNativeSignal(ActivityEvent.ACTIVITY, ActivityEvent);
19 | }
20 | public function get status():NativeSignal {
21 | return getNativeSignal(StatusEvent.STATUS, StatusEvent);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/NativeSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets
2 | {
3 | import org.osflash.signals.natives.INativeDispatcher;
4 | import org.osflash.signals.natives.NativeSignal;
5 |
6 | import flash.events.Event;
7 | import flash.events.IEventDispatcher;
8 | import flash.utils.Dictionary;
9 |
10 | /**
11 | * A convenient way to access a logical set of signals.
12 | *
13 | * @author Jon Adams
14 | *
15 | * @example SignalSets allow you to get predefined signals for many built in events
16 | * ArgumentError
: eventType must not be null.
63 | */
64 | public function getNativeSignal(eventType:String, eventClass:Class = null):NativeSignal
65 | {
66 | if(null == eventType) throw new ArgumentError('eventType must not be null.');
67 |
68 | return _signals[eventType] ||= new NativeSignal(target, eventType, eventClass || Event);
69 | }
70 |
71 | /**
72 | * The current number of listeners for the signal.
73 | */
74 | public function get numListeners():int
75 | {
76 | // TODO : This is horrid, it's very expensive to call this if there is a lot of signals.
77 | var count:int = 0;
78 | for each (var signal:INativeDispatcher in _signals)
79 | {
80 | count += signal.numListeners;
81 | }
82 | return count;
83 | }
84 |
85 | /**
86 | * The signals in the SignalSet as an Array.
87 | */
88 | public function get signals():Array
89 | {
90 | // TODO : This is horrid, it's very expensive to call this if there is a lot of signals.
91 | var result:Array = [];
92 | for each (var signal:INativeDispatcher in _signals)
93 | {
94 | result[result.length] = signal;
95 | }
96 | return result;
97 | }
98 |
99 | /**
100 | * Unsubscribes all listeners from all signals in the set.
101 | */
102 | public function removeAll():void
103 | {
104 | for each (var signal:INativeDispatcher in _signals)
105 | {
106 | signal.removeAll();
107 | delete _signals[signal.eventType];
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/NetConnectionSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.AsyncErrorEvent;
5 | import flash.events.IOErrorEvent;
6 | import flash.events.NetStatusEvent;
7 | import flash.events.SecurityErrorEvent;
8 | import flash.net.NetConnection;
9 |
10 | /**
11 | * @author Jon Adams
12 | */
13 | public class NetConnectionSignalSet extends EventDispatcherSignalSet {
14 |
15 | public function NetConnectionSignalSet(target:NetConnection) {
16 | super(target);
17 | }
18 |
19 | public function get asyncError():NativeSignal {
20 | return getNativeSignal(AsyncErrorEvent.ASYNC_ERROR, AsyncErrorEvent);
21 | }
22 |
23 | public function get ioError():NativeSignal {
24 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
25 | }
26 |
27 | public function get netStatus():NativeSignal {
28 | return getNativeSignal(NetStatusEvent.NET_STATUS, NetStatusEvent);
29 | }
30 |
31 | public function get securityError():NativeSignal {
32 | return getNativeSignal(SecurityErrorEvent.SECURITY_ERROR, SecurityErrorEvent);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/NetStreamSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.AsyncErrorEvent;
5 | import flash.events.IOErrorEvent;
6 | import flash.events.NetStatusEvent;
7 | import flash.net.NetStream;
8 |
9 | /**
10 | * @author Jon Adams
11 | */
12 | public class NetStreamSignalSet extends EventDispatcherSignalSet {
13 |
14 | public function NetStreamSignalSet(target:NetStream) {
15 | super(target);
16 | }
17 |
18 | public function get asyncError():NativeSignal {
19 | return getNativeSignal(AsyncErrorEvent.ASYNC_ERROR, AsyncErrorEvent);
20 | }
21 | public function get ioError():NativeSignal {
22 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
23 | }
24 | public function get netStatus():NativeSignal {
25 | return getNativeSignal(NetStatusEvent.NET_STATUS, NetStatusEvent);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/SharedObjectSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.AsyncErrorEvent;
5 | import flash.events.NetStatusEvent;
6 | import flash.events.SyncEvent;
7 | import flash.net.SharedObject;
8 |
9 | /**
10 | * @author Jon Adams
11 | */
12 | public class SharedObjectSignalSet extends EventDispatcherSignalSet {
13 |
14 | public function SharedObjectSignalSet(target:SharedObject) {
15 | super(target);
16 | }
17 |
18 | public function get asyncError():NativeSignal {
19 | return getNativeSignal(AsyncErrorEvent.ASYNC_ERROR, AsyncErrorEvent);
20 | }
21 | public function get netStatus():NativeSignal {
22 | return getNativeSignal(NetStatusEvent.NET_STATUS, NetStatusEvent);
23 | }
24 | public function get sync():NativeSignal {
25 | return getNativeSignal(SyncEvent.SYNC, SyncEvent);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/SocketSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.Event;
5 | import flash.events.IOErrorEvent;
6 | import flash.events.ProgressEvent;
7 | import flash.events.SecurityErrorEvent;
8 | import flash.net.Socket;
9 |
10 | /**
11 | * @author Jon Adams
12 | */
13 | public class SocketSignalSet extends EventDispatcherSignalSet {
14 |
15 | public function SocketSignalSet(target:Socket) {
16 | super(target);
17 | }
18 |
19 | public function get close():NativeSignal {
20 | return getNativeSignal(Event.CLOSE);
21 | }
22 |
23 | public function get connect():NativeSignal {
24 | return getNativeSignal(Event.CONNECT);
25 | }
26 |
27 | public function get ioError():NativeSignal {
28 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
29 | }
30 |
31 | public function get securityError():NativeSignal {
32 | return getNativeSignal(SecurityErrorEvent.SECURITY_ERROR, SecurityErrorEvent);
33 | }
34 |
35 | public function get socketData():NativeSignal {
36 | return getNativeSignal(ProgressEvent.SOCKET_DATA, ProgressEvent);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/SoundChannelSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.Event;
5 | import flash.media.SoundChannel;
6 |
7 | /**
8 | * @author Jon Adams
9 | */
10 | public class SoundChannelSignalSet extends EventDispatcherSignalSet {
11 |
12 | public function SoundChannelSignalSet(target:SoundChannel) {
13 | super(target);
14 | }
15 |
16 | public function get soundComplete():NativeSignal {
17 | return getNativeSignal(Event.SOUND_COMPLETE);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/SoundSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.Event;
5 | import flash.events.IOErrorEvent;
6 | import flash.events.ProgressEvent;
7 | import flash.media.Sound;
8 |
9 | /**
10 | * @author Jon Adams
11 | */
12 | public class SoundSignalSet extends EventDispatcherSignalSet {
13 |
14 | public function SoundSignalSet(target:Sound) {
15 | super(target);
16 | }
17 |
18 | public function get complete():NativeSignal {
19 | return getNativeSignal(Event.COMPLETE);
20 | }
21 |
22 | public function get id3():NativeSignal {
23 | return getNativeSignal(Event.ID3);
24 | }
25 |
26 | public function get ioError():NativeSignal {
27 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
28 | }
29 |
30 | public function get open():NativeSignal {
31 | return getNativeSignal(Event.OPEN);
32 | }
33 |
34 | public function get progress():NativeSignal {
35 | return getNativeSignal(ProgressEvent.PROGRESS, ProgressEvent);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/StageSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets
2 | {
3 | import org.osflash.signals.natives.NativeSignal;
4 |
5 | import flash.display.Stage;
6 | import flash.events.Event;
7 |
8 | /**
9 | * @author Jon Adams
10 | */
11 | public class StageSignalSet extends InteractiveObjectSignalSet
12 | {
13 |
14 | public function StageSignalSet(target:Stage)
15 | {
16 | super(target);
17 | }
18 |
19 | public function get fullScreen():NativeSignal
20 | {
21 | return getNativeSignal(Event.FULLSCREEN);
22 | }
23 |
24 | public function get mouseLeave():NativeSignal
25 | {
26 | return getNativeSignal(Event.MOUSE_LEAVE);
27 | }
28 |
29 | public function get resize():NativeSignal
30 | {
31 | return getNativeSignal(Event.RESIZE);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/TextFieldSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.Event;
5 | import flash.events.TextEvent;
6 | import flash.text.TextField;
7 |
8 | /**
9 | * @author Jon Adams
10 | */
11 | public class TextFieldSignalSet extends InteractiveObjectSignalSet {
12 |
13 | public function TextFieldSignalSet(target:TextField) {
14 | super(target);
15 | }
16 |
17 | public function get change():NativeSignal {
18 | return getNativeSignal(Event.CHANGE);
19 | }
20 | public function get link():NativeSignal {
21 | return getNativeSignal(TextEvent.LINK, TextEvent);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/TimerSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.TimerEvent;
5 | import flash.utils.Timer;
6 |
7 | /**
8 | * @author Jon Adams
9 | */
10 | public class TimerSignalSet extends EventDispatcherSignalSet {
11 |
12 | public function TimerSignalSet(target:Timer) {
13 | super(target);
14 | }
15 |
16 | public function get timer():NativeSignal {
17 | return getNativeSignal(TimerEvent.TIMER, TimerEvent);
18 | }
19 | public function get timerComplete():NativeSignal {
20 | return getNativeSignal(TimerEvent.TIMER_COMPLETE, TimerEvent);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/URLLoaderSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.Event;
5 | import flash.events.HTTPStatusEvent;
6 | import flash.events.IOErrorEvent;
7 | import flash.events.ProgressEvent;
8 | import flash.events.SecurityErrorEvent;
9 | import flash.net.URLLoader;
10 |
11 | /**
12 | * @author Jon Adams
13 | */
14 | public class URLLoaderSignalSet extends EventDispatcherSignalSet {
15 |
16 | public function URLLoaderSignalSet(target:URLLoader) {
17 | super(target);
18 | }
19 |
20 | public function get complete():NativeSignal {
21 | return getNativeSignal(Event.COMPLETE);
22 | }
23 |
24 | public function get httpStatus():NativeSignal {
25 | return getNativeSignal(HTTPStatusEvent.HTTP_STATUS, HTTPStatusEvent);
26 | }
27 |
28 | public function get ioError():NativeSignal {
29 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
30 | }
31 |
32 | public function get open():NativeSignal {
33 | return getNativeSignal(Event.OPEN);
34 | }
35 |
36 | public function get progress():NativeSignal {
37 | return getNativeSignal(ProgressEvent.PROGRESS, ProgressEvent);
38 | }
39 |
40 | public function get securityError():NativeSignal {
41 | return getNativeSignal(SecurityErrorEvent.SECURITY_ERROR, SecurityErrorEvent);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/URLStreamSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.Event;
5 | import flash.events.HTTPStatusEvent;
6 | import flash.events.IOErrorEvent;
7 | import flash.events.ProgressEvent;
8 | import flash.events.SecurityErrorEvent;
9 | import flash.net.URLStream;
10 |
11 | /**
12 | * @author Jon Adams
13 | */
14 | public class URLStreamSignalSet extends EventDispatcherSignalSet {
15 |
16 | public function URLStreamSignalSet(target:URLStream) {
17 | super(target);
18 | }
19 |
20 | public function get complete():NativeSignal {
21 | return getNativeSignal(Event.COMPLETE);
22 | }
23 | public function get httpStatus():NativeSignal {
24 | return getNativeSignal(HTTPStatusEvent.HTTP_STATUS, HTTPStatusEvent);
25 | }
26 | public function get ioError():NativeSignal {
27 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
28 | }
29 | public function get open():NativeSignal {
30 | return getNativeSignal(Event.OPEN);
31 | }
32 | public function get progress():NativeSignal {
33 | return getNativeSignal(ProgressEvent.PROGRESS, ProgressEvent);
34 | }
35 | public function get securityError():NativeSignal {
36 | return getNativeSignal(SecurityErrorEvent.SECURITY_ERROR, SecurityErrorEvent);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/org/osflash/signals/natives/sets/XMLSocketSignalSet.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets {
2 | import org.osflash.signals.natives.NativeSignal;
3 |
4 | import flash.events.DataEvent;
5 | import flash.events.Event;
6 | import flash.events.IOErrorEvent;
7 | import flash.events.SecurityErrorEvent;
8 | import flash.net.XMLSocket;
9 |
10 | /**
11 | * @author Jon Adams
12 | */
13 | public class XMLSocketSignalSet extends EventDispatcherSignalSet {
14 |
15 | public function XMLSocketSignalSet(target:XMLSocket) {
16 | super(target);
17 | }
18 |
19 | public function get close():NativeSignal {
20 | return getNativeSignal(Event.CLOSE);
21 | }
22 | public function get connect():NativeSignal {
23 | return getNativeSignal(Event.CONNECT);
24 | }
25 | public function get data():NativeSignal {
26 | return getNativeSignal(DataEvent.DATA, DataEvent);
27 | }
28 | public function get ioError():NativeSignal {
29 | return getNativeSignal(IOErrorEvent.IO_ERROR, IOErrorEvent);
30 | }
31 | public function get securityError():NativeSignal {
32 | return getNativeSignal(SecurityErrorEvent.SECURITY_ERROR, SecurityErrorEvent);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/AllTests.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import org.osflash.signals.natives.AmbiguousRelationshipInNativeSignalTest;
4 | import org.osflash.signals.natives.MXMLNativeSignalTest;
5 | import org.osflash.signals.natives.NativeMappedSignalBoundaryUseTest;
6 | import org.osflash.signals.natives.NativeMappedSignalDefaultsTest;
7 | import org.osflash.signals.natives.NativeMappedSignalFunctionArgTest;
8 | import org.osflash.signals.natives.NativeMappedSignalFunctionNoArgsTest;
9 | import org.osflash.signals.natives.NativeMappedSignalObjectArgTest;
10 | import org.osflash.signals.natives.NativeRelaySignalTest;
11 | import org.osflash.signals.natives.NativeSignalSlotTest;
12 | import org.osflash.signals.natives.NativeSignalTest;
13 | import org.osflash.signals.natives.sets.DisplayObjectSignalSetTest;
14 | import org.osflash.signals.natives.sets.EventDispatcherSignalSetTest;
15 | import org.osflash.signals.natives.sets.NativeSignalSetTest;
16 |
17 | [Suite]
18 | public class AllTests
19 | {
20 | public var _AmbiguousRelationshipTest:AmbiguousRelationshipTest;
21 | public var _AmbiguousRelationshipInNativeSignalTest:AmbiguousRelationshipInNativeSignalTest;
22 | public var _GenericEventTest:GenericEventTest;
23 |
24 | public var _NativeRelaySignalTest:NativeRelaySignalTest;
25 | public var _NativeSignalTest:NativeSignalTest;
26 | public var _NativeMappedSignalDefaultsTest:NativeMappedSignalDefaultsTest;
27 | public var _NativeMappedSignalObjectArgTest:NativeMappedSignalObjectArgTest;
28 | public var _NativeMappedSignalFunctionNoArgsTest:NativeMappedSignalFunctionNoArgsTest;
29 | public var _NativeMappedSignalFunctionArgTest:NativeMappedSignalFunctionArgTest;
30 | public var _NativeMappedSignalBoundaryUseTest:NativeMappedSignalBoundaryUseTest;
31 | public var _NativeSlotTest:NativeSignalSlotTest;
32 |
33 | public var _PriorityListenersTest:PriorityListenersTest;
34 | public var _PrioritySignalTest:PrioritySignalTest;
35 | public var _RedispatchedEventTest:RedispatchedEventTest;
36 |
37 | public var _DeluxeSignalWithBubblingEventTest:DeluxeSignalWithBubblingEventTest;
38 | public var _DeluxeSignalWithGenericEventTest:DeluxeSignalWithGenericEventTest;
39 |
40 | public var _MXMLDeluxeSignalTest:MXMLDeluxeSignalTest;
41 | public var _MXMLSignalTest:MXMLSignalTest;
42 | public var _MXMLNativeSignalTest:MXMLNativeSignalTest;
43 |
44 | public var _SignalDispatchArgsTest:SignalDispatchArgsTest;
45 | public var _SignalDispatchExtraArgsTest:SignalDispatchExtraArgsTest;
46 | public var _SignalDispatchNoArgsTest:SignalDispatchNoArgsTest;
47 | public var _SignalDispatchNonEventTest:SignalDispatchNonEventTest;
48 | public var _SignalTest:SignalTest;
49 | public var _SignalWithCustomEventTest:SignalWithCustomEventTest;
50 | public var _SlotTest:SlotTest;
51 | public var _SlotListTest:SlotListTest;
52 | public var _SignalDispatchVarArgsTest:SignalDispatchVarArgsTest;
53 |
54 | public var _MonoSignalTest:MonoSignalTest;
55 | public var _MonoSignalDispatchArgsTest:MonoSignalDispatchArgsTest;
56 | public var _MonoSignalDispatchExtraArgsTest:MonoSignalDispatchExtraArgsTest;
57 | public var _MonoSignalDispatchNoArgsTest:MonoSignalDispatchNoArgsTest;
58 | public var _MonoSignalDispatchNonEventTest:MonoSignalDispatchNonEventTest;
59 | public var _MonoSignalSlotTest:MonoSignalSlotTest;
60 | public var _MonoSignalDispatchVarArgsTest:MonoSignalDispatchVarArgsTest;
61 |
62 | public var _PromiseTest:PromiseTest;
63 | public var _NativeSignalSetTest:NativeSignalSetTest;
64 | public var _EventDispatcherSignalSetTest:EventDispatcherSignalSetTest;
65 | public var _DisplayObjectSignalSetTest:DisplayObjectSignalSetTest;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/AllTestsCIRunner.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.core.FlexUnitCICore;
4 | import asunit.core.TextCore;
5 |
6 | import flash.display.MovieClip;
7 |
8 | [SWF(width='1000', height='800', backgroundColor='#333333', frameRate='31')]
9 | public class AllTestsCIRunner extends MovieClip
10 | {
11 | private var core:TextCore;
12 |
13 | public function AllTestsCIRunner()
14 | {
15 | core = new FlexUnitCICore();
16 | core.start(AllTests, null, this);
17 | }
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/AllTestsRunner.as:
--------------------------------------------------------------------------------
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.textPrinter.hideLocalPaths = true;
16 | core.start(AllTests, null, this);
17 | }
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/AmbiguousRelationshipTest.as:
--------------------------------------------------------------------------------
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 | }
61 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/DeluxeSignalWithBubblingEventTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import org.osflash.signals.events.GenericEvent;
7 | import org.osflash.signals.events.IBubbleEventHandler;
8 | import org.osflash.signals.events.IEvent;
9 |
10 | public class DeluxeSignalWithBubblingEventTest implements IBubbleEventHandler
11 | {
12 | [Inject]
13 | public var async:IAsync;
14 |
15 | protected var theParent:IBubbleEventHandler;
16 | protected var theChild:Child;
17 | protected var theGrandChild:Child;
18 | protected var cancelTimeout:Function;
19 |
20 | [Before]
21 | public function setUp():void
22 | {
23 | theParent = this;
24 | theChild = new Child(this, 'theChild');
25 | theGrandChild = new Child(theChild, 'theGrandChild');
26 | }
27 |
28 | [After]
29 | public function tearDown():void
30 | {
31 | theChild = null;
32 | theGrandChild = null;
33 | cancelTimeout = null;
34 | }
35 |
36 | [Test]
37 | public function parent_child_relationships():void
38 | {
39 | assertSame("theChild's parent is this", this, theChild.parent);
40 | assertTrue("this can handle bubbling events", this is IBubbleEventHandler);
41 | }
42 |
43 | [Test]
44 | public function dispatch_bubbling_event_from_theGrandChild_should_bubble_to_parent_IBubbleHandler():void
45 | {
46 | // If cancelTimeout() isn't called, this test will fail.
47 | cancelTimeout = async.add(null, 10);
48 | var event:IEvent = new GenericEvent();
49 | event.bubbles = true;
50 |
51 | theGrandChild.completed.dispatch(event);
52 | }
53 |
54 | public function onEventBubbled(e:IEvent):Boolean
55 | {
56 | cancelTimeout();
57 | assertSame('e.target should be the object that originally dispatched event', theGrandChild, e.target);
58 | assertSame('e.currentTarget should be the object receiving the bubbled event', this, e.currentTarget);
59 | return false;
60 | }
61 |
62 | [Test]
63 | public function returning_false_from_onEventBubbled_should_stop_bubbling():void
64 | {
65 | var bubbleHater:BubbleHater = new BubbleHater();
66 | theChild = new Child(bubbleHater, 'bubblePopper');
67 | theChild.popsBubbles = true;
68 | theGrandChild = new Child(theChild, 'bubbleBlower');
69 |
70 | var bubblingEvent:IEvent = new GenericEvent(true);
71 | // Will only complete without error if theChild pops the bubble.
72 | theGrandChild.completed.dispatch(bubblingEvent);
73 | }
74 |
75 | [Test(expects="flash.errors.IllegalOperationError")]
76 | public function returning_true_from_onEventBubbled_should_continue_bubbling():void
77 | {
78 | var bubbleHater:BubbleHater = new BubbleHater();
79 | theChild = new Child(bubbleHater, 'bubblePopper');
80 | // Changing popsBubbles to false will fail the test nicely.
81 | theChild.popsBubbles = false;
82 | theGrandChild = new Child(theChild, 'bubbleBlower');
83 |
84 | var bubblingEvent:IEvent = new GenericEvent(true);
85 | // Because theChild didn't pop the bubble, this causes bubbleHater to throw an error.
86 | theGrandChild.completed.dispatch(bubblingEvent);
87 | }
88 | }
89 | }
90 |
91 | import org.osflash.signals.DeluxeSignal;
92 | import org.osflash.signals.events.IBubbleEventHandler;
93 | import org.osflash.signals.events.IEvent;
94 |
95 | import flash.errors.IllegalOperationError;
96 |
97 | class Child implements IBubbleEventHandler
98 | {
99 | public var parent:Object;
100 | public var completed:DeluxeSignal;
101 | public var name:String;
102 | public var popsBubbles:Boolean = false;
103 |
104 | public function Child(parent:Object = null, name:String = '')
105 | {
106 | this.parent = parent;
107 | this.name = name;
108 | completed = new DeluxeSignal(this);
109 | }
110 |
111 | public function toString():String
112 | {
113 | return '[Child '+name+']';
114 | }
115 |
116 | public function onEventBubbled(event:IEvent):Boolean
117 | {
118 | return !popsBubbles;
119 | }
120 | }
121 |
122 | class BubbleHater implements IBubbleEventHandler
123 | {
124 | public function onEventBubbled(event:IEvent):Boolean
125 | {
126 | throw new IllegalOperationError('I SAID NO BUBBLES!!!');
127 | return false;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/DeluxeSignalWithGenericEventTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import org.osflash.signals.events.GenericEvent;
7 | import org.osflash.signals.events.IEvent;
8 |
9 | import flash.display.Sprite;
10 |
11 | public class DeluxeSignalWithGenericEventTest
12 | {
13 | [Inject]
14 | public var async:IAsync;
15 |
16 | protected var completed:DeluxeSignal;
17 | protected var delegate:Function;
18 |
19 | [Before]
20 | public function setUp():void
21 | {
22 | completed = new DeluxeSignal(this);
23 | }
24 |
25 | [After]
26 | public function tearDown():void
27 | {
28 | completed.removeAll();
29 | completed = null;
30 | delegate = null;
31 | }
32 |
33 | [Test]
34 | public function signal_length_is_0_after_creation():void
35 | {
36 | assertEquals(0, completed.numListeners);
37 | }
38 |
39 | //////
40 |
41 | [Test]
42 | public function add_listener_and_dispatch_event_should_pass_event_to_listener():void
43 | {
44 | completed.add(async.add(checkGenericEvent, 10));
45 | completed.dispatch(new GenericEvent());
46 | }
47 |
48 | protected function checkGenericEvent(e:IEvent):void
49 | {
50 | assertTrue('instance of IEvent', e is IEvent);
51 | assertTrue('instance of GenericEvent', e is GenericEvent);
52 | assertEquals('event.signal points to the originating Signal', this.completed, e.signal);
53 | assertEquals('event.target points to object containing the Signal', this, e.target);
54 | assertEquals('event.target is e.currentTarget because event does not bubble', e.target, e.currentTarget);
55 | }
56 |
57 | //////
58 |
59 |
60 | [Test]
61 | public function add_two_listeners_and_dispatch_should_call_both():void
62 | {
63 | completed.add(async.add(checkGenericEvent, 10));
64 | completed.add(async.add(checkGenericEvent, 10));
65 | completed.dispatch(new GenericEvent());
66 | }
67 |
68 | //////
69 |
70 | [Test]
71 | public function addOnce_and_dispatch_should_remove_listener_automatically():void
72 | {
73 | completed.addOnce(newEmptyHandler());
74 | completed.dispatch(new GenericEvent());
75 | assertEquals('there should be no listeners', 0, completed.numListeners);
76 | }
77 |
78 | //////
79 |
80 | [Test]
81 | public function add_one_listener_and_dispatch_then_listener_remove_itself_using_event_signal():void
82 | {
83 | delegate = async.add(remove_myself_from_signal, 10);
84 | completed.add(delegate);
85 | completed.dispatch(new GenericEvent());
86 | }
87 |
88 | private function remove_myself_from_signal(e:IEvent):void
89 | {
90 | assertEquals('listener still in signal', 1, e.signal.numListeners);
91 |
92 | // Can't remove(arguments.callee) because it's wrapped with delegate created by async.add().
93 | e.signal.remove(delegate);
94 |
95 | assertEquals('listener removed from signal', 0, e.signal.numListeners);
96 | }
97 |
98 | //////
99 |
100 | [Test]
101 | public function add_listener_then_remove_then_dispatch_should_not_call_listener():void
102 | {
103 | var delegate:Function = failIfCalled;
104 | completed.add(delegate);
105 | completed.remove(delegate);
106 | completed.dispatch(new GenericEvent());
107 | }
108 |
109 | private function failIfCalled(e:IEvent):void
110 | {
111 | fail('This event handler should not have been called.');
112 | }
113 |
114 | //////
115 |
116 | [Test]
117 | public function add_2_listeners_remove_2nd_then_dispatch_should_call_1st_not_2nd_listener():void
118 | {
119 | completed.add(async.add(checkGenericEvent, 10));
120 | var delegate:Function = failIfCalled;
121 | completed.add(delegate);
122 | completed.remove(delegate);
123 | completed.dispatch(new GenericEvent());
124 | }
125 | //////
126 | [Test]
127 | public function add_2_listeners_should_yield_length_of_2():void
128 | {
129 | completed.add(newEmptyHandler());
130 | completed.add(newEmptyHandler());
131 | assertEquals(2, completed.numListeners);
132 | }
133 |
134 | private function newEmptyHandler():Function
135 | {
136 | return function(e:*):void {};
137 | }
138 |
139 |
140 | //////
141 | [Test]
142 | public function add_2_listeners_then_remove_1_should_yield_length_of_1():void
143 | {
144 | var firstFunc:Function = newEmptyHandler();
145 | completed.add(firstFunc);
146 | completed.add(newEmptyHandler());
147 |
148 | completed.remove(firstFunc);
149 |
150 | assertEquals(1, completed.numListeners);
151 | }
152 |
153 | [Test]
154 | public function add_2_listeners_then_removeAll_should_yield_length_of_0():void
155 | {
156 | completed.add(newEmptyHandler());
157 | completed.add(newEmptyHandler());
158 |
159 | completed.removeAll();
160 |
161 | assertEquals(0, completed.numListeners);
162 | }
163 |
164 | [Test]
165 | public function add_same_listener_twice_should_only_add_it_once():void
166 | {
167 | var func:Function = newEmptyHandler();
168 | completed.add(func);
169 | completed.add(func);
170 | assertEquals(1, completed.numListeners);
171 | }
172 | //////
173 | [Test]
174 | public function dispatch_object_that_isnt_an_IEvent_should_dispatch_without_error():void
175 | {
176 | completed.addOnce(checkSprite);
177 | // Sprite doesn't have a target property,
178 | // so if the signal tried to set .target,
179 | // an error would be thrown and this test would fail.
180 | completed.dispatch(new Sprite());
181 | }
182 |
183 | private function checkSprite(sprite:Sprite):void
184 | {
185 | assertTrue(sprite is Sprite);
186 | }
187 | //////
188 |
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/GenericEventTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 |
5 | import org.osflash.signals.events.GenericEvent;
6 | import org.osflash.signals.events.IEvent;
7 |
8 | public class GenericEventTest
9 | {
10 | private var instance:GenericEvent;
11 |
12 | [Before]
13 | public function setUp():void
14 | {
15 | instance = new GenericEvent();
16 | }
17 |
18 | [After]
19 | public function tearDown():void
20 | {
21 | instance = null;
22 | }
23 |
24 | public function testInstantiated():void
25 | {
26 | assertTrue("GenericEvent instantiated", instance is GenericEvent);
27 | assertNull('target is null by default', instance.target);
28 | assertFalse('bubbles is false by default', instance.bubbles);
29 | }
30 |
31 | [Test]
32 | public function bubbles_roundtrips_through_constructor():void
33 | {
34 | var bubblingEvent:GenericEvent = new GenericEvent(true);
35 | assertTrue(bubblingEvent.bubbles);
36 | }
37 |
38 | [Test]
39 | public function clone_should_be_instance_of_original_event_class():void
40 | {
41 | var theClone:IEvent = instance.clone();
42 | assertTrue(theClone is GenericEvent);
43 | }
44 |
45 | [Test]
46 | public function clone_non_bubbling_event_should_have_bubbles_false():void
47 | {
48 | var theClone:GenericEvent = GenericEvent(instance.clone());
49 | assertFalse(theClone.bubbles);
50 | }
51 |
52 | [Test]
53 | public function clone_bubbling_event_should_have_bubbles_true():void
54 | {
55 | var bubblingEvent:GenericEvent = new GenericEvent(true);
56 | var theClone:IEvent = bubblingEvent.clone();
57 | assertTrue(theClone.bubbles);
58 | }
59 |
60 |
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/ISignalTestBase.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import flash.events.Event;
7 |
8 | public class ISignalTestBase
9 | {
10 | [Inject]
11 | public var async:IAsync;
12 |
13 | protected var signal:ISignal;
14 |
15 | [After]
16 | public function destroySignal():void
17 | {
18 | signal.removeAll();
19 | signal = null;
20 | }
21 |
22 | [Test]
23 | public function numListeners_is_0_after_creation():void
24 | {
25 | assertEquals(0, signal.numListeners);
26 | }
27 |
28 | [Test]
29 | public function addOnce_and_dispatch_should_remove_listener_automatically():void
30 | {
31 | signal.addOnce(newEmptyHandler());
32 | dispatchSignal();
33 | assertEquals('there should be no listeners', 0, signal.numListeners);
34 | }
35 |
36 | [Test]
37 | public function add_listener_then_remove_then_dispatch_should_not_call_listener():void
38 | {
39 | signal.add(failIfCalled);
40 | signal.remove(failIfCalled);
41 | dispatchSignal();
42 | }
43 |
44 | [Test]
45 | public function add_listener_then_remove_function_not_in_listeners_should_do_nothing():void
46 | {
47 | signal.add(newEmptyHandler());
48 | signal.remove(newEmptyHandler());
49 | assertEquals(1, signal.numListeners);
50 | }
51 |
52 | [Test]
53 | public function add_2_listeners_remove_2nd_then_dispatch_should_call_1st_not_2nd_listener():void
54 | {
55 | var called:Boolean = false;
56 | signal.add(function(e:* = null):void { called = true; });
57 | signal.add(failIfCalled);
58 | signal.remove(failIfCalled);
59 | dispatchSignal();
60 | assertTrue(called);
61 | }
62 |
63 | [Test]
64 | public function add_2_listeners_should_yield_numListeners_of_2():void
65 | {
66 | signal.add(newEmptyHandler());
67 | signal.add(newEmptyHandler());
68 | assertEquals(2, signal.numListeners);
69 | }
70 |
71 | [Test]
72 | public function add_2_listeners_then_remove_1_should_yield_numListeners_of_1():void
73 | {
74 | var firstFunc:Function = newEmptyHandler();
75 | signal.add(firstFunc);
76 | signal.add(newEmptyHandler());
77 | signal.remove(firstFunc);
78 |
79 | assertEquals(1, signal.numListeners);
80 | }
81 |
82 | [Test]
83 | public function add_2_listeners_then_removeAll_should_yield_numListeners_of_0():void
84 | {
85 | signal.add(newEmptyHandler());
86 | signal.add(newEmptyHandler());
87 | signal.removeAll();
88 | assertEquals(0, signal.numListeners);
89 | }
90 |
91 | [Test]
92 | public function add_same_listener_twice_should_only_add_it_once():void
93 | {
94 | var func:Function = newEmptyHandler();
95 | signal.add(func);
96 | signal.add(func);
97 | assertEquals(1, signal.numListeners);
98 | }
99 |
100 | [Test]
101 | public function addOnce_same_listener_twice_should_only_add_it_once():void
102 | {
103 | var func:Function = newEmptyHandler();
104 | signal.addOnce(func);
105 | signal.addOnce(func);
106 | assertEquals(1, signal.numListeners);
107 | }
108 |
109 | [Test]
110 | public function add_two_listeners_and_dispatch_should_call_both():void
111 | {
112 | var calledA:Boolean = false;
113 | var calledB:Boolean = false;
114 | signal.add(function(e:* = null):void { calledA = true; });
115 | signal.add(function(e:* = null):void { calledB = true; });
116 | dispatchSignal();
117 | assertTrue(calledA);
118 | assertTrue(calledB);
119 | }
120 |
121 |
122 | [Test]
123 | public function add_the_same_listener_twice_should_not_throw_error():void
124 | {
125 | var listener:Function = newEmptyHandler();
126 | signal.add(listener);
127 | signal.add(listener);
128 | }
129 |
130 | [Test]
131 | public function dispatch_2_listeners_1st_listener_removes_itself_then_2nd_listener_is_still_called():void
132 | {
133 | signal.add(selfRemover);
134 | // async.add verifies the second listener is called
135 | signal.add(async.add(newEmptyHandler(), 10));
136 | dispatchSignal();
137 | }
138 |
139 | private function selfRemover(e:* = null):void
140 | {
141 | signal.remove(selfRemover);
142 | }
143 |
144 | [Test]
145 | public function dispatch_2_listeners_1st_listener_removes_all_then_2nd_listener_is_still_called():void
146 | {
147 | signal.add(async.add(allRemover, 10));
148 | signal.add(async.add(newEmptyHandler(), 10));
149 | dispatchSignal();
150 | }
151 |
152 | private function allRemover(e:* = null):void
153 | {
154 | signal.removeAll();
155 | }
156 |
157 | [Test]
158 | public function adding_a_listener_during_dispatch_should_not_call_it():void
159 | {
160 | signal.add(async.add(addListenerDuringDispatch, 10));
161 | dispatchSignal();
162 | }
163 |
164 | private function addListenerDuringDispatch(e:* = null):void
165 | {
166 | signal.add(failIfCalled);
167 | }
168 |
169 | //TODO: clarify test purpose through naming and/or implementation
170 | [Test]
171 | public function can_use_anonymous_listeners():void
172 | {
173 | var slots:Array = [];
174 |
175 | for ( var i:int = 0; i < 10; i++ )
176 | {
177 | slots.push(signal.add(newEmptyHandler()));
178 | }
179 | assertEquals("there should be 10 listeners", 10, signal.numListeners);
180 |
181 | for each( var slot:ISlot in slots )
182 | {
183 | signal.remove(slot.listener);
184 | }
185 | assertEquals("all anonymous listeners removed", 0, signal.numListeners);
186 | }
187 |
188 | //TODO: clarify test purpose through naming and/or implementation
189 | [Test]
190 | public function can_use_anonymous_listeners_in_addOnce():void
191 | {
192 | var slots:Array = [];
193 |
194 | for ( var i:int = 0; i < 10; i++ )
195 | {
196 | slots.push(signal.addOnce(newEmptyHandler()));
197 | }
198 | assertEquals("there should be 10 listeners", 10, signal.numListeners);
199 |
200 | for each( var slot:ISlot in slots )
201 | {
202 | signal.remove(slot.listener);
203 | }
204 | assertEquals("all anonymous listeners removed", 0, signal.numListeners);
205 | }
206 |
207 | [Test]
208 | public function add_listener_returns_slot_with_same_listener():void
209 | {
210 | var listener:Function = newEmptyHandler();
211 | var slot:ISlot = signal.add(listener);
212 | assertSame(listener, slot.listener);
213 | }
214 |
215 | [Test]
216 | public function remove_listener_returns_same_slot_as_when_it_was_added():void
217 | {
218 | var listener:Function = newEmptyHandler();
219 | var slot:ISlot = signal.add(listener);
220 | assertSame(slot, signal.remove(listener));
221 | }
222 |
223 | protected function dispatchSignal():void
224 | {
225 | signal.dispatch(new Event('test'));
226 | }
227 |
228 | ////// UTILITY METHODS //////
229 |
230 | protected static function newEmptyHandler():Function
231 | {
232 | return function(e:* = null, ...args):void {};
233 | }
234 |
235 | protected static function failIfCalled(e:* = null):void
236 | {
237 | fail('This function should not have been called.');
238 | }
239 |
240 |
241 | }
242 | }
--------------------------------------------------------------------------------
/tests/org/osflash/signals/MXMLDeluxeSignalTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 |
5 | import org.osflash.signals.events.IEvent;
6 | import org.osflash.signals.support.SpriteWithDeluxeSignals;
7 |
8 | public class MXMLDeluxeSignalTest
9 | {
10 | private var mxmlSprite:SpriteWithDeluxeSignals;
11 |
12 | [Before]
13 | public function setUp():void
14 | {
15 | mxmlSprite = new SpriteWithDeluxeSignals();
16 | }
17 |
18 | [After]
19 | public function tearDown():void
20 | {
21 | mxmlSprite = null;
22 | }
23 |
24 | [Test]
25 | public function mxml_object_has_DeluxeSignals_after_creation():void
26 | {
27 | assertTrue(mxmlSprite.numChildrenChanged is DeluxeSignal);
28 | assertTrue(mxmlSprite.nameChanged is DeluxeSignal);
29 | assertTrue(mxmlSprite.tabEnabledChanged is DeluxeSignal);
30 | assertTrue(mxmlSprite.tabIndexChanged is DeluxeSignal);
31 | }
32 |
33 | [Test]
34 | public function has_single_value_class_from_mxml_default_property():void
35 | {
36 | var valueClasses:Array = mxmlSprite.numChildrenChanged.valueClasses;
37 | assertEquals(1, valueClasses.length);
38 | assertEquals(IEvent, valueClasses[0]);
39 | }
40 |
41 | [Test]
42 | public function has_multiple_value_classes_from_mxml_default_property():void
43 | {
44 | var valueClasses:Array = mxmlSprite.nameChanged.valueClasses;
45 | assertEquals(2, valueClasses.length);
46 | assertEquals(String, valueClasses[0]);
47 | assertEquals(uint, valueClasses[1]);
48 | }
49 |
50 | [Test]
51 | public function has_target_from_mxml_attribute():void
52 | {
53 | assertSame(mxmlSprite, mxmlSprite.numChildrenChanged.target);
54 | }
55 |
56 | [Test]
57 | public function has_single_value_class_from_mxml_attribute():void
58 | {
59 | var valueClasses:Array = mxmlSprite.tabEnabledChanged.valueClasses;
60 | assertEquals(1, valueClasses.length);
61 | assertEquals(Boolean, valueClasses[0]);
62 | }
63 |
64 | [Test]
65 | public function has_multiple_value_classes_from_mxml_attribute():void
66 | {
67 | var valueClasses:Array = mxmlSprite.tabIndexChanged.valueClasses;
68 | assertEquals(2, valueClasses.length);
69 | assertEquals(int, valueClasses[0]);
70 | assertEquals(Boolean, valueClasses[1]);
71 | }
72 |
73 | [Test]
74 | public function add_listener_then_dispatch_calls_listener():void
75 | {
76 | var called:Boolean = false;
77 | var handler:Function = function(newValue:Boolean):void { called = true; };
78 | mxmlSprite.tabEnabledChanged.addOnce(handler);
79 | // when
80 | mxmlSprite.tabEnabledChanged.dispatch(true);
81 | // then
82 | assertTrue(called);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/MXMLSignalTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 |
5 | import org.osflash.signals.support.SpriteWithSignals;
6 |
7 | public class MXMLSignalTest
8 | {
9 | private var mxmlSprite:SpriteWithSignals;
10 |
11 | [Before]
12 | public function setUp():void
13 | {
14 | mxmlSprite = new SpriteWithSignals();
15 | }
16 |
17 | [After]
18 | public function tearDown():void
19 | {
20 | mxmlSprite = null;
21 | }
22 |
23 | [Test]
24 | public function mxml_object_has_Signals_after_creation():void
25 | {
26 | assertTrue(mxmlSprite.numChildrenChanged is Signal);
27 | assertTrue(mxmlSprite.nameChanged is Signal);
28 | assertTrue(mxmlSprite.tabEnabledChanged is Signal);
29 | }
30 |
31 | [Test]
32 | public function has_single_value_class_from_mxml_default_property():void
33 | {
34 | var valueClasses:Array = mxmlSprite.numChildrenChanged.valueClasses;
35 | assertEquals(1, valueClasses.length);
36 | assertEquals(uint, valueClasses[0]);
37 | }
38 |
39 | [Test]
40 | public function has_multiple_value_classes_from_mxml_default_property():void
41 | {
42 | var valueClasses:Array = mxmlSprite.nameChanged.valueClasses;
43 | assertEquals(2, valueClasses.length);
44 | assertEquals(String, valueClasses[0]);
45 | assertEquals(uint, valueClasses[1]);
46 | }
47 |
48 | [Test]
49 | public function has_single_value_class_from_mxml_attribute():void
50 | {
51 | var valueClasses:Array = mxmlSprite.tabEnabledChanged.valueClasses;
52 | assertEquals(1, valueClasses.length);
53 | assertEquals(Boolean, valueClasses[0]);
54 | }
55 |
56 | [Test]
57 | public function has_multiple_value_classes_from_mxml_attribute():void
58 | {
59 | var valueClasses:Array = mxmlSprite.tabIndexChanged.valueClasses;
60 | assertEquals(2, valueClasses.length);
61 | assertEquals(int, valueClasses[0]);
62 | assertEquals(Boolean, valueClasses[1]);
63 | }
64 |
65 | [Test]
66 | public function add_listener_then_dispatch_calls_listener():void
67 | {
68 | var called:Boolean = false;
69 | var handler:Function = function(newValue:Boolean):void { called = true; };
70 | mxmlSprite.tabEnabledChanged.addOnce(handler);
71 | // when
72 | mxmlSprite.tabEnabledChanged.dispatch(true);
73 | // then
74 | assertTrue(called);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/MonoSignalDispatchArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.assertEquals;
4 | import asunit.asserts.assertTrue;
5 | import asunit.framework.IAsync;
6 | /**
7 | * @author Simon Richardson - simon@ustwo.co.uk
8 | */
9 | public class MonoSignalDispatchArgsTest
10 | {
11 |
12 | [Inject]
13 | public var async:IAsync;
14 |
15 | public var completed:MonoSignal;
16 |
17 | [Before]
18 | public function setUp():void
19 | {
20 | completed = new MonoSignal();
21 | }
22 |
23 | [After]
24 | public function tearDown():void
25 | {
26 | completed.removeAll();
27 | completed = null;
28 | }
29 |
30 | [Test]
31 | public function dispatch_two_correct_value_objects_should_succeed():void
32 | {
33 | var signal:Signal = new Signal(String, uint);
34 | signal.dispatch("the Answer", 42);
35 | }
36 |
37 | [Test(expects="ArgumentError")]
38 | public function dispatch_fewer_value_objects_than_value_classes_should_should_throw_ArgumentError():void
39 | {
40 | var signal:Signal = new Signal(Date, Array);
41 | signal.dispatch(new Date());
42 | }
43 |
44 | [Test]
45 | public function dispatch_more_value_objects_than_value_classes_should_succeed():void
46 | {
47 | var signal:Signal = new Signal(Date, Array);
48 | signal.dispatch(new Date(), new Array(), "extra value object");
49 | }
50 |
51 | [Test]
52 | public function dispatch_values_with_no_value_classes_defined_should_pass_to_listener():void
53 | {
54 | var signalNoValueClasses:Signal = new Signal();
55 | signalNoValueClasses.add(async.add(checkDispatchedValues, 10));
56 | signalNoValueClasses.dispatch(22, 'done', new Date());
57 | }
58 |
59 | private function checkDispatchedValues(a:uint, b:String, c:Date):void
60 | {
61 | assertEquals('correct number of arguments were dispatched', 3, arguments.length);
62 | assertEquals('the uint was dispatched', 22, a);
63 | assertEquals('the String was dispatched', 'done', b);
64 | assertTrue('a Date was dispatched', c is Date);
65 | }
66 |
67 | [Test(expects="ArgumentError")]
68 | public function dispatch_one_correct_and_one_incorrect_value_object_should_throw_ArgumentError():void
69 | {
70 | var signal:Signal = new Signal(Date, Array);
71 | signal.dispatch(new Date(), "wrong value type");
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/MonoSignalDispatchExtraArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.assertEquals;
4 | import asunit.asserts.assertTrue;
5 | import asunit.framework.IAsync;
6 | /**
7 | * @author Simon Richardson - simon@ustwo.co.uk
8 | */
9 | public class MonoSignalDispatchExtraArgsTest
10 | {
11 | [Inject]
12 | public var async:IAsync;
13 |
14 | public var completed:MonoSignal;
15 |
16 | [Before]
17 | public function setUp():void
18 | {
19 | completed = new MonoSignal();
20 | }
21 |
22 | [After]
23 | public function tearDown():void
24 | {
25 | completed.removeAll();
26 | completed = null;
27 | }
28 | //////
29 | [Test]
30 | public function dispatch_extra_args_should_call_listener_with_extra_args():void
31 | {
32 | completed.add( async.add(onCompleted, 10) );
33 | completed.dispatch(22, 'done', new Date());
34 | }
35 |
36 | private function onCompleted(a:uint, b:String, c:Date):void
37 | {
38 | assertEquals(3, arguments.length);
39 | assertEquals(22, a);
40 | assertEquals('done', b);
41 | assertTrue(c is Date);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/MonoSignalDispatchNoArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.assertEquals;
4 | import asunit.framework.IAsync;
5 | /**
6 | * @author Simon Richardson - simon@ustwo.co.uk
7 | */
8 | public class MonoSignalDispatchNoArgsTest
9 | {
10 | [Inject]
11 | public var async:IAsync;
12 |
13 | public var completed:MonoSignal;
14 |
15 | [Before]
16 | public function setUp():void
17 | {
18 | completed = new MonoSignal();
19 | }
20 |
21 | [After]
22 | public function tearDown():void
23 | {
24 | completed.removeAll();
25 | completed = null;
26 | }
27 | //////
28 | [Test]
29 | public function dispatch_no_args_should_call_listener_with_no_args():void
30 | {
31 | completed.add( async.add(onCompleted, 10) );
32 | completed.dispatch();
33 | }
34 |
35 | private function onCompleted():void
36 | {
37 | assertEquals(0, arguments.length);
38 | }
39 | //////
40 | [Test]
41 | public function addOnce_in_handler_and_dispatch_should_call_new_listener():void
42 | {
43 | completed.addOnce( async.add(addOnceInHandler, 10) );
44 | completed.dispatch();
45 | }
46 |
47 | protected function addOnceInHandler():void
48 | {
49 | completed.addOnce( async.add(secondAddOnceListener, 10) );
50 | completed.dispatch();
51 | }
52 |
53 | protected function secondAddOnceListener():void
54 | {
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/MonoSignalDispatchNonEventTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.assertEquals;
4 | import asunit.asserts.assertNull;
5 | import asunit.framework.IAsync;
6 | /**
7 | * @author Simon Richardson - simon@ustwo.co.uk
8 | */
9 | public class MonoSignalDispatchNonEventTest
10 | {
11 | [Inject]
12 | public var async:IAsync;
13 |
14 | public var completed:MonoSignal;
15 |
16 | [Before]
17 | public function setUp():void
18 | {
19 | completed = new MonoSignal(Date);
20 | }
21 |
22 | [After]
23 | public function tearDown():void
24 | {
25 | completed.removeAll();
26 | completed = null;
27 | }
28 |
29 | /**
30 | * Captures bug where dispatching 0 was considered null.
31 | */
32 | [Test]
33 | public function dispatch_zero_should_call_listener_with_zero():void
34 | {
35 | completed = new MonoSignal(Number);
36 | completed.add( async.add(onZero, 10) );
37 | completed.dispatch(0);
38 | }
39 |
40 | private function onZero(num:Number):void
41 | {
42 | assertEquals(0, num);
43 | }
44 | //////
45 | [Test]
46 | public function dispatch_2_zeroes_should_call_listener_with_2_zeroes():void
47 | {
48 | completed = new MonoSignal(Number, Number);
49 | completed.add( async.add(onZeroZero, 10) );
50 | completed.dispatch(0, 0);
51 | }
52 |
53 | private function onZeroZero(a:Object, b:Object):void
54 | {
55 | assertEquals(0, a);
56 | assertEquals(0, b);
57 | }
58 | //////
59 | [Test]
60 | public function dispatch_null_should_call_listener_with_null():void
61 | {
62 | completed.addOnce( async.add(checkNullDate, 10) );
63 | completed.dispatch(null);
64 | }
65 |
66 | private function checkNullDate(date:Date):void
67 | {
68 | assertNull(date);
69 | }
70 | //////
71 | [Test]
72 | public function dispatch_null_through_int_Signal_should_be_autoconverted_to_zero():void
73 | {
74 | completed = new MonoSignal(int);
75 | completed.addOnce( async.add(checkNullConvertedToZero, 10) );
76 | completed.dispatch(null);
77 | }
78 |
79 | private function checkNullConvertedToZero(intValue:int):void
80 | {
81 | assertEquals('null was converted to 0', 0, intValue);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/MonoSignalDispatchVarArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.assertEquals;
4 | import asunit.asserts.assertEqualsArrays;
5 | import asunit.framework.IAsync;
6 | /**
7 | * @author Simon Richardson - simon@ustwo.co.uk
8 | */
9 | public class MonoSignalDispatchVarArgsTest
10 | {
11 |
12 | [Inject]
13 | public var async:IAsync;
14 |
15 | public var completed:MonoSignal;
16 |
17 | [Before]
18 | public function setUp():void
19 | {
20 | completed = new MonoSignal(int, int, int, int);
21 | }
22 |
23 | [After]
24 | public function tearDown():void
25 | {
26 | completed.removeAll();
27 | completed = null;
28 | }
29 |
30 | //////
31 |
32 | [Test]
33 | public function adding_vararg_at_0_should_not_throw_error():void
34 | {
35 | completed.add(handlerArgsAt0());
36 | }
37 |
38 | //////
39 |
40 | [Test]
41 | public function adding_vararg_at_1_should_not_throw_error():void
42 | {
43 | completed.add(handlerArgsAt1());
44 | }
45 |
46 | //////
47 |
48 | [Test]
49 | public function adding_vararg_at_2_should_not_throw_error():void
50 | {
51 | completed.add(handlerArgsAt2());
52 | }
53 |
54 | //////
55 |
56 | [Test]
57 | public function adding_vararg_at_0_then_dispatch_should_not_throw_error():void
58 | {
59 | completed.add(handlerArgsAt0());
60 | completed.dispatch(0, 1, 2, 3);
61 | }
62 |
63 | //////
64 |
65 | [Test]
66 | public function adding_vararg_at_1_then_dispatch_should_not_throw_error():void
67 | {
68 | completed.add(handlerArgsAt1());
69 | completed.dispatch(0, 1, 2, 3);
70 | }
71 |
72 | //////
73 |
74 | [Test]
75 | public function adding_vararg_at_2_then_dispatch_should_not_throw_error():void
76 | {
77 | completed.add(handlerArgsAt2());
78 | completed.dispatch(0, 1, 2, 3);
79 | }
80 |
81 | //////
82 |
83 | [Test]
84 | public function verify_num_args_after_dispatch():void
85 | {
86 | completed.add(verifyNumArgs);
87 | completed.dispatch(0, 1, 2, 3);
88 | }
89 |
90 | private function handlerArgsAt0():Function
91 | {
92 | return function(...args):void
93 | {
94 | assertEqualsArrays('Arguments should be [0,1,2,3]', [0,1,2,3], args);
95 | assertEquals('Number of var arguments should be 4', 4, args.length);
96 | };
97 | }
98 |
99 | private function handlerArgsAt1():Function
100 | {
101 | return function(a:int, ...args):void
102 | {
103 | assertEqualsArrays('Arguments should be [1,2,3]', [1,2,3], args);
104 | assertEquals('Number of var arguments should be 3', 3, args.length);
105 | };
106 | }
107 |
108 | private function handlerArgsAt2():Function
109 | {
110 | return function(a:int, b:int, ...args):void
111 | {
112 | assertEqualsArrays('Arguments should be [2,3]', [2,3], args);
113 | assertEquals('Number of var arguments should be 2', 2, args.length);
114 | };
115 | }
116 |
117 | private function verifyNumArgs(...args):void
118 | {
119 | assertEquals('Number of arguments should be 4', 4, args.length);
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/PriorityListenersTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | public class PriorityListenersTest
7 | {
8 | [Inject]
9 | public var async:IAsync;
10 |
11 | public var completed:DeluxeSignal;
12 | private var listenersCalled:Array;
13 |
14 | [Before]
15 | public function setUp():void
16 | {
17 | completed = new DeluxeSignal(this);
18 | listenersCalled = [];
19 | }
20 |
21 | [After]
22 | public function tearDown():void
23 | {
24 | completed.removeAll();
25 | completed = null;
26 | listenersCalled = null;
27 | }
28 | //////
29 | [Test]
30 | public function listener_added_second_with_higher_priority_should_be_called_first():void
31 | {
32 | completed.addWithPriority( async.add(listener1, 5) );
33 | completed.addWithPriority( async.add(listener0, 5), 10 );
34 |
35 | completed.dispatch();
36 | }
37 |
38 | private function listener0():void
39 | {
40 | listenersCalled.push(arguments.callee);
41 | assertSame('this should be the first listener called', arguments.callee, listenersCalled[0]);
42 | }
43 |
44 | private function listener1():void
45 | {
46 | listenersCalled.push(arguments.callee);
47 | assertSame('this should be the second listener called', arguments.callee, listenersCalled[1]);
48 | }
49 |
50 | private function listener2():void
51 | {
52 | listenersCalled.push(arguments.callee);
53 | assertSame('this should be the third listener called', arguments.callee, listenersCalled[2]);
54 | }
55 | //////
56 | [Test]
57 | public function listeners_added_with_same_priority_should_be_called_in_order_added():void
58 | {
59 | completed.addWithPriority( async.add(listener0, 5), 10 );
60 | completed.addWithPriority( async.add(listener1, 5), 10 );
61 | completed.addWithPriority( async.add(listener2, 5), 10 );
62 |
63 | completed.dispatch();
64 | }
65 |
66 |
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/PrioritySignalTestSuite.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | [Suite]
4 | public class PrioritySignalTestSuite
5 | {
6 |
7 | public var _PriorityListenersTest:PriorityListenersTest;
8 | public var _SignalTest:SignalTest;
9 | public var _PrioritySignalTest:PrioritySignalTest;
10 |
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/PrioritySignalTestsRunner.as:
--------------------------------------------------------------------------------
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 PrioritySignalTestsRunner extends MovieClip
9 | {
10 | private var core:TextCore;
11 |
12 | public function PrioritySignalTestsRunner()
13 | {
14 | core = new TextCore();
15 | core.textPrinter.hideLocalPaths = true;
16 | core.start(PrioritySignalTestSuite, null, this);
17 | }
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/PromiseTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import org.hamcrest.assertThat;
4 | import org.hamcrest.object.isTrue;
5 | import org.hamcrest.object.sameInstance;
6 |
7 | public class PromiseTest
8 | {
9 | private var promise:Promise;
10 |
11 | [Before]
12 | public function before():void
13 | {
14 | promise = new Promise();
15 | }
16 |
17 | [Test]
18 | public function addOncedListenerWillExecuteWhenPromiseIsDispatched():void
19 | {
20 | var isCalled:Boolean = false;
21 | function listener():void
22 | {
23 | isCalled = true;
24 | }
25 |
26 | promise.addOnce(listener);
27 | promise.dispatch();
28 |
29 | assertThat(isCalled, isTrue());
30 | }
31 |
32 | [Test]
33 | public function addOncedListenerWillReceiveDataWhenPromiseIsDispatched():void
34 | {
35 | var received:Object;
36 | function listener(data:Object):void
37 | {
38 | received = data;
39 | }
40 |
41 | var object:Object = {hello:"world"};
42 | promise.addOnce(listener);
43 | promise.dispatch(object);
44 |
45 | assertThat(received, sameInstance(object));
46 | }
47 |
48 | [Test]
49 | public function listenerWillExecuteWhenBoundAfterPromiseIsDispatched():void
50 | {
51 | var isCalled:Boolean = false;
52 | function listener():void
53 | {
54 | isCalled = true;
55 | }
56 |
57 | promise.dispatch();
58 | promise.addOnce(listener);
59 |
60 | assertThat(isCalled, isTrue());
61 | }
62 |
63 | [Test]
64 | public function listenerWillReceiveDataWhenBoundAfterPromiseIsDispatched():void
65 | {
66 | var received:Object;
67 | function listener(data:Object):void
68 | {
69 | received = data;
70 | }
71 |
72 | var object:Object = {hello:"world"};
73 | promise.dispatch(object);
74 | promise.addOnce(listener);
75 |
76 | assertThat(received, sameInstance(object));
77 | }
78 |
79 | [Test(expects="flash.errors.IllegalOperationError")]
80 | public function promiseWillThrowErrorIfDispatchedTwice():void
81 | {
82 | promise.dispatch();
83 | promise.dispatch();
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/RedispatchedEventTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import org.osflash.signals.events.GenericEvent;
7 |
8 | public class RedispatchedEventTest
9 | {
10 | [Inject]
11 | public var async:IAsync;
12 |
13 | public var completed:DeluxeSignal;
14 | protected var originalEvent:GenericEvent;
15 |
16 | [Before]
17 | public function setUp():void
18 | {
19 | completed = new DeluxeSignal(this);
20 | }
21 |
22 | [After]
23 | public function tearDown():void
24 | {
25 | completed.removeAll();
26 | completed = null;
27 | }
28 | //////
29 | [Test]
30 | public function dispatch_event_already_dispatched_should_clone_it():void
31 | {
32 | completed.add(async.add(redispatchEvent, 10));
33 | originalEvent = new GenericEvent();
34 | completed.dispatch(originalEvent);
35 | }
36 |
37 | private function redispatchEvent(e:GenericEvent):void
38 | {
39 | DeluxeSignal(e.signal).removeAll();
40 | assertSame(originalEvent, e);
41 | completed.add(async.add(check_redispatched_event_is_not_original, 10));
42 |
43 | completed.dispatch(originalEvent);
44 | }
45 |
46 | private function check_redispatched_event_is_not_original(e:GenericEvent):void
47 | {
48 | assertNotSame(originalEvent, e);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SignalDispatchArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | public class SignalDispatchArgsTest
7 | {
8 | [Inject]
9 | public var async:IAsync;
10 |
11 | public var completed:Signal;
12 |
13 | [Before]
14 | public function setUp():void
15 | {
16 | completed = new Signal();
17 | }
18 |
19 | [After]
20 | public function tearDown():void
21 | {
22 | completed.removeAll();
23 | completed = null;
24 | }
25 |
26 | [Test]
27 | public function dispatch_two_correct_value_objects_should_succeed():void
28 | {
29 | var signal:Signal = new Signal(String, uint);
30 | signal.dispatch("the Answer", 42);
31 | }
32 |
33 | [Test(expects="ArgumentError")]
34 | public function dispatch_fewer_value_objects_than_value_classes_should_should_throw_ArgumentError():void
35 | {
36 | var signal:Signal = new Signal(Date, Array);
37 | signal.dispatch(new Date());
38 | }
39 |
40 | [Test]
41 | public function dispatch_more_value_objects_than_value_classes_should_succeed():void
42 | {
43 | var signal:Signal = new Signal(Date, Array);
44 | signal.dispatch(new Date(), new Array(), "extra value object");
45 | }
46 |
47 | [Test]
48 | public function dispatch_values_with_no_value_classes_defined_should_pass_to_listener():void
49 | {
50 | var signalNoValueClasses:Signal = new Signal();
51 | signalNoValueClasses.add( async.add(checkDispatchedValues, 10) );
52 | signalNoValueClasses.dispatch(22, 'done', new Date());
53 | }
54 |
55 | private function checkDispatchedValues(a:uint, b:String, c:Date):void
56 | {
57 | assertEquals('correct number of arguments were dispatched', 3, arguments.length);
58 | assertEquals('the uint was dispatched', 22, a);
59 | assertEquals('the String was dispatched', 'done', b);
60 | assertTrue('a Date was dispatched', c is Date);
61 | }
62 |
63 | [Test(expects="ArgumentError")]
64 | public function dispatch_one_correct_and_one_incorrect_value_object_should_throw_ArgumentError():void
65 | {
66 | var signal:Signal = new Signal(Date, Array);
67 | signal.dispatch(new Date(), "wrong value type");
68 | }
69 |
70 |
71 |
72 |
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SignalDispatchExtraArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | public class SignalDispatchExtraArgsTest
7 | {
8 | [Inject]
9 | public var async:IAsync;
10 |
11 | public var completed:Signal;
12 |
13 | [Before]
14 | public function setUp():void
15 | {
16 | completed = new Signal();
17 | }
18 |
19 | [After]
20 | public function tearDown():void
21 | {
22 | completed.removeAll();
23 | completed = null;
24 | }
25 | //////
26 | [Test]
27 | public function dispatch_extra_args_should_call_listener_with_extra_args():void
28 | {
29 | completed.add( async.add(onCompleted, 10) );
30 | completed.dispatch(22, 'done', new Date());
31 | }
32 |
33 | private function onCompleted(a:uint, b:String, c:Date):void
34 | {
35 | assertEquals(3, arguments.length);
36 | assertEquals(22, a);
37 | assertEquals('done', b);
38 | assertTrue(c is Date);
39 | }
40 | //////
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SignalDispatchNoArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | public class SignalDispatchNoArgsTest
7 | {
8 | [Inject]
9 | public var async:IAsync;
10 |
11 | public var signal:ISignal;
12 |
13 | [Before]
14 | public function setUp():void
15 | {
16 | signal = new Signal();
17 | }
18 |
19 | [After]
20 | public function tearDown():void
21 | {
22 | signal.removeAll();
23 | signal = null;
24 | }
25 | //////
26 | [Test]
27 | public function dispatch_no_args_should_call_listener_with_no_args():void
28 | {
29 | signal.add( async.add(onCompleted, 10) );
30 | signal.dispatch();
31 | }
32 |
33 | private function onCompleted():void
34 | {
35 | assertEquals(0, arguments.length);
36 | }
37 | //////
38 | [Test]
39 | public function addOnce_in_handler_and_dispatch_should_call_new_listener():void
40 | {
41 | signal.addOnce( async.add(addOnceInHandler, 10) );
42 | signal.dispatch();
43 | }
44 |
45 | protected function addOnceInHandler():void
46 | {
47 | signal.addOnce( async.add(secondAddOnceListener, 10) );
48 | signal.dispatch();
49 | }
50 |
51 | protected function secondAddOnceListener():void
52 | {
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SignalDispatchNonEventTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | public class SignalDispatchNonEventTest
7 | {
8 | [Inject]
9 | public var async:IAsync;
10 |
11 | public var completed:Signal;
12 |
13 | [Before]
14 | public function setUp():void
15 | {
16 | completed = new Signal(Date);
17 | }
18 |
19 | [After]
20 | public function tearDown():void
21 | {
22 | completed.removeAll();
23 | completed = null;
24 | }
25 |
26 | /**
27 | * Captures bug where dispatching 0 was considered null.
28 | */
29 | [Test]
30 | public function dispatch_zero_should_call_listener_with_zero():void
31 | {
32 | completed = new Signal(Number);
33 | completed.add( async.add(onZero, 10) );
34 | completed.dispatch(0);
35 | }
36 |
37 | private function onZero(num:Number):void
38 | {
39 | assertEquals(0, num);
40 | }
41 | //////
42 | [Test]
43 | public function dispatch_2_zeroes_should_call_listener_with_2_zeroes():void
44 | {
45 | completed = new Signal(Number, Number);
46 | completed.add( async.add(onZeroZero, 10) );
47 | completed.dispatch(0, 0);
48 | }
49 |
50 | private function onZeroZero(a:Object, b:Object):void
51 | {
52 | assertEquals(0, a);
53 | assertEquals(0, b);
54 | }
55 | //////
56 | [Test]
57 | public function dispatch_null_should_call_listener_with_null():void
58 | {
59 | completed.addOnce( async.add(checkNullDate, 10) );
60 | completed.dispatch(null);
61 | }
62 |
63 | private function checkNullDate(date:Date):void
64 | {
65 | assertNull(date);
66 | }
67 | //////
68 | [Test]
69 | public function dispatch_null_through_int_Signal_should_be_autoconverted_to_zero():void
70 | {
71 | completed = new Signal(int);
72 | completed.addOnce( async.add(checkNullConvertedToZero, 10) );
73 | completed.dispatch(null);
74 | }
75 |
76 | private function checkNullConvertedToZero(intValue:int):void
77 | {
78 | assertEquals('null was converted to 0', 0, intValue);
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SignalDispatchVarArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.assertEqualsArrays;
4 | import asunit.asserts.assertEquals;
5 |
6 | /**
7 | * @author Simon Richardson - simon@ustwo.co.uk
8 | */
9 | public class SignalDispatchVarArgsTest
10 | {
11 | public var signal:ISignal;
12 |
13 | [Before]
14 | public function setUp():void
15 | {
16 | signal = new Signal(int, int, int, int);
17 | }
18 |
19 | [After]
20 | public function tearDown():void
21 | {
22 | signal.removeAll();
23 | signal = null;
24 | }
25 |
26 | //////
27 |
28 | [Test]
29 | public function adding_vararg_at_0_should_not_throw_error():void
30 | {
31 | signal.add(handlerArgsAt0());
32 | }
33 |
34 | //////
35 |
36 | [Test]
37 | public function adding_vararg_at_1_should_not_throw_error():void
38 | {
39 | signal.add(handlerArgsAt1());
40 | }
41 |
42 | //////
43 |
44 | [Test]
45 | public function adding_vararg_at_2_should_not_throw_error():void
46 | {
47 | signal.add(handlerArgsAt2());
48 | }
49 |
50 | //////
51 |
52 | [Test]
53 | public function adding_vararg_at_0_then_dispatch_should_not_throw_error():void
54 | {
55 | signal.add(handlerArgsAt0());
56 | signal.dispatch(0, 1, 2, 3);
57 | }
58 |
59 | //////
60 |
61 | [Test]
62 | public function adding_vararg_at_1_then_dispatch_should_not_throw_error():void
63 | {
64 | signal.add(handlerArgsAt1());
65 | signal.dispatch(0, 1, 2, 3);
66 | }
67 |
68 | //////
69 |
70 | [Test]
71 | public function adding_vararg_at_2_then_dispatch_should_not_throw_error():void
72 | {
73 | signal.add(handlerArgsAt2());
74 | signal.dispatch(0, 1, 2, 3);
75 | }
76 |
77 | //////
78 |
79 | [Test]
80 | public function verify_num_args_after_dispatch():void
81 | {
82 | signal.add(verifyNumArgs);
83 | signal.dispatch(0, 1, 2, 3);
84 | }
85 |
86 | /////
87 |
88 | [Test]
89 | public function verify_redispatch_of_signal():void
90 | {
91 | const redispatch:Signal = new Signal();
92 | redispatch.add(handlerArgsAt0());
93 |
94 | signal.add(redispatch.dispatch);
95 | signal.dispatch(0, 1, 2, 3);
96 | }
97 |
98 | private function handlerArgsAt0():Function
99 | {
100 | return function(...args):void
101 | {
102 | assertEqualsArrays('Arguments should be [0,1,2,3]', [0,1,2,3], args);
103 | assertEquals('Number of var arguments should be 4', 4, args.length);
104 | };
105 | }
106 |
107 | private function handlerArgsAt1():Function
108 | {
109 | return function(a:int, ...args):void
110 | {
111 | assertEqualsArrays('Arguments should be [1,2,3]', [1,2,3], args);
112 | assertEquals('Number of var arguments should be 3', 3, args.length);
113 | };
114 | }
115 |
116 | private function handlerArgsAt2():Function
117 | {
118 | return function(a:int, b:int, ...args):void
119 | {
120 | assertEqualsArrays('Arguments should be [2,3]', [2,3], args);
121 | assertEquals('Number of var arguments should be 2', 2, args.length);
122 | };
123 | }
124 |
125 | private function verifyNumArgs(...args):void
126 | {
127 | assertEquals('Number of arguments should be 4', 4, args.length);
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SignalTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 |
5 | import org.osflash.signals.events.GenericEvent;
6 |
7 | import flash.display.Sprite;
8 |
9 | public class SignalTest extends ISignalTestBase
10 | {
11 | [Before]
12 | public function setUp():void
13 | {
14 | signal = new Signal();
15 | }
16 |
17 | [Test]
18 | public function dispatch_should_pass_event_to_listener_but_not_set_signal_or_target_properties():void
19 | {
20 | signal.add(async.add(checkGenericEvent, 10));
21 | signal.dispatch(new GenericEvent());
22 | }
23 |
24 | protected function checkGenericEvent(e:GenericEvent):void
25 | {
26 | assertNull('event.signal is not set by Signal', e.signal);
27 | assertNull('event.target is not set by Signal', e.target);
28 | }
29 |
30 | [Test]
31 | public function dispatch_non_IEvent_without_error():void
32 | {
33 | signal.addOnce(checkSprite);
34 | // Sprite doesn't have a target property,
35 | // so if the signal tried to set .target,
36 | // an error would be thrown and this test would fail.
37 | signal.dispatch(new Sprite());
38 | }
39 |
40 | private function checkSprite(sprite:Sprite):void
41 | {
42 | assertTrue(sprite is Sprite);
43 | }
44 |
45 | [Test]
46 | public function adding_dispatch_method_as_listener_does_not_throw_error():void
47 | {
48 | const redispatchSignal:Signal = new Signal(GenericEvent);
49 | signal = new Signal(GenericEvent);
50 | signal.add(redispatchSignal.dispatch);
51 | }
52 |
53 | [Test]
54 | public function slot_params_should_be_sent_through_to_listener():void
55 | {
56 | var listener:Function = function(number:int, string:String, sprite:Sprite):void
57 | {
58 | assertEquals(number, 12345);
59 | assertEquals(string, 'text');
60 | assertEquals(sprite, slot.params[2]);
61 | };
62 |
63 | var slot:ISlot = signal.add(async.add(listener));
64 | slot.params = [12345, 'text', new Sprite()];
65 |
66 | signal.dispatch();
67 | }
68 |
69 | [Test]
70 | public function slot_params_with_with_10_params_should_be_sent_through_to_listener():void
71 | {
72 | // Test the function.apply - maying sure we get everything we ask for.
73 | var listener:Function = function(
74 | number:int,
75 | string:String,
76 | sprite:Sprite,
77 | alpha0:String,
78 | alpha1:String,
79 | alpha2:String,
80 | alpha3:String,
81 | alpha4:String,
82 | alpha5:String,
83 | alpha6:String
84 | ):void
85 | {
86 | assertEquals(number, 12345);
87 | assertEquals(string, 'text');
88 | assertEquals(sprite, slot.params[2]);
89 | assertEquals(alpha0, 'a');
90 | assertEquals(alpha1, 'b');
91 | assertEquals(alpha2, 'c');
92 | assertEquals(alpha3, 'd');
93 | assertEquals(alpha4, 'e');
94 | assertEquals(alpha5, 'f');
95 | assertEquals(alpha6, 'g');
96 | };
97 |
98 | var slot:ISlot = signal.add(async.add(listener));
99 | slot.params = [12345, 'text', new Sprite(), "a", "b", "c", "d", "e", "f", "g"];
100 |
101 | signal.dispatch();
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SignalWithCustomEventTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import org.osflash.signals.events.GenericEvent;
7 |
8 | public class SignalWithCustomEventTest
9 | {
10 | [Inject]
11 | public var async:IAsync;
12 |
13 | public var messaged:Signal;
14 |
15 | [Before]
16 | public function setUp():void
17 | {
18 | messaged = new Signal(MessageEvent);
19 | }
20 |
21 | [After]
22 | public function tearDown():void
23 | {
24 | messaged.removeAll();
25 | messaged = null;
26 | }
27 | //////
28 | [Test]
29 | public function valueClasses_roundtrip_through_constructor():void
30 | {
31 | assertSame(MessageEvent, messaged.valueClasses[0]);
32 | assertEquals(1, messaged.valueClasses.length);
33 | }
34 |
35 | [Test]
36 | public function valueClasses_roundtrip_through_setter():void
37 | {
38 | messaged.valueClasses = [GenericEvent];
39 | assertSame(GenericEvent, messaged.valueClasses[0]);
40 | assertEquals(1, messaged.valueClasses.length);
41 | }
42 |
43 | [Test]
44 | public function valueClasses_setter_clones_the_array():void
45 | {
46 | var newValueClasses:Array = [GenericEvent];
47 | messaged.valueClasses = newValueClasses;
48 | assertNotSame(newValueClasses, messaged.valueClasses);
49 | }
50 |
51 | [Test]
52 | public function add_one_listener_and_dispatch():void
53 | {
54 | messaged.add(async.add(onMessage, 50));
55 | messaged.dispatch(new MessageEvent('ok'));
56 | }
57 |
58 | protected function onMessage(e:MessageEvent):void
59 | {
60 | assertEquals('message value in the event', 'ok', e.message);
61 | }
62 |
63 | [Test(expects="ArgumentError")]
64 | public function dispatch_wrong_event_type_should_throw_ArgumentError():void
65 | {
66 | messaged.dispatch(new GenericEvent());
67 | }
68 |
69 | [Test(expects="ArgumentError")]
70 | public function constructing_signal_with_non_class_should_throw_ArgumentError():void
71 | {
72 | new Signal(new Date());
73 | }
74 |
75 | [Test(expects="ArgumentError")]
76 | public function constructing_signal_with_two_nulls_should_throw_ArgumentError():void
77 | {
78 | new Signal(null, null);
79 | }
80 |
81 | [Test(expects="ArgumentError")]
82 | public function constructing_signal_with_class_and_non_class_should_throw_ArgumentError():void
83 | {
84 | new Signal(Date, 42);
85 | }
86 |
87 | }
88 | }
89 |
90 | import org.osflash.signals.events.GenericEvent;
91 | import org.osflash.signals.events.IEvent;
92 |
93 | ////// PRIVATE CLASSES //////
94 |
95 |
96 | class MessageEvent extends GenericEvent implements IEvent
97 | {
98 | public var message:String;
99 |
100 | public function MessageEvent(message:String)
101 | {
102 | super();
103 | this.message = message;
104 | }
105 |
106 | override public function clone():IEvent
107 | {
108 | return new MessageEvent(message);
109 | }
110 |
111 | }
112 |
113 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SlotListTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import asunit.asserts.*;
4 | import org.osflash.signals.Signal;
5 | import org.osflash.signals.ISlot;
6 | import org.osflash.signals.SlotList;
7 |
8 | public class SlotListTest
9 | {
10 | private var signal:Signal;
11 | private var listenerA:Function;
12 | private var listenerB:Function;
13 | private var listenerC:Function;
14 | private var slotA:ISlot;
15 | private var slotB:ISlot;
16 | private var slotC:ISlot;
17 | private var listOfA:SlotList;
18 | private var listOfAB:SlotList;
19 | private var listOfABC:SlotList;
20 |
21 | [Before]
22 | public function setUp():void
23 | {
24 | signal = new Signal();
25 | listenerA = function(e:* = null):void {};
26 | listenerB = function(e:* = null):void {};
27 | listenerC = function(e:* = null):void {};
28 | slotA = new Slot(listenerA, signal);
29 | slotB = new Slot(listenerB, signal);
30 | slotC = new Slot(listenerC, signal);
31 | listOfA = new SlotList(slotA);
32 | listOfAB = listOfA.append(slotB);
33 | listOfABC = listOfAB.append(slotC);
34 | }
35 |
36 | [Test]
37 | public function NIL_has_length_zero():void
38 | {
39 | assertEquals(0, SlotList.NIL.length);
40 | }
41 |
42 | [Test]
43 | public function tail_defaults_to_NIL_if_omitted_in_constructor():void
44 | {
45 | const noTail:SlotList = new SlotList(slotA);
46 | assertSame(SlotList.NIL, noTail.tail);
47 | }
48 |
49 | [Test]
50 | public function tail_defaults_to_NIL_if_passed_null_in_constructor():void
51 | {
52 | const nullTail:SlotList = new SlotList(slotA, null);
53 | assertSame(SlotList.NIL, nullTail.tail);
54 | }
55 |
56 | [Test(expects="ArgumentError")]
57 | public function constructing_with_null_head_throws_error():void
58 | {
59 | new SlotList(null, listOfA);
60 | }
61 |
62 | [Test]
63 | public function list_with_one_listener_contains_it():void
64 | {
65 | assertTrue(listOfA.contains(listenerA));
66 | }
67 |
68 | [Test]
69 | public function find_the_only_listener_yields_its_slot():void
70 | {
71 | assertSame(slotA, listOfA.find(listenerA));
72 | }
73 |
74 | [Test]
75 | public function list_with_one_listener_has_it_in_its_head():void
76 | {
77 | assertSame(listenerA, listOfA.head.listener);
78 | }
79 |
80 | [Test]
81 | public function NIL_does_not_contain_anonymous_listener():void
82 | {
83 | assertFalse(SlotList.NIL.contains(function():void {}));
84 | }
85 |
86 | [Test]
87 | public function find_in_empty_list_yields_null():void
88 | {
89 | assertNull(SlotList.NIL.find(listenerA));
90 | }
91 |
92 | [Test]
93 | public function NIL_does_not_contain_null_listener():void
94 | {
95 | assertFalse(SlotList.NIL.contains(null));
96 | }
97 |
98 | [Test]
99 | public function find_the_1st_of_2_listeners_yields_its_slot():void
100 | {
101 | assertSame(slotA, listOfAB.find(listenerA));
102 | }
103 |
104 | [Test]
105 | public function find_the_2nd_of_2_listeners_yields_its_slot():void
106 | {
107 | assertSame(slotB, listOfAB.find(listenerB));
108 | }
109 |
110 | [Test]
111 | public function find_the_1st_of_3_listeners_yields_its_slot():void
112 | {
113 | assertSame(slotA, listOfABC.find(listenerA));
114 | }
115 |
116 | [Test]
117 | public function find_the_2nd_of_3_listeners_yields_its_slot():void
118 | {
119 | assertSame(slotB, listOfABC.find(listenerB));
120 | }
121 |
122 | [Test]
123 | public function find_the_3rd_of_3_listeners_yields_its_slot():void
124 | {
125 | assertSame(slotC, listOfABC.find(listenerC));
126 | }
127 |
128 | [Test]
129 | public function prepend_a_slot_makes_it_head_of_new_list():void
130 | {
131 | const newList:SlotList = listOfA.prepend(slotB);
132 | assertSame(slotB, newList.head);
133 | }
134 |
135 | [Test]
136 | public function prepend_a_slot_makes_the_old_list_the_tail():void
137 | {
138 | const newList:SlotList = listOfA.prepend(slotB);
139 | assertSame(listOfA, newList.tail);
140 | }
141 |
142 | [Test]
143 | public function after_prepend_slot_new_list_contains_its_listener():void
144 | {
145 | const newList:SlotList = listOfA.prepend(slotB);
146 | assertTrue(newList.contains(slotB.listener));
147 | }
148 |
149 | [Test]
150 | public function append_a_slot_yields_new_list_with_same_head():void
151 | {
152 | const oldHead:ISlot = listOfA.head;
153 | const newList:SlotList = listOfA.append(slotB);
154 | assertSame(oldHead, newList.head);
155 | }
156 |
157 | [Test]
158 | public function append_to_list_of_one_yields_list_of_length_two():void
159 | {
160 | const newList:SlotList = listOfA.append(slotB);
161 | assertEquals(2, newList.length);
162 | }
163 |
164 | [Test]
165 | public function after_append_slot_new_list_contains_its_listener():void
166 | {
167 | const newList:SlotList = listOfA.append(slotB);
168 | assertTrue(newList.contains(slotB.listener));
169 | }
170 |
171 | [Test]
172 | public function append_slot_yields_a_different_list():void
173 | {
174 | const newList:SlotList = listOfA.append(slotB);
175 | assertNotSame(listOfA, newList);
176 | }
177 |
178 | [Test]
179 | public function append_null_yields_same_list():void
180 | {
181 | const newList:SlotList = listOfA.append(null);
182 | assertSame(listOfA, newList);
183 | }
184 |
185 | [Test]
186 | public function filterNot_on_empty_list_yields_same_list():void
187 | {
188 | const newList:SlotList = SlotList.NIL.filterNot(listenerA);
189 | assertSame(SlotList.NIL, newList);
190 | }
191 |
192 | [Test]
193 | public function filterNot_null_yields_same_list():void
194 | {
195 | const newList:SlotList = listOfA.filterNot(null);
196 | assertSame(listOfA, newList);
197 | }
198 |
199 | [Test]
200 | public function filterNot_head_from_list_of_1_yields_empty_list():void
201 | {
202 | const newList:SlotList = listOfA.filterNot(listOfA.head.listener);
203 | assertSame(SlotList.NIL, newList);
204 | }
205 |
206 | [Test]
207 | public function filterNot_1st_listener_from_list_of_2_yields_list_of_2nd_listener():void
208 | {
209 | const newList:SlotList = listOfAB.filterNot(listenerA);
210 | assertSame(listenerB, newList.head.listener);
211 | assertEquals(1, newList.length);
212 | }
213 |
214 | [Test]
215 | public function filterNot_2nd_listener_from_list_of_2_yields_list_of_head():void
216 | {
217 | const newList:SlotList = listOfAB.filterNot(listenerB);
218 | assertSame(listenerA, newList.head.listener);
219 | assertEquals(1, newList.length);
220 | }
221 |
222 | [Test]
223 | public function filterNot_2nd_listener_from_list_of_3_yields_list_of_1st_and_3rd():void
224 | {
225 | const newList:SlotList = listOfABC.filterNot(listenerB);
226 | assertSame(listenerA, newList.head.listener);
227 | assertSame(listenerC, newList.tail.head.listener);
228 | assertEquals(2, newList.length);
229 | }
230 |
231 | // Issue #56
232 | [Test]
233 | public function insertWithPriority_adds_4_slots_without_losing_any():void
234 | {
235 | var s:PrioritySignal = new PrioritySignal();
236 | var l1:Function = function():void{};
237 | var l2:Function = function():void{};
238 | var l3:Function = function():void{};
239 | var l4:Function = function():void{};
240 | var slot1:ISlot = new Slot(l1, s);
241 | var slot2:ISlot = new Slot(l2, s, false, -1);
242 | var slot3:ISlot = new Slot(l3, s);
243 | var slot4:ISlot = new Slot(l4, s);
244 | var list:SlotList = new SlotList(slot1);
245 | list = list.insertWithPriority(slot2);
246 | list = list.insertWithPriority(slot3);
247 | list = list.insertWithPriority(slot4);
248 | // This was failing because one slot was being lost.
249 | assertEquals("number of slots in list", 4, list.length);
250 | assertEquals(slot1, list.head);
251 | assertEquals(slot3, list.tail.head);
252 | assertEquals(slot4, list.tail.tail.head);
253 | assertEquals(slot2, list.tail.tail.tail.head);
254 | }
255 | }
256 | }
--------------------------------------------------------------------------------
/tests/org/osflash/signals/SlotTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals
2 | {
3 | import org.osflash.signals.events.GenericEvent;
4 | /**
5 | * @author Simon Richardson - simon@ustwo.co.uk
6 | */
7 | public class SlotTest extends ISlotTestBase
8 | {
9 |
10 | [Before]
11 | public function setUp():void
12 | {
13 | signal = new Signal();
14 | }
15 |
16 | [Test]
17 | public function add_listener_pause_then_resume_on_slot_should_dispatch():void
18 | {
19 | var slot:ISlot = signal.add(async.add(checkGenericEvent, 10));
20 | slot.enabled = false;
21 | slot.enabled = true;
22 |
23 | signal.dispatch(new GenericEvent());
24 | }
25 |
26 | [Test]
27 | public function addOnce_listener_pause_then_resume_on_slot_should_dispatch():void
28 | {
29 | var slot:ISlot = signal.addOnce(async.add(checkGenericEvent, 10));
30 | slot.enabled = false;
31 | slot.enabled = true;
32 |
33 | signal.dispatch(new GenericEvent());
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/AmbiguousRelationshipInNativeSignalTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.asserts.*;
4 |
5 | import flash.display.Sprite;
6 | import flash.events.Event;
7 |
8 | public class AmbiguousRelationshipInNativeSignalTest
9 | {
10 | private var target:Sprite;
11 |
12 | private var instance:NativeSignal;
13 |
14 | [Before]
15 | public function setUp():void
16 | {
17 | target = new Sprite();
18 | instance = new NativeSignal(target, Event.CHANGE);
19 | }
20 |
21 | [After]
22 | public function tearDown():void
23 | {
24 | instance = null;
25 | }
26 |
27 | [Test(expects="flash.errors.IllegalOperationError")]
28 | public function add_then_addOnce_throws_error():void
29 | {
30 | instance.add(failIfCalled);
31 | instance.addOnce(failIfCalled);
32 | }
33 |
34 | [Test(expects="flash.errors.IllegalOperationError")]
35 | public function addOnce_then_add_should_throw_error():void
36 | {
37 | instance.addOnce(failIfCalled);
38 | instance.add(failIfCalled);
39 | }
40 |
41 | [Test]
42 | public function add_then_add_should_not_throw_error():void
43 | {
44 | instance.add(failIfCalled);
45 | instance.add(failIfCalled);
46 | assertEquals(1, instance.numListeners);
47 | }
48 |
49 | [Test]
50 | public function addOnce_then_addOnce_should_not_throw_error():void
51 | {
52 | instance.addOnce(failIfCalled);
53 | instance.addOnce(failIfCalled);
54 | assertEquals(1, instance.numListeners);
55 | }
56 |
57 | private function failIfCalled(event:Event):void
58 | {
59 | fail("if this listener is called, something horrible is going on");
60 | }
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/MXMLNativeSignalTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.asserts.*;
4 | import flash.events.Event;
5 | import flash.events.MouseEvent;
6 | import org.osflash.signals.support.SpriteWithNativeSignals;
7 |
8 | import flash.display.Sprite;
9 |
10 | public class MXMLNativeSignalTest
11 | {
12 | [Inject] public var context:Sprite;
13 |
14 | private var mxmlSprite:SpriteWithNativeSignals;
15 |
16 | [Before]
17 | public function setUp():void
18 | {
19 | mxmlSprite = new SpriteWithNativeSignals();
20 | }
21 |
22 | [After]
23 | public function tearDown():void
24 | {
25 | mxmlSprite = null;
26 | }
27 |
28 | [Test]
29 | public function mxml_object_has_NativeSignals_after_creation():void
30 | {
31 | assertTrue(mxmlSprite.clicked is NativeSignal);
32 | assertTrue(mxmlSprite.doubleClicked is NativeSignal);
33 | assertTrue(mxmlSprite.addedToStage is NativeSignal);
34 | }
35 |
36 | [Test]
37 | public function has_eventClass_from_mxml_default_property():void
38 | {
39 | assertEquals(MouseEvent, mxmlSprite.clicked.eventClass);
40 | }
41 |
42 | [Test]
43 | public function has_eventType_from_mxml_attribute():void
44 | {
45 | assertEquals(MouseEvent.CLICK, mxmlSprite.clicked.eventType);
46 | }
47 |
48 | [Test]
49 | public function has_target_from_mxml_attribute():void
50 | {
51 | assertEquals(mxmlSprite, mxmlSprite.clicked.target);
52 | }
53 |
54 | [Test]
55 | public function has_eventClass_from_mxml_attribute():void
56 | {
57 | assertEquals(MouseEvent, mxmlSprite.doubleClicked.eventClass);
58 | }
59 |
60 | [Test]
61 | public function omitted_eventClass_defaults_to_Event():void
62 | {
63 | assertEquals(Event, mxmlSprite.addedToStage.eventClass);
64 | }
65 |
66 | [Test]
67 | public function add_listener_then_dispatch_calls_listener():void
68 | {
69 | var called:Boolean = false;
70 | var handler:Function = function(event:Event):void { called = true; };
71 | mxmlSprite.addedToStage.addOnce(handler);
72 | // when
73 | context.addChild(mxmlSprite);
74 | // then
75 | assertTrue(called);
76 | context.removeChild(mxmlSprite);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/NativeMappedSignalBoundaryUseTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import org.osflash.signals.IPrioritySignal;
7 |
8 | import flash.display.Sprite;
9 | import flash.events.MouseEvent;
10 |
11 | public class NativeMappedSignalBoundaryUseTest
12 | {
13 | [Inject]
14 | public var async:IAsync;
15 |
16 | private var signalArrayOfFunctions:NativeMappedSignal;
17 | private var signalPassArray:NativeMappedSignal;
18 | private var signalPassArrayThroughFunction:NativeMappedSignal;
19 | private var sprite:Sprite;
20 | private const EventType:String = MouseEvent.CLICK;
21 | private const func1:Function = function ():String { return 'mapped arg 1'; };
22 | private const func2:Function = function ():String { return 'mapped arg 2'; };
23 | private const MappedArray:Array = [0, 1];
24 |
25 | [Before]
26 | public function setUp():void
27 | {
28 | sprite = new Sprite();
29 | signalArrayOfFunctions = new NativeMappedSignal(sprite, EventType).mapTo(func1, func2);
30 | signalPassArray = new NativeMappedSignal(sprite, EventType).mapTo(MappedArray);
31 | signalPassArrayThroughFunction = new NativeMappedSignal(sprite, EventType, MouseEvent, Array).mapTo(
32 | function ():Array {
33 | return MappedArray;
34 | }
35 | );
36 | }
37 |
38 | [After]
39 | public function tearDown():void
40 | {
41 | signalArrayOfFunctions.removeAll();
42 | signalArrayOfFunctions = null;
43 | signalPassArray.removeAll();
44 | signalPassArray = null;
45 | signalPassArrayThroughFunction.removeAll();
46 | signalPassArrayThroughFunction = null;
47 | }
48 |
49 | [Test]
50 | public function testInstantiated():void
51 | {
52 | assertFalse('sprite has no click event listener to start', sprite.hasEventListener(EventType));
53 |
54 | assertTrue("NativeMappedSignal instantiated", signalArrayOfFunctions is NativeMappedSignal);
55 | assertTrue('implements ISignal', signalArrayOfFunctions is IPrioritySignal);
56 | assertSame('has no value classes', 0, signalArrayOfFunctions.valueClasses.length);
57 |
58 | assertTrue("NativeMappedSignal instantiated", signalPassArray is NativeMappedSignal);
59 | assertTrue('implements IPrioritySignal', signalPassArray is IPrioritySignal);
60 | assertSame('has no value classed', 0, signalPassArray.valueClasses.length);
61 |
62 | assertTrue("NativeMappedSignal instantiated", signalPassArrayThroughFunction is NativeMappedSignal);
63 | assertTrue('implements IPrioritySignal', signalPassArrayThroughFunction is IPrioritySignal);
64 | assertSame('has only one value class', 1, signalPassArrayThroughFunction.valueClasses.length);
65 | assertSame('single value class is of type Array', Array, signalPassArrayThroughFunction.valueClasses[0]);
66 | }
67 | //////
68 | [Test]
69 | public function signal_array_of_functions_add_then_callback_called():void
70 | {
71 | signalArrayOfFunctions.add( async.add(callbackTwoFunctions, 10) );
72 | sprite.dispatchEvent(new MouseEvent(EventType));
73 | }
74 |
75 | private function callbackTwoFunctions(argFunc1:Function, argFunc2:Function):void
76 | {
77 | assertSame(func1, argFunc1);
78 | assertSame(func2, argFunc2);
79 | }
80 |
81 | [Test]
82 | public function signal_pass_array_add_then_array_callback_should_be_called():void
83 | {
84 | signalPassArray.add( async.add(callbackArrayAsArg, 10) );
85 | sprite.dispatchEvent(new MouseEvent(EventType));
86 | }
87 |
88 | private function callbackArrayAsArg(argArray:Array):void
89 | {
90 | assertSame(MappedArray, argArray);
91 | }
92 |
93 | [Test]
94 | public function signal_pass_array_through_function_add_then_array_callback_should_be_called():void
95 | {
96 | signalPassArrayThroughFunction.add( async.add(callbackArrayAsArg, 10) );
97 | sprite.dispatchEvent(new MouseEvent(EventType));
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/NativeMappedSignalDefaultsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.framework.IAsync;
4 |
5 | import flash.display.Sprite;
6 | import flash.events.MouseEvent;
7 |
8 | public class NativeMappedSignalDefaultsTest
9 | {
10 | [Inject]
11 | public var async:IAsync;
12 |
13 | private var signalDefault:NativeMappedSignal;
14 | private var signalDefaultWithMappingObject:NativeMappedSignal;
15 | private var signalDefaultWithMappingFunction:NativeMappedSignal;
16 | private var signalWithValueClassesWithoutMappingFunction:NativeMappedSignal;
17 | private var sprite:Sprite;
18 | private const EventType:String = MouseEvent.CLICK;
19 | private const MappedObject:String = "mapped " + EventType;
20 |
21 | [Before]
22 | public function setUp():void
23 | {
24 | sprite = new Sprite();
25 | signalDefault = new NativeMappedSignal(sprite, EventType);
26 | signalDefaultWithMappingObject = new NativeMappedSignal(sprite, EventType).mapTo(MappedObject);
27 | signalDefaultWithMappingFunction = new NativeMappedSignal(sprite, EventType).mapTo(
28 | function ():String {
29 | return MappedObject;
30 | }
31 | );
32 | signalWithValueClassesWithoutMappingFunction = new NativeMappedSignal(sprite, EventType, MouseEvent, String);
33 | }
34 |
35 | [After]
36 | public function tearDown():void
37 | {
38 | signalDefault.removeAll();
39 | signalDefault = null;
40 | signalDefaultWithMappingObject.removeAll();
41 | signalDefaultWithMappingObject = null;
42 | signalDefaultWithMappingFunction.removeAll();
43 | signalDefaultWithMappingFunction = null;
44 | signalWithValueClassesWithoutMappingFunction.removeAll();
45 | signalWithValueClassesWithoutMappingFunction = null;
46 | }
47 |
48 | //////
49 | [Test]
50 | public function signal_default_add_then_emptyCallback_should_be_called():void
51 | {
52 | signalDefault.add( async.add(emptyCallback, 10) );
53 | sprite.dispatchEvent(new MouseEvent(EventType));
54 | }
55 |
56 | private function emptyCallback(e:* = null):void {}
57 |
58 | [Test]
59 | public function signal_default_with_mapped_object_add_then_emptyCallback_should_be_called():void
60 | {
61 | signalDefaultWithMappingObject.add( async.add(emptyCallback, 10) );
62 | sprite.dispatchEvent(new MouseEvent(EventType));
63 | }
64 |
65 | [Test]
66 | public function signal_default_with_mapped_function_add_then_emptyCallback_should_be_called():void
67 | {
68 | signalDefaultWithMappingFunction.add( async.add(emptyCallback, 10) );
69 | sprite.dispatchEvent(new MouseEvent(EventType));
70 | }
71 |
72 | [Test(expects="ArgumentError")]
73 | public function signal_with_value_classes_without_mapping_function():void
74 | {
75 | signalWithValueClassesWithoutMappingFunction.dispatch(new MouseEvent(EventType));
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/NativeMappedSignalFunctionArgTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import org.osflash.signals.IPrioritySignal;
7 |
8 | import flash.display.Sprite;
9 | import flash.events.Event;
10 | import flash.events.MouseEvent;
11 |
12 | public class NativeMappedSignalFunctionArgTest
13 | {
14 | [Inject]
15 | public var async:IAsync;
16 |
17 | private var signal:NativeMappedSignal;
18 | private var signalMappingToEventType:NativeMappedSignal;
19 | private var signalMappingToIncorrectEventType:NativeMappedSignal;
20 | private var signalMappingToVoid:NativeMappedSignal;
21 | private var sprite:Sprite;
22 | private const EventType:String = MouseEvent.CLICK;
23 | private const MappedObject:String = "mapped " + EventType;
24 |
25 | [Before]
26 | public function setUp():void
27 | {
28 | sprite = new Sprite();
29 | signal = new NativeMappedSignal(sprite, EventType, MouseEvent, String).mapTo(
30 | function ():String {
31 | return MappedObject;
32 | }
33 | );
34 |
35 | signalMappingToEventType = new NativeMappedSignal(sprite, EventType, MouseEvent, String).mapTo(
36 | function (event:MouseEvent):String {
37 | return event.type;
38 | }
39 | );
40 |
41 | signalMappingToIncorrectEventType = new NativeMappedSignal(sprite, EventType, MouseEvent, String).mapTo(
42 | function (event:MouseEvent):int {
43 | return event.delta;
44 | }
45 | );
46 |
47 | signalMappingToVoid = new NativeMappedSignal(sprite, EventType).mapTo(function ():void {});
48 | }
49 |
50 | [After]
51 | public function tearDown():void
52 | {
53 | signal.removeAll();
54 | signal = null;
55 | signalMappingToEventType.removeAll();
56 | signalMappingToEventType = null;
57 | signalMappingToIncorrectEventType.removeAll();
58 | signalMappingToIncorrectEventType = null;
59 | signalMappingToVoid.removeAll();
60 | signalMappingToVoid = null;
61 | }
62 |
63 | [Test]
64 | public function testInstantiated():void
65 | {
66 | assertFalse('sprite has no click event listener to start', sprite.hasEventListener(EventType));
67 |
68 | assertTrue("NativeMappedSignal instantiated", signal is NativeMappedSignal);
69 | assertTrue('implements IPrioritySignal', signal is IPrioritySignal);
70 | assertSame('has only one value class', 1, signal.valueClasses.length);
71 | assertSame('single value class is of type String', String, signal.valueClasses[0]);
72 |
73 | assertTrue("NativeMappedSignal instantiated", signalMappingToEventType is NativeMappedSignal);
74 | assertTrue('implements IPrioritySignal', signalMappingToEventType is IPrioritySignal);
75 | assertSame('has only one value class', 1, signalMappingToEventType.valueClasses.length);
76 | assertSame('single value class is of type String', String, signalMappingToEventType.valueClasses[0]);
77 |
78 | assertTrue("NativeMappedSignal instantiated", signalMappingToIncorrectEventType is NativeMappedSignal);
79 | assertTrue('implements IPrioritySignal', signalMappingToIncorrectEventType is IPrioritySignal);
80 | assertSame('has only one value class', 1, signalMappingToIncorrectEventType.valueClasses.length);
81 | assertSame('single value class is of type String', String, signalMappingToIncorrectEventType.valueClasses[0]);
82 |
83 | assertTrue("NativeMappedSignal instantiated", signalMappingToVoid is NativeMappedSignal);
84 | assertTrue('implements IPrioritySignal', signalMappingToVoid is IPrioritySignal);
85 | assertSame('has no value classes', 0, signalMappingToVoid.valueClasses.length);
86 | }
87 |
88 | private function dispatchTestEvent():void
89 | {
90 | sprite.dispatchEvent(buildTestEvent());
91 | }
92 |
93 | private function buildTestEvent():Event
94 | {
95 | return new MouseEvent(EventType);
96 | }
97 |
98 | //////
99 | [Test]
100 | public function signal_add_then_mapped_object_should_be_callback_argument():void
101 | {
102 | signal.add( async.add(checkMappedArgument, 10) );
103 | dispatchTestEvent();
104 | }
105 |
106 | private function checkMappedArgument(argument:String):void
107 | {
108 | assertSame(MappedObject, argument);
109 | }
110 | //////
111 | [Test]
112 | public function mapping_function_should_receive_event_as_argument():void
113 | {
114 | signalMappingToEventType.add( async.add(checkMappedEventTypeArgument, 10) );
115 | dispatchTestEvent();
116 | }
117 |
118 | private function checkMappedEventTypeArgument(argument:String):void
119 | {
120 | assertSame(EventType, argument);
121 | }
122 |
123 | [Test(expects="ArgumentError")]
124 | public function mapping_function_has_to_many_arguments_should_throw_ArgumentError():void
125 | {
126 | new NativeMappedSignal(sprite, EventType, MouseEvent, String).mapTo(
127 | function (event:MouseEvent, extraArg:Object):String {
128 | return event.type;
129 | }
130 | );
131 | }
132 |
133 | [Test(expects="Error")]
134 | public function mapping_function_returns_incorrectly_typed_argument_should_throw_Error():void
135 | {
136 | signalMappingToIncorrectEventType.dispatch(buildTestEvent());
137 | }
138 |
139 | private function emptyHandler(argument:String):void {}
140 |
141 | [Test]
142 | public function mapping_to_void():void
143 | {
144 | signalMappingToVoid.add(async.add(emptyHandler, 10));
145 | dispatchTestEvent();
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/NativeMappedSignalFunctionNoArgsTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import org.osflash.signals.IPrioritySignal;
7 |
8 | import flash.display.Sprite;
9 | import flash.events.MouseEvent;
10 |
11 | public class NativeMappedSignalFunctionNoArgsTest
12 | {
13 | [Inject]
14 | public var async:IAsync;
15 |
16 | private var signalSingle:NativeMappedSignal;
17 | private var signalList:NativeMappedSignal;
18 | private var sprite:Sprite;
19 | private const EventType:String = MouseEvent.CLICK;
20 | private const MappedObject:String = "mapped " + EventType;
21 | private const MappedObject2:int = 3;
22 | private const MappedObject3:Number = 3.1415;
23 |
24 | [Before]
25 | public function setUp():void
26 | {
27 | sprite = new Sprite();
28 | signalSingle = new NativeMappedSignal(sprite, EventType, MouseEvent, String).mapTo(
29 | function ():String {
30 | return MappedObject;
31 | }
32 | );
33 |
34 | signalList = new NativeMappedSignal(sprite, EventType, MouseEvent, String, int, Number).mapTo(
35 | function ():Array
36 | {
37 | return [MappedObject, MappedObject2, MappedObject3];
38 | }
39 | );
40 | }
41 |
42 | [After]
43 | public function tearDown():void
44 | {
45 | signalSingle.removeAll();
46 | signalSingle = null;
47 | signalList.removeAll();
48 | signalList = null;
49 | }
50 |
51 | [Test]
52 | public function testInstantiated():void
53 | {
54 | assertFalse('sprite has no click event listener to start', sprite.hasEventListener(EventType));
55 |
56 | assertTrue("NativeMappedSignal instantiated", signalSingle is NativeMappedSignal);
57 | assertTrue('implements IPrioritySignal', signalSingle is IPrioritySignal);
58 | assertSame('has only one value class', 1, signalSingle.valueClasses.length);
59 | assertSame('single value class is of type String', String, signalSingle.valueClasses[0]);
60 |
61 | assertTrue("NativeMappedSignal instantiated", signalList is NativeMappedSignal);
62 | assertTrue('implements IPrioritySignal', signalList is IPrioritySignal);
63 | assertSame('has three value classes', 3, signalList.valueClasses.length);
64 | assertSame('first value class is of type String', String, signalList.valueClasses[0]);
65 | assertSame('second value class is of type int', int, signalList.valueClasses[1]);
66 | assertSame('third value class is of type Number', Number, signalList.valueClasses[2]);
67 | }
68 | //////
69 | [Test]
70 | public function signal_add_then_mapped_object_should_be_callback_argument():void
71 | {
72 | signalSingle.add( async.add(checkMappedArgumentSingle, 10) );
73 | sprite.dispatchEvent(new MouseEvent(EventType));
74 | }
75 |
76 | private function checkMappedArgumentSingle(argument:String):void
77 | {
78 | assertSame(MappedObject, argument);
79 | }
80 | //////
81 | [Test]
82 | public function signal_list_add_then_mapped_object_should_be_callback_argument():void
83 | {
84 | signalList.add( async.add(checkMappedArgumentList, 10) );
85 | sprite.dispatchEvent(new MouseEvent(EventType));
86 | }
87 |
88 | private function checkMappedArgumentList(argument1:String, argument2:int, argument3:Number):void
89 | {
90 | assertSame(MappedObject, argument1);
91 | assertSame(MappedObject2, argument2);
92 | assertSame(MappedObject3, argument3);
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/NativeMappedSignalObjectArgTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.asserts.*;
4 | import asunit.framework.IAsync;
5 |
6 | import org.osflash.signals.IPrioritySignal;
7 |
8 | import flash.display.Sprite;
9 | import flash.events.MouseEvent;
10 |
11 | public class NativeMappedSignalObjectArgTest
12 | {
13 | [Inject]
14 | public var async:IAsync;
15 |
16 | private var signalSingle:NativeMappedSignal;
17 | private var signalList:NativeMappedSignal;
18 | private var sprite:Sprite;
19 | private const EventType:String = MouseEvent.CLICK;
20 | private const MappedObject:String = "mapped " + EventType;
21 | private const MappedObject2:int = 3;
22 | private const MappedObject3:Number = 3.1415;
23 |
24 | [Before]
25 | public function setUp():void
26 | {
27 | sprite = new Sprite();
28 | signalSingle = new NativeMappedSignal(sprite, EventType, MouseEvent, String).mapTo(MappedObject);
29 | signalList = new NativeMappedSignal(sprite, EventType, MouseEvent, String, int, Number).mapTo(MappedObject, MappedObject2, MappedObject3);
30 | }
31 |
32 | [After]
33 | public function tearDown():void
34 | {
35 | signalSingle.removeAll();
36 | signalSingle = null;
37 | signalList.removeAll();
38 | signalList = null;
39 | }
40 |
41 | [Test]
42 | public function testInstantiated():void
43 | {
44 | assertFalse('sprite has no click event listener to start', sprite.hasEventListener(EventType));
45 |
46 | assertTrue("NativeMappedSignal instantiated", signalSingle is NativeMappedSignal);
47 | assertTrue('implements ISignal', signalSingle is IPrioritySignal);
48 | assertSame('has only one value class', 1, signalSingle.valueClasses.length);
49 | assertSame('single value class is of type String', String, signalSingle.valueClasses[0]);
50 |
51 | assertTrue("NativeMappedSignal instantiated", signalList is NativeMappedSignal);
52 | assertTrue('implements IPrioritySignal', signalList is IPrioritySignal);
53 | assertSame('has three value classes', 3, signalList.valueClasses.length);
54 | assertSame('first value class is of type String', String, signalList.valueClasses[0]);
55 | assertSame('second value class is of type int', int, signalList.valueClasses[1]);
56 | assertSame('third value class is of type Number', Number, signalList.valueClasses[2]);
57 | }
58 | //////
59 | [Test]
60 | public function signal_single_add_then_mapped_object_should_be_callback_argument():void
61 | {
62 | signalSingle.add( async.add(checkMappedArgumentSingle, 10) );
63 | sprite.dispatchEvent(new MouseEvent(EventType));
64 | }
65 |
66 | private function checkMappedArgumentSingle(argument:String):void
67 | {
68 | assertSame(MappedObject, argument);
69 | }
70 | //////
71 | [Test]
72 | public function signal_list_add_then_mapped_object_should_be_callback_argument():void
73 | {
74 | signalList.add( async.add(checkMappedArgumentList, 10) );
75 | sprite.dispatchEvent(new MouseEvent(EventType));
76 | }
77 |
78 | private function checkMappedArgumentList(argument1:String, argument2:int, argument3:Number):void
79 | {
80 | assertSame(MappedObject, argument1);
81 | assertSame(MappedObject2, argument2);
82 | assertSame(MappedObject3, argument3);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/NativeRelaySignalTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.asserts.*;
4 |
5 | import flash.display.Sprite;
6 | import flash.events.Event;
7 | import flash.events.EventDispatcher;
8 | import flash.events.MouseEvent;
9 |
10 | public class NativeRelaySignalTest extends INativeDispatcherTestBase
11 | {
12 | [Before]
13 | public function setUp():void
14 | {
15 | sprite = new Sprite();
16 | clicked = new NativeRelaySignal(sprite, 'click', MouseEvent);
17 | signal = new NativeRelaySignal(new EventDispatcher(), 'test', Event);
18 | }
19 |
20 | [After]
21 | public function tearDown():void
22 | {
23 | clicked.removeAll();
24 | clicked = null;
25 | }
26 |
27 | [Test]
28 | public function setting_eventClass_to_null_defaults_it_to_Event():void
29 | {
30 | NativeRelaySignal(clicked).eventClass = null;
31 | clicked.dispatch(new Event('click'));
32 | assertSame(Event, clicked.eventClass);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/NativeSignalSlotTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import org.osflash.signals.ISlotTestBase;
4 |
5 | import flash.display.Sprite;
6 | import flash.events.Event;
7 | import flash.events.IEventDispatcher;
8 | /**
9 | * @author Simon Richardson - me@simonrichardson.info
10 | */
11 | public class NativeSignalSlotTest extends ISlotTestBase
12 | {
13 | private var sprite:IEventDispatcher;
14 |
15 | [Before]
16 | public function setUp():void
17 | {
18 | sprite = new Sprite();
19 | signal = new NativeSignal(sprite, 'click', Event);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/NativeSignalTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives
2 | {
3 | import asunit.asserts.*;
4 |
5 | import flash.display.Sprite;
6 | import flash.events.Event;
7 | import flash.events.EventDispatcher;
8 | import flash.events.MouseEvent;
9 |
10 | public class NativeSignalTest extends INativeDispatcherTestBase
11 | {
12 | [Before]
13 | public function setUp():void
14 | {
15 | sprite = new Sprite();
16 | clicked = new NativeSignal(sprite, 'click', MouseEvent);
17 | signal = new NativeSignal(new EventDispatcher(), 'test', Event);
18 | }
19 |
20 | [After]
21 | public function tearDown():void
22 | {
23 | clicked.removeAll();
24 | clicked = null;
25 | }
26 |
27 | [Test]
28 | public function setting_eventClass_to_null_defaults_it_to_Event():void
29 | {
30 | NativeSignal(clicked).eventClass = null;
31 | // This was causing a null exception: Issue #32.
32 | clicked.dispatch(new Event('click'));
33 | assertSame(Event, clicked.eventClass);
34 | }
35 |
36 | [Test]
37 | public function adding_listener_with_no_args_does_not_throw_error():void
38 | {
39 | clicked.add(function():void {});
40 | }
41 |
42 | [Test]
43 | public function adding_listener_with_varargs_does_not_throw_error():void
44 | {
45 | clicked.add(function(...args):void {});
46 | }
47 |
48 | [Test]
49 | public function adding_listener_with_more_than_one_arg_does_not_throw_error():void
50 | {
51 | clicked.add(function(a:*, b:*):void { } );
52 | }
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/base/SignalSpriteTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.base
2 | {
3 | import asunit.asserts.assertEquals;
4 | import asunit.asserts.assertSame;
5 | import asunit.asserts.assertTrue;
6 | import asunit.framework.IAsync;
7 |
8 | import org.osflash.signals.natives.sets.InteractiveObjectSignalSet;
9 |
10 | import flash.events.MouseEvent;
11 |
12 | public class SignalSpriteTest
13 | {
14 | [Inject]
15 | public var async:IAsync;
16 |
17 | private var sprite:SignalSprite;
18 |
19 | [Before]
20 | public function setUp():void
21 | {
22 | sprite = new SignalSprite();
23 | }
24 |
25 | [After]
26 | public function tearDown():void
27 | {
28 | sprite.signals.removeAll();
29 | sprite = null;
30 | }
31 |
32 | [Test]
33 | public function has_signals_after_creation():void
34 | {
35 | assertTrue(sprite.signals is InteractiveObjectSignalSet);
36 | }
37 |
38 | [Test]
39 | public function numListeners_is_0_after_creation():void
40 | {
41 | assertEquals(sprite.signals.numListeners, 0);
42 | }
43 |
44 | [Test]
45 | public function signal_add_then_EventDispatcher_dispatch_should_call_signal_listener():void
46 | {
47 | sprite.signals.click.add( async.add(checkClickEvent) );
48 | sprite.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
49 | }
50 |
51 | private function checkClickEvent(event:MouseEvent):void
52 | {
53 | assertSame(MouseEvent.CLICK, event.type);
54 | assertSame(sprite, event.target);
55 | }
56 |
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/sets/EventDispatcherSignalSetTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets
2 | {
3 | import org.osflash.signals.ISlot;
4 | import asunit.asserts.fail;
5 | import asunit.asserts.assertNotNull;
6 | import asunit.asserts.assertSame;
7 | import asunit.asserts.assertTrue;
8 | import asunit.framework.IAsync;
9 |
10 | import flash.display.Sprite;
11 | import flash.events.Event;
12 | /**
13 | * @author Simon Richardson - simon@ustwo.co.uk
14 | */
15 | public class EventDispatcherSignalSetTest
16 | {
17 |
18 | [Inject]
19 | public var async:IAsync;
20 |
21 | private var sprite:Sprite;
22 |
23 | private var signalSet:EventDispatcherSignalSet;
24 |
25 | [Before]
26 | public function setUp():void
27 | {
28 | sprite = new Sprite();
29 | signalSet = new EventDispatcherSignalSet(sprite);
30 | }
31 |
32 | [After]
33 | public function tearDown():void
34 | {
35 | signalSet.removeAll();
36 | signalSet = null;
37 | sprite = null;
38 | }
39 |
40 |
41 | protected function newEmptyHandler():Function
42 | {
43 | return function(e:*):void {};
44 | }
45 |
46 | private function handleEvent(event:Event):void
47 | {
48 | assertSame(sprite, event.target);
49 | }
50 |
51 | protected function failIfCalled(e:Event):void
52 | {
53 | fail('This event handler should not have been called.');
54 | }
55 |
56 | //////
57 |
58 | [Test]
59 | public function numListeners_should_be_zero():void
60 | {
61 | assertTrue('Number of listeners should be 0.', signalSet.numListeners == 0);
62 | }
63 |
64 | //////
65 |
66 | [Test]
67 | public function signals_should_be_not_null():void
68 | {
69 | assertNotNull('Signals should not be null.', signalSet.signals);
70 | }
71 |
72 | //////
73 |
74 | [Test]
75 | public function signals_length_should_be_empty():void
76 | {
77 | assertTrue('Signals length should be 0.', signalSet.signals.length == 0);
78 | }
79 |
80 | //////
81 |
82 | [Test]
83 | public function signals_length_should_be_zero_after_removeAll():void
84 | {
85 | signalSet.removeAll();
86 |
87 | assertTrue('Signals length should be 0.', signalSet.signals.length == 0);
88 | }
89 |
90 | //////
91 |
92 | [Test]
93 | public function numListeners_should_be_zero_after_removeAll():void
94 | {
95 | signalSet.removeAll();
96 |
97 | assertTrue('Number of listeners should be 0.', signalSet.numListeners == 0);
98 | }
99 |
100 | //////
101 |
102 | [Test]
103 | public function activate_signal_should_not_be_null():void
104 | {
105 | assertNotNull('Activate NativeSignal should not be null', signalSet.activate);
106 | }
107 |
108 | //////
109 |
110 | [Test]
111 | public function deactivate_signal_should_not_be_null():void
112 | {
113 | assertNotNull('Deactivate NativeSignal should not be null', signalSet.deactivate);
114 | }
115 |
116 | //////
117 |
118 | [Test]
119 | public function add_activate_then_EventDispatcher_dispatch_should_call_signal_listener():void
120 | {
121 | signalSet.activate.add(async.add(handleEvent));
122 | sprite.dispatchEvent(new Event(Event.ACTIVATE));
123 | }
124 |
125 | //////
126 |
127 | [Test]
128 | public function add_deactivate_then_EventDispatcher_dispatch_should_call_signal_listener():void
129 | {
130 | signalSet.deactivate.add(async.add(handleEvent));
131 | sprite.dispatchEvent(new Event(Event.DEACTIVATE));
132 | }
133 |
134 | //////
135 |
136 | [Test]
137 | public function add_activate_then_pause_and_dispatch_should_not_call_signal_listener():void
138 | {
139 | const slot:ISlot = signalSet.activate.add(failIfCalled);
140 | slot.enabled = false;
141 |
142 | sprite.dispatchEvent(new Event(Event.ACTIVATE));
143 | }
144 |
145 | //////
146 |
147 | [Test]
148 | public function add_deactivate_then_pause_and_dispatch_should_not_call_signal_listener():void
149 | {
150 | const slot:ISlot = signalSet.deactivate.add(failIfCalled);
151 | slot.enabled = false;
152 |
153 | sprite.dispatchEvent(new Event(Event.DEACTIVATE));
154 | }
155 |
156 | //////
157 |
158 | [Test]
159 | public function add_activate_then_numListeners_should_be_one():void
160 | {
161 | signalSet.activate.add(handleEvent);
162 | assertTrue('Number of listeners should be 1', signalSet.numListeners == 1);
163 | }
164 |
165 | //////
166 |
167 | [Test]
168 | public function add_deactivate_then_numListeners_should_be_one():void
169 | {
170 | signalSet.deactivate.add(handleEvent);
171 | assertTrue('Number of listeners should be 1', signalSet.numListeners == 1);
172 | }
173 |
174 | //////
175 |
176 | [Test]
177 | public function add_too_both_signals_then_numListeners_should_be_two():void
178 | {
179 | signalSet.activate.add(handleEvent);
180 | signalSet.deactivate.add(handleEvent);
181 | assertTrue('Number of listeners should be 2', signalSet.numListeners == 2);
182 | }
183 |
184 | [Test]
185 | public function add_too_both_signals_then_remove_activate_numListeners_should_be_one():void
186 | {
187 | signalSet.activate.add(handleEvent);
188 | signalSet.deactivate.add(handleEvent);
189 |
190 | signalSet.activate.removeAll();
191 |
192 | assertTrue('Number of listeners should be 1', signalSet.numListeners == 1);
193 | }
194 |
195 | [Test]
196 | public function add_too_both_signals_then_remove_deactivate_numListeners_should_be_one():void
197 | {
198 | signalSet.activate.add(handleEvent);
199 | signalSet.deactivate.add(handleEvent);
200 |
201 | signalSet.deactivate.removeAll();
202 |
203 | assertTrue('Number of listeners should be 1', signalSet.numListeners == 1);
204 | }
205 |
206 | [Test]
207 | public function add_too_both_signals_then_removeAll_numListeners_should_be_zero():void
208 | {
209 | signalSet.activate.add(handleEvent);
210 | signalSet.deactivate.add(handleEvent);
211 |
212 | signalSet.removeAll();
213 |
214 | assertTrue('Number of listeners should be 0', signalSet.numListeners == 0);
215 | }
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/natives/sets/NativeSignalSetTest.as:
--------------------------------------------------------------------------------
1 | package org.osflash.signals.natives.sets
2 | {
3 | import flash.events.Event;
4 | import org.osflash.signals.natives.NativeSignal;
5 | import asunit.asserts.assertNotNull;
6 | import asunit.asserts.assertTrue;
7 | import asunit.framework.IAsync;
8 |
9 | import flash.display.Sprite;
10 | /**
11 | * @author Simon Richardson - me@simonrichardson.info
12 | */
13 | public class NativeSignalSetTest
14 | {
15 |
16 | [Inject]
17 | public var async:IAsync;
18 |
19 | private var sprite:Sprite;
20 |
21 | private var signalSet:NativeSignalSet;
22 |
23 | [Before]
24 | public function setUp():void
25 | {
26 | sprite = new Sprite();
27 | signalSet = new NativeSignalSet(sprite);
28 | }
29 |
30 | [After]
31 | public function tearDown():void
32 | {
33 | signalSet.removeAll();
34 | signalSet = null;
35 | sprite = null;
36 | }
37 |
38 | protected function newEmptyHandler():Function
39 | {
40 | return function(e:*):void {};
41 | }
42 |
43 | //////
44 |
45 | [Test]
46 | public function numListeners_should_be_zero():void
47 | {
48 | assertTrue('Number of listeners should be 0.', signalSet.numListeners == 0);
49 | }
50 |
51 | //////
52 |
53 | [Test]
54 | public function signals_should_be_not_null():void
55 | {
56 | assertNotNull('Signals should not be null.', signalSet.signals);
57 | }
58 |
59 | //////
60 |
61 | [Test]
62 | public function signals_length_should_be_empty():void
63 | {
64 | assertTrue('Signals length should be 0.', signalSet.signals.length == 0);
65 | }
66 |
67 | //////
68 |
69 | [Test]
70 | public function signals_length_should_be_zero_after_removeAll():void
71 | {
72 | signalSet.removeAll();
73 |
74 | assertTrue('Signals length should be 0.', signalSet.signals.length == 0);
75 | }
76 |
77 | //////
78 |
79 | [Test]
80 | public function numListeners_should_be_zero_after_removeAll():void
81 | {
82 | signalSet.removeAll();
83 |
84 | assertTrue('Number of listeners should be 0.', signalSet.numListeners == 0);
85 | }
86 |
87 | //////
88 |
89 | [Test]
90 | public function getNativeSignal_should_return_NativeSignal():void
91 | {
92 | const result:NativeSignal = signalSet.getNativeSignal(Event.INIT);
93 | assertTrue('getNativeSignal should return type NativeSignal.', result is NativeSignal);
94 | }
95 |
96 | //////
97 |
98 | [Test]
99 | public function getNativeSignal_should_not_throw_Error_when_null_is_used_as_classType():void
100 | {
101 | signalSet.getNativeSignal(Event.INIT, null);
102 | }
103 |
104 | //////
105 |
106 | [Test(expects='ArgumentError')]
107 | public function getNativeSignal_should_throw_Error_when_used_for_event_type():void
108 | {
109 | signalSet.getNativeSignal(null);
110 | }
111 |
112 | //////
113 |
114 | [Test]
115 | public function getNativeSignal_should_increment_num_signals_to_one():void
116 | {
117 | signalSet.getNativeSignal(Event.INIT);
118 |
119 | assertTrue('Number of Signals should be 1', signalSet.signals.length == 1);
120 | }
121 |
122 | //////
123 |
124 | [Test]
125 | public function getNativeSignal_with_same_event_type_should_have_signal_length_of_one():void
126 | {
127 | signalSet.getNativeSignal(Event.INIT);
128 | signalSet.getNativeSignal(Event.INIT);
129 |
130 | assertTrue('Number of Signals should be 1', signalSet.signals.length == 1);
131 | }
132 |
133 | //////
134 |
135 | [Test]
136 | public function getNativeSignal_with_different_eventType_should_increment_num_signals_to_two():void
137 | {
138 | signalSet.getNativeSignal(Event.INIT);
139 | signalSet.getNativeSignal(Event.ACTIVATE);
140 |
141 | assertTrue('Number of Signals should be 2', signalSet.signals.length == 2);
142 | }
143 |
144 | //////
145 |
146 | [Test]
147 | public function getNativeSignal_with_lots_of_different_eventType_should_increment_num_signals_to_100():void
148 | {
149 | for(var i:int = 0; i<100; i++)
150 | {
151 | signalSet.getNativeSignal("event" + i);
152 | }
153 |
154 | assertTrue('Number of Signals should be 100', signalSet.signals.length == 100);
155 | }
156 |
157 | //////
158 |
159 | [Test]
160 | public function get_lots_of_getNativeSignal_then_removeAll_should_have_zero_signals():void
161 | {
162 | for(var i:int = 0; i<100; i++)
163 | {
164 | signalSet.getNativeSignal("event" + i);
165 | }
166 |
167 | signalSet.removeAll();
168 |
169 | assertTrue('Number of Signals should be 0', signalSet.signals.length == 0);
170 | }
171 |
172 | //////
173 |
174 | [Test]
175 | public function getNativeSignal_and_add_listener():void
176 | {
177 | const nativeSignal:NativeSignal = signalSet.getNativeSignal(Event.INIT);
178 | nativeSignal.add(newEmptyHandler());
179 |
180 | assertTrue('Number of listeners should be 1.', signalSet.numListeners == 1);
181 | }
182 |
183 | //////
184 |
185 | [Test]
186 | public function getNativeSignal_and_add_10_listeners():void
187 | {
188 | const nativeSignal:NativeSignal = signalSet.getNativeSignal(Event.INIT);
189 |
190 | for(var i:int = 0; i<10; i++)
191 | {
192 | nativeSignal.add(newEmptyHandler());
193 | }
194 |
195 | assertTrue('Number of listeners should be 10.', signalSet.numListeners == 10);
196 | }
197 |
198 | //////
199 |
200 | [Test]
201 | public function getNativeSignal_and_add_10_listeners_and_removeAll():void
202 | {
203 | const nativeSignal:NativeSignal = signalSet.getNativeSignal(Event.INIT);
204 |
205 | for(var i:int = 0; i<10; i++)
206 | {
207 | nativeSignal.add(newEmptyHandler());
208 | }
209 |
210 | signalSet.removeAll();
211 |
212 | assertTrue('Number of listeners should be 0.', signalSet.numListeners == 0);
213 | }
214 |
215 | //////
216 |
217 | [Test]
218 | public function getNativeSignal_and_add_10_listeners_and_removeAll_from_signal():void
219 | {
220 | const nativeSignal:NativeSignal = signalSet.getNativeSignal(Event.INIT);
221 |
222 | for(var i:int = 0; i<10; i++)
223 | {
224 | nativeSignal.add(newEmptyHandler());
225 | }
226 |
227 | nativeSignal.removeAll();
228 |
229 | assertTrue('Number of listeners should be 0.', signalSet.numListeners == 0);
230 | }
231 |
232 | //////
233 |
234 | [Test]
235 | public function get_two_getNativeSignal_and_add_10_listeners_to_each():void
236 | {
237 | const nativeSignal0:NativeSignal = signalSet.getNativeSignal(Event.INIT);
238 |
239 | var i:int = 0;
240 | for(i = 0; i<10; i++)
241 | {
242 | nativeSignal0.add(newEmptyHandler());
243 | }
244 |
245 | const nativeSignal1:NativeSignal = signalSet.getNativeSignal(Event.CHANGE);
246 |
247 | for(i = 0; i<10; i++)
248 | {
249 | nativeSignal1.add(newEmptyHandler());
250 | }
251 |
252 | assertTrue('Number of listeners should be 20.', signalSet.numListeners == 20);
253 | }
254 |
255 | //////
256 | }
257 | }
258 |
--------------------------------------------------------------------------------
/tests/org/osflash/signals/support/SpriteWithDeluxeSignals.mxml:
--------------------------------------------------------------------------------
1 |
2 |