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
張貼留言