Je continue l'extension de classes natives de Flash pour leur attribuer le modêle évenementiel de EventDispatcher. J'en suis venu à me pencher sur la classe EventDispatcher elle-même, et j'ai découvert quelques tips, que tout le monde ne connaît pas forcément...

1. INITIALISATION
Une méthode toute simple consiste à déclarer les trois méthodes principales, et d'appeler ensuite la méthode statique 'initialize' qui va s'occuper de décorer le prototype de notre classe. A la base, c'est même dans le constructeur que l'on initialise l'instance, mais dans la classe ca fait plus mieux. En gros, on retrouve le même code un peu partout, excepté le nom de la classe qui change. import mx.events.EventDispatcher;
class EventSource {
        public var addEventListener:Function;
        public var removeEventListener:Function;
        private var dispatchEvent:Function;
        private static var __initEvent = EventDispatcher.initialize(EventSource.prototype);
}
Il faut bien avouer que à la pratique, au bout d'un moment, ca devient assez lourd de toujours retaper la même chose. Un #include serait bien pratique, mais étant donné que le nom de la classe change à chaque fois, cela obligerait à laisser le initialize() dans le code de la classe. J'ai donc utilisé une autre méthode :// fichier "initEvent.as"
private static var __dispatcher:Function = mx.events.EventDispatcher;
public function addEventListener(e:String, o) {
  __dispatcher.prototype.addEventListener.apply(this, arguments);
}
public function removeEventListener(e:String, o) {
  __dispatcher.prototype.removeEventListener.apply(this, arguments);
}
private function dispatchEvent(o) {
  __dispatcher.prototype.dispatchEvent.apply(this, arguments);
}
private function dispatchQueue(q, o) {
 __dispatcher.prototype.dispatchQueue.apply(this, arguments);
}
// fin "initEvent.as"

// fichier "EventSource.as"
class EventSource {
        #include "initEvent.as"
}
La méthode dispatchQueue() n'est jamais utilisée en général, excepté par dispatchEvent(), mais elle a besoin d'être là pour faire fonctionner le tout... Bon, je veux bien concevoir que c'est pas trés académique d'utiliser les prototypes. :$ Mais en tout cas, ca fonctionne plutôt bien, et ca me permet de chager de "dispatcher" facilement. Par exemple, si je préfère utiliser GDispatcher, il me suffit de changer la première ligne de mon fichier, et toutes les classes qui l'utilisent seront mises à jour à la compilation! 8) Et si jamais, j'ai un besoin réellement spécifique, il me suffit de copier/coller le code directement dans la classe. Cela peut même éventuellement me permettre de rajouter un typage quelqconque a mes paramètres, ou d'afficher des infos de debug, etc... 2. HANDLER INTERNE La classe EventDispatcher permet nativement de créer un handler interne qui va intercepter les évenements diffusés. Il suffit pour cela de créer une méthode qui s'appelle <nomEvenement>Handler(). Ca permet d'éviter d'inscrire une instance comme son propre écouteur :// Sans handler interne
class EventSource {
        #include "initEvent.as"
        function EventSource() {
           this.addEventListener("onEvent", this);
        }
        private function onEvent(o) {
           trace(o.type + " event dispatched");
        }
}
// Avec handler interne
class EventSource {
        #include "initEvent.as"
        function EventSource() { }
        private function onEventHandler(o) {
           trace(o.type + " event dispatched");
        }
}
Bien pratique parfois, pour du debug par exemple. :) 3. HANDLER GENERIQUE En plus d'une méthode portant le nom de l'évenement à intercepter, un objet qui en écoute un autre peut intercepter n'importe quel évenement pour peu qu'il y soit abonné, s'il implémente une méthode nommée handleEvent(). C'est d'ailleurs ce système qu'utilise la classe Delegate de Macromedia (et celle de Francis BOURRE aussi, mais son site il est plus la pour l'instant :()// Fichier "EventSource.as"
class EventSource {
        #include "initEvent.as"
        function EventSource() { }
        function doIt() {
                dispatchEvent({type:"onEvent", target:this});
        }
}
// Fin fichier
// Fichier "EventListener.as"
class EventListener {
        function EventListener() {}
        function handleEvent(o) {
                trace(o.type + " event handled by handleEvent() method");
        }
        function onEvent(o) {
                trace(o.type + " event handled by onEvent() method");
        }
}
// Fin fichier
// Code principal
var es:EventSource = new EventSource();
var el:EventListener = new EventListener();
es.addEventListener(el);
es.doIt();
// Sortie
onEvent event handled by handleEvent() method
onEvent event handled by onEvent() method
4. FONCTIONS Un évenement peut également être inetrcepté par un simple fonction. Plus besoin à ce moment là de passer par une instance de classe. Bien entendu, dans le cadre d'un développement full-OO, cette pratique n'est pas vraiment conseillée... 8|var es = new EventSource();
var fct:Function = function(o) {
        trace(o.type + " handled by a function");
}
es.addEventListener("onEvent", fct);
es.doIt();
// Sortie
onEvent handled by a function

Wala, wala pour les quelques subtilités de EventDispatcher... ;)
Bon, je sais, il faut absolument que je fasse quelque chose pour les couleurs de mon code. Ca va viendre, ca va viendre... :$