FreeSignal – Use Signals easier
Robert Penner's as3-signals make my life much cleaner and easier. There is only one thing that not perfect: With Events I know what parameters to pass when dispatch it, and what can I get when handle it. But the dispatch method of Signals is not so plain. So I was thinking about it for a long time.
We need ISignal Interface for signals, but maybe not IDispatcher. For any signal we want to know exactly what it is and what it have when dispatch or handle it. So I wrote a base class for "FreeSignal". Every "FreeSignal" which extends this FreeSignalBase should have its own dispatch method, and call the protected "doDispatch" method in that dispatch method.
For example, a signal just like the ProgressEvent:
public class ProgressSignal extends FreeSignalBase { private var _bytesLoaded:uint = 0; public function get bytesLoaded():uint { return _bytesLoaded; } private var _bytesTotal:uint = 0; public function get bytesTotal():uint { return _bytesTotal; } public function dispatch(bytesLoaded:uint, bytesTotal:uint):void { _bytesLoaded = bytesLoaded; _bytesTotal = bytesTotal; doDispatch(); } } |
Instead of new Signal(int, int), we have dispatch(bytesLoaded:uint, bytesTotal:uint) now.
And for the listener:
private function addListener():void { someLoader.progressed.add(onProgressed); } private function onProgressed(signal:ProgressSignal):void { var value:Number = signal.bytesLoaded / signal.bytesTotal; } |
Maybe we need target.
public class ProgressSignal extends FreeSignalBase { public function ProgressSignal(target:Object) { _target = target; } private var _target:Object; public function get target():Object { return _target; } private var _bytesLoaded:uint = 0; public function get bytesLoaded():uint { return _bytesLoaded; } private var _bytesTotal:uint = 0; public function get bytesTotal():uint { return _bytesTotal; } public function dispatch(bytesLoaded:uint, bytesTotal:uint):void { _bytesLoaded = bytesLoaded; _bytesTotal = bytesTotal; doDispatch(); } } public class SomeLoader { public const progressed:ProgressSignal = new ProgressSignal(this); } public class SomeHandler { private function onProgressed(signal:ProgressSignal):void { var target:Object = signal.target; var value:Number = signal.bytesLoaded / signal.bytesTotal; } } |
It works fine with SignalCommandMap utility of Robotlegs.
public class ShowLoadedImageCommand implements ICommand { [Inject] public var triggerSignal:ImageSignal; public function execute():void { var image:DisplayObject = triggerSignal.image; // ... } } |
Maybe not a good practice, but I feel good with it so far. If you're interested, here are some more information:
- FreeSignalBase class
- unit-tests for free signals
- Source of Joel Hooks's example for Robotlegs, SignalCommandMap utility and as3-signal - Using FreeSignal, of course.
Test suite generator for Flex Unit 4
中文:Flex Unit 4 的 Test Suite 生成工具
Wrote a small tool to create AllTests.as file with all test cases for FlexUnit4 in Air. To use it, download the air file and install the small app, run it.
Here is the demo code to run it via ant:
<project name="Test Suiter" default="createSuite"> <target name="createSuite"> <exec executable="/Applications/TestSuiter.app/Contents/MacOS/TestSuiter"> <arg value="/Users/someone/Desktop/SomeProject/tests" /> </exec> </target> </project> |
Async test for as3-signals with FlexUnit4
中文: 使用FlexUnit4对as3-signals进行异步测试
Robert Penner 's as3-signals bring us clearer and less code. Here is a utility lib with some delegate methods to test them with FlexUnit4:
- proceedOnSignal
- handleSignal
- failOnSignal
- registerFailureSignal
proceedOnSignal
Use this method to ensure that some signal is dispatched during an asynchronous test.
[Test(async)] public function test_proceedOnSignal():void { var model:IModel = new SomeModel(); proceedOnSignal(this, model.changedSignal); model.doSomethingChange(); } |
Google Tasks Wapper of ig version
It’s a light version of Google Tasks in https://mail.google.com/tasks/ig instead of Christian Cantrell ’s canvas version in https://mail.google.com/tasks/canvas. Choose the one fit you. The code is on GitHub .
xface: A simple ui-unit develop tool
XFace is a simple AsUnit/FlexUnit 4 style UI-Unit framework, but not for testing. It's a tool to reach and verify UI implementation fast.
Demo: (Source)
It use metadata [Before], [After], [Test], [Suite] like the ones in AsUnit/FlexUnit 4, and [Inject] for Dependency injection support.
[Inject] pubic var container:DisplayObjectContainer; [Test] public function test():void { container.addChild(instance); } |
It shows all ui-unit methods in a list. You can select one of them to focus on the smallest ui element and move by smallest steps.
Runner UI uses the List component in @bit101's Minimal Comps.
SignalExecutorMap – Another way to map AS3-Signal to Command in Robotlegs
I love both Robotlegs and AS3-Signals so much, and many thanks to Joel Hooks's SignalCommandMap, they work together great now. When I saw [Execute] tag in dawn I thought if I can do its way for SignalCommand. So, Here is my SignalExecutorMap. I used it in a simple slide player for my Robotlegs slides.
To use it, put the same count and type of params in the execute() method of the Command as its trigger Signal.
// The signal in SignalBus: public const turnToPageRequested:Signal = new Signal(int); |
// Execute method in Command: public function execute(index:int):void |
// Dispatch the signal signalBus.turnToPageRequested.dispatch(0); |
It's not a common solution, because it eliminates the possibility of using other Command impls already in existence. So I created it as SignalExecutorMap instead of expanding SignalCommandMap, and just leave it a single class for personal use. I shared it just in case somebody want it like me because:
- 1, By now (until Robotlegs 1.1) SignalCommandMap will unmap the value passed by Signal.
- 2, Don't want to inject base type like
[Inject] public var index:int;
- 3, Don't want to create VO class just for being passed by Signal to avoid 1 and 2.
I'm sure SignalCommandMap will get better with Robotlegs 1.1 and better later. Robotlegs and as3-signals, they were born to work together ![]()
My Robotlegs slides
I'll give a presentation about Robotlegs the end of this month, here are slides based on Joel Hooks's, Please correct me if I'm doing something wrong, many thanks. The file is on GitHub, and also valid as .key, .ppt, and .pdf format download.
