AS3-Signals 好用,但也有些缺點:
- 不能設定 useCapture。其實 Event 的這個功能,在專案上個人幾乎是沒用過,所以就顯得不重要了。若要用 useCapture 就使用 Event 吧。
- 不能設定 useWeakReference。據作者的說明,weak reference 有 bugs ,目前沒有將這個功能加入。視情況去 remove signal listener。
An introduction to AS3 Signals
as3signals – An Awesome Solution to Events/Signals in AS3
Signals 並不能完全取代 Event,主要原因是無法取代原生的 Event 如 MouseEvent。此時,使用NativeSignal 去做轉接的動作。
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import org.osflash.signals.natives.NativeSignal;
[SWF(width="600", height="400")]
public class Test1NativeSignal extends Sprite{
public function Test1NativeSignal() {
var btn:Sprite = new MyButton();
this.addChild(btn);
// 建立和滑鼠事件相關的 signal物件
var clickSignal:NativeSignal = new NativeSignal(btn, MouseEvent.CLICK, MouseEvent);
// 在 signal物件 上註冊處理器
clickSignal.add(clickHandler);
}
private function clickHandler(event:MouseEvent):void {
var txt:TextField = new TextField();
this.addChild(txt);
txt.autoSize = TextFieldAutoSize.LEFT;
txt.y = this.height;
txt.text = event.type + ':' + event.target.name;
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
class MyButton extends Sprite {
private static var count:int;
public function MyButton () {
var g:Graphics = this.graphics;
g.beginFill(0x666699);
g.drawRoundRect(10, 10, 100, 60, 20, 20);
g.endFill();
this.name = 'MyButton' + ++count;
}
}
習慣上會將 signal 定義為某個會發送訊息物件的屬性。package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
[SWF(width="600", height="400")]
public class Test2NativeSignal extends Sprite {
public function Test2NativeSignal() {
var btn:MyButton;
for(var i:int=0; i<5; i++) {
btn = new MyButton();
this.addChild(btn);
btn.x = (btn.width+10)*i;
btn.click.add(clickHandler);
}
}
private function clickHandler(event:MouseEvent):void {
var txt:TextField = new TextField();
this.addChild(txt);
txt.autoSize = TextFieldAutoSize.LEFT;
txt.y = this.height;
txt.text = event.type + ':' + event.target.name;
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
import org.osflash.signals.natives.NativeSignal;
class MyButton extends Sprite {
private static var count:int;
public var click:NativeSignal;
public function MyButton () {
var g:Graphics = this.graphics;
g.beginFill(0x666699);
g.drawRoundRect(10, 10, 100, 60, 20, 20);
g.endFill();
this.name = 'MyButton' + ++count;
click = new NativeSignal(this, MouseEvent.CLICK, MouseEvent);
}
}
使用 NativeMappedSignal 轉換發出的物件格式。
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
[SWF(width="600", height="400")]
public class Test3NativeMappedSignal extends Sprite{
public function Test3NativeMappedSignal() {
var btn:MyButton;
for(var i:int=0; i<5; i++) {
btn = new MyButton();
this.addChild(btn);
btn.x = (btn.width+10)*i;
btn.click.add(clickHandler);
}
}
public function clickHandler(data:String):void {
var txt:TextField = new TextField();
this.addChild(txt);
txt.autoSize = TextFieldAutoSize.LEFT;
txt.y = this.height;
txt.text = data;
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
import org.osflash.signals.natives.NativeMappedSignal;
class MyButton extends Sprite {
private static var count:int;
public var click:NativeMappedSignal;
private var clickCount:int;
public function MyButton () {
var g:Graphics = this.graphics;
g.beginFill(0x666699);
g.drawRoundRect(10, 10, 100, 60, 20, 20);
g.endFill();
this.name = 'MyButton' + ++count;
click = new NativeMappedSignal(this, MouseEvent.CLICK, MouseEvent, String)
.mapTo(function(event:MouseEvent):String {
return name+':' + ++clickCount;
});
}
}
使用 Signal 類別的例子
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import org.osflash.signals.Signal;
public class Test4Signal extends Sprite{
public var count:int;
private var signal:Signal;
public function Test4Signal() {
// 限定傳送資料的類型
signal = new Signal(String, int);
signal.add( listener );
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function listener(str:String, count:int):void {
var txt:TextField = new TextField();
this.addChild(txt);
txt.autoSize = TextFieldAutoSize.LEFT;
txt.y = this.height;
txt.text = str + ':' + count ;
}
private function enterFrameHandler(event:Event):void {
count++;
if( count%30 == 0) {
// 觸發
signal.dispatch('count', count);
}
}
}
}使用 DeluxeSignal 類別的例子
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import org.osflash.signals.DeluxeSignal;
import org.osflash.signals.events.GenericEvent;
public class Test5DeluxeSignal extends Sprite {
public var count:int;
private var signal:DeluxeSignal;
public function Test5DeluxeSignal() {
// 設定 target 為 this
signal = new DeluxeSignal(this);
signal.add( listener );
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function listener(event:GenericEvent):void {
var txt:TextField = new TextField();
this.addChild(txt);
txt.autoSize = TextFieldAutoSize.LEFT;
txt.y = this.height;
txt.text = event.currentTarget + ':' + event.currentTarget.count ;
}
private function enterFrameHandler(event:Event):void {
count++;
if( count%30 == 0) {
// 觸發
signal.dispatch(new GenericEvent());
}
}
}
}
2 則留言:
兩個問題想請教老師:
1.請問您後來有在專案使用這個Signal框架嗎?
2.對於效能有提升嗎?
謝謝
1. 尚未在專案上使用 Signal
2. Signal 不是用來提高效能的, 它只是方便處理 events
張貼留言