In letzter Zeit bin ich öfters über das Projekt „AS3 Signals” von Robert Penner gestoßen. Es handelt sich um einen alternativen Ansatz zur normalen Events-Klasse in Flash.

Signals is a new approach for AS3 events, inspired by C# events and signals/slots in Qt. […] Wire your application with better APIs and less boilerplate than AS3 Events.

Die AS3-Signals sind leicht zu verwenden, wie die folgenden Beispiele zeigen. Interessant ist, dass die Signale immer Bestandteile der Klasse in Form von Attributen sind.

Der Vorteil gegenüber Flashevents: Man muss keine eigenen Eventklassen schreiben. Außerdem müssen die Listener nicht auf Event-Stringkonstanten hören, weil man sich an echten Objekten registriert.

Codebeispiele zu AS3Signals

Ein kurzes Beispiel: Ein Objekt der Klasse org.florianplag.MP3Player hat eine öffentliche Eigenschaft mit dem Namen turnedOn (= das Signal). Wird der MP3Player eingeschaltet, soll dieses Signal ausgelöst werden.

Intern in der Klasse passiert das Feuern des Signals mit turnedOn.dispatch() (analog zum Dispatchen eines Flashevents).

Actionscript:
  1. package org.florianplag {
  2.     import org.osflash.signals.Signal;
  3.  
  4.     public class MP3Player {
  5.        
  6.         public var turnedOn:Signal = new Signal();
  7.        
  8.         public function MP3Player() {
  9.         }
  10.        
  11.         public function turnOn():void {
  12.             // Signal feuern
  13.             turnedOn.dispatch();
  14.         }
  15.        
  16.     }
  17. }

Möchte man nun von außerhalb einen Listener für das Signal hinzufügen, geschieht dies mit mp3Player.turnedOn.add(...) (= das Pendant zu addEventListener).

Actionscript:
  1. package {
  2.     import org.florianplag.MP3Player;
  3.     import flash.display.Sprite;
  4.  
  5.     public class SimpleExample extends Sprite {
  6.         private var mp3Player : MP3Player  = new MP3Player();
  7.  
  8.         public function SimpleExample() {
  9.             // Listener für Signal hinzufügen  
  10.             mp3Player.turnedOn.add(doSomething);
  11.            
  12.             // MP3Player anschalten
  13.             mp3Player.turnOn();
  14.         }
  15.        
  16.         private function doSomething():void {
  17.             trace ("MP3Player eingeschaltet");
  18.         }
  19.        
  20.     }
  21. }

Weitere Methoden

Mit remove kann man den Listener wieder entfernen. removeAll entfernt alle Listener.

Nett: Möchte nur genau einmal auf ein Signal hören, gibt es neben der add-Methode auch addOnce(doSomethingOnlyOneTime).

Übergabe von Werten

Möchte man Werte oder Objekte als Payload mit dem Signal übertragen, ist dies auch sehr einfach gelöst.

Beim Erstellen des Signals gibt man einen Datentyp bzw. eine Klasse an. Im Beispiel ist dies ein String.

Actionscript:
  1. public class MP3PlayerPayload {
  2.        
  3.   // es soll ein String übergeben werden
  4.   public var turnedOn:Signal = new Signal(String);
  5.        
  6.   public function MP3PlayerPayload() {
  7.   }
  8.        
  9.   public function turnOn():void {
  10.     // Signal feuern
  11.     turnedOn.dispatch("Guten Morgen vom MP3 Player!");
  12.   }
  13.        
  14. }

Auf Empfängerseite muss man den Stringparameter dann einfach in der Funktion hinzufügen, die als Reaktion auf das Signal ausgeführt wird.

Actionscript:
  1. // Listener für Signal hinzufügen  
  2.     mp3Player.turnedOn.add(doSomething);
  3.    
  4.     // MP3Player anschalten
  5.     mp3Player.turnOn();
  6. }
  7.    
  8. private function doSomething(message:String):void {
  9.     trace (message);
  10. }

Dies waren sehr einfache Beispiele. Selbstverständlich lassen sich mit Signals auch die üblichen Fälle abbilden wie MouseEvents, Verursacher des Signals, etc. Ich empfehle das unten verlinkte Videotutorial, das die Möglichkeiten der AS3Signal schön aufzeigt.

Was haltet ihr von dem Ansatz?

Link: AS3 Signals Tutorial (Video Tutorial)
Link: AS3 Signals