[pixLib] - Une programmation événementielle typée
Par Laurent Deketelaere le mardi, janvier 17 2006, 23:45 - Flash plateforme - Lien permanent
Dans ce billet, je m'attaque au package events de pixLib.
J'avoue avoir eu l'impression d'avancer seul dans le brouillard pour déchiffrer tout ça, et j'espère ne pas être passé à coté de l'essentiel de ce que cette outil nous apporte. Il est conseillé de connaître les bases de la programmation événementielle dans Flash pour comprendre ce qui suit.
Première chose à savoir, le package events de pixLib ce veut polymorphique à celui de Adobe (ex Macromedia).
var oEB : IEventDispatcher = new EventBroadcaster(this); oEB.dispatchEvent( {type:'onUnTruc', target:this, param:123} );
Deuxièmement, la structure du package events de pixLib permet le typage fort des événements.
iEvent
public function getType() : EventType; public function getTarget(); public function setType(e:EventType) : Void; public function setTarget(oTarget) : Void;
IEventDispatcher
public function addEventListener(t:String, oL) : Void; public function removeEventListener(t:String, oL) : Void; public function dispatchEvent(o:Object) : Void; public function broadcastEvent(e:IEvent) : Void;
De ces deux interfaces découlent tout le système d'événements de pixLib.
Une implémentation basic de IEvent est faite dans BasicEvent, les autres types d'événements plus spécifiques (NumberEvent, StringEvent, BooleanEvent,…) sont simplement des extensions de BasicEvent.
EventBroadcaster quand à lui implémente IEventDispatcher.
On voit dans IEvent apparaître l'objet EventType, le typage des événements ce fait par cette classe. L'objet EventType possède qu'une fonction constructeur qui prend en paramètre le nom du type d'événement.
var e:EventType = new EventType('onUnTruc');
Je m'arrête deux minutes sur la classe EventType, car au niveau architecture «c'est de toute beautée».
/** * @author Francis Bourre * @version 1.0 */ class com.bourre.events.EventType extends String { public function EventType(s:String) { super(s); } }
Avec cette structure il est très facile de comparer deux type d'événements, il suffit d'utiliser un simple opérateur d'égalité(==) et le tour est joué.
Maintenant que l'on a une vue d'ensemble, voyons comment tout cela fonctionne concrètement.
Par chance Francis utilise tous ce beaux monde dans le packages transitions, ce qui nous offre un exemple tout fait.
TweenEventType
Il s'agit d'une classe qui étends la classe EventType.
Elle possède quatre variables statiques, les événements par défaut de la classe Tween.
Chaque variable statique est une occurrence d'elle même, se qui permettrait de connaître exactement tous les types d'événements si l'on rendait le constructeur privé.
static onStartEVENT:TweenEventType = new TweenEventType( "onStart" ); static onStopEVENT:TweenEventType = new TweenEventType( "onStop" ); static onMotionFinishedEVENT:TweenEventType = new TweenEventType( "onMotionFinished" ); static onMotionChangedEVENT:TweenEventType = new TweenEventType( "onMotionChanged" );
TweenEvent
TweenEvent étends quand à elle la classe BasicEvent, la seule différence qu'il y ai avec BasicEvent c'est le typage des éléments, les EventType devient TweenEventType et les cible (Object) devient des objet qui implémentent ITween. Ce qui nous offre un système fortement typé dédié aux transitions.
public function TweenEvent(e:TweenEventType, oTween:ITween); public function getTween() : ITween;
ITweenListener
ITweenListener est une interface que les Ecouteurs des classes de transitions sont obligé d'implémenter.
public function onStart(e:TweenEvent) : Void; public function onStop(e:TweenEvent) : Void; public function onMotionFinished(e:TweenEvent) : Void; public function onMotionChanged(e:TweenEvent) : Void;
TweenFPS et TweenMS
Pour ces classes, je présenterai uniquement le fonctionnement de l'événement «Stop», pour les autres événements le schéma est le même.
private var _oEB:EventBroadcaster; public static var onStopEVENT:TweenEventType = TweenEventType.onStopEVENT; private var _eOnMotionStopEvent : TweenEvent; public function constructeur(oT, sP, nE:Number, nMs:Number, nS:Number, fE:Function) { super(oT, sP, nE, nMs, nS, fE); _oEB = new EventBroadcaster( this ); _eOnMotionStopEvent = new TweenEvent(onStopEVENT, this); } public function addListener(oL:ITweenListener) : Void { _oEB.addListener(oL); } public function removeListener(oL:ITweenListener) : Void { _oEB.removeListener(oL); } public function stop() : Void { super.stop(); _oEB.broadcastEvent( _eOnMotionStopEvent ); }
Comme on peut le voir les écouteurs qui sont accepté pour écouter les transitions sont des implémentations de ITweenListener, en voici une petite «maison» qui permet de récupèrer tout les états de la transition dans FlashInspector.
import com.bourre.transitions.*; import com.bourre.log.*; import com.bourre.utils.LuminicTracer; class LuminicTweenListener implements ITweenListener { public function LuminicTweenListener() { Logger.getInstance().addLogListener( LuminicTracer.getInstance() ); } public function onStart(e:TweenEvent) : Void { Logger.LOG(e.toString(), LogLevel.INFO); } public function onStop(e:TweenEvent) : Void { Logger.LOG(e.toString(), LogLevel.INFO); } public function onMotionFinished(e:TweenEvent) : Void { Logger.LOG(e.toString(), LogLevel.INFO); } public function onMotionChanged(e:TweenEvent) : Void { Logger.LOG(e.toString(), LogLevel.INFO); } }
Ensuite il suffit de tester tout ça dans un fla.
import com.bourre.transitions.*; // Création d'un trait avec l'API de dessin import com.bourre.transitions.*; // Création d'un trait avec l'API de dessin var mc : MovieClip = this.createEmptyMovieClip('mcLigne' , 2 ); mc.lineStyle( 5, 0x000000, 100); mc.moveTo( 0, 0); mc.lineTo( 200, 200); // Transition : variation de l'alpha en 6 frames (100->0). var t:TweenFPS = new TweenFPS( mc, '_alpha' , 0, 6); // ajoute d'un écouteur occurence de LuminicTweenListener. t.addListener(new LuminicTweenListener()); // Lancement de l'interpolation t.execute();
En sortie
Le package events contient d'autres classes : ListenerArray, FrontController et les BubbleEvent.
ListenerArray :
Cette classe est une extension de Array spécialisé dans le stockage d'écouteurs, son API lui permet de répondre au besoin de l'EventBroadcaster().
// retourne l'indice de l'écouteur, -1 si inexistant. public function getIndex(oL) : Number // test l'existence d'un écouteur. public function listenerExists(oL) : Boolean // insert un écouteur public function insert(oL) : Boolean // retire un écouteur public function remove(oL) : Boolean // test si le tableau est vide public function isEmpty() : Boolean
Pour Front Controller, les BubbleEvent et une description des events spécifiques, il faudra bien un autre billet et surtout quelques explications de Francis. :p
J'en profite pour remercier Romain pour son explication sur la mailing liste, mais j'ai bien peur que t'en de notions d'un coup dans mon petit cerveau aient du mal à rentrer. :p
Retrouvez l'API complète des classes events dans la doc de pixLib.
Traduction et adaptation d'une partie des slides que Francis Bourre a utilisé lors du Spark Europe en novembre 2005 + quelques explications sur MSN et la mailing liste. :p
Commentaires
Hey ! bien sympatique tout ça Ca permet une rapide entrée en matière avec l'Event API de Pixlib.
Je viens aussi de lire tes autres billets sur Pixlib; belle initiative Laurent
@+ et bonne continuation
Merci
Je crois qu'une version plus simple, introduisant la programmation événementielle devrait suivre, car j'ai eu pas mal de retour via MSN sur le fait que ce n'était pas très clair. :/
Wouah joli article
"Il est conseillé de connaître les bases de la programmation événementielle dans Flash pour comprendre ce qui suit" Tu nous prépares un pti article non? =)
Merci en tout cas pour celui ci !!
Salut, Dans l'exemple de transition si je veux que l'alpha varie de (0-100) quel paramétre je dois passer ???
Merci j'espére que ma question n'est pas trop stupide La
a+
Salut,
Aucune question est stupide.
Pour les transitions, je prévois un billet complet, mais en attendant voici la solution pour passer de 0 à 100.
Il te suffit d'inverser les valeurs, tu donne un _alpha 0 comme couleur du trait, et tu lui donne une valeur 100 comme valeur finale de la transition.
Hésites pas à aller voir la doc de la classe TweenFPS
++
Merci t'arrete pas dans l'explication de cette lib C bien sympa de ta part
a+
Je ne sais pas si cela peut aider, mais j'avais posté une implémentations d'événements typés ici : http://wiki.media-box.net/tutoriaux/flash/designs_patterns/modele_delegation
Cela tente d'expliquer cette technique appliquée à ASBroadcaster. L'idée provient de Colin Moock (as2e). Cette technique est très intéressante, car stricte, mais parfois longue à mettre en place.
Il faut donc bien évaluer cet aspect. Notamment les implémentations obligatoires de callbacks d'événements dans toutes les classes écouteurs. Si l'API est large, cela peut être assez contraignant. Malgré tout, c'est une structure très sophistiquée et solide.
je vais regarder ca Mais je me posais une autre question si je veux mettre a jour mon objet TweenFPS le plus simple C quoi
Merci a+
Qu'est ce que tu entends par mettre à jour ? TweenFPS fonctionne plus ou moins comme l'objet Tween de Flash, normalement en regardant la doc de TweenFPS.
Merci erixtekila, je regarde ça de suite.
Salut, Peut on utiliser un objet TweenFPS est lui repasser de nouveaux paramétre de transition apres un Execute, c'est ce que j'entendais par mise a jour.
Merci pour les Liens des doc
à 1er vue il semble que non, j'avoue ne pas bien connaitre l'API des transitions de pixLib. Par contre avec les Tween de Adobe c'est possible -> http://wiki.media-box.net/documentation/flash/tween/continueto
Arg d'autres tutoriaux manquent cruellement... Enfin merci quant même pour ceux déjà proposé ici, ça a le mérite d’offrir un certain kick pour ce framework. Vivement une doc officielle car certains concepts m’échappent encore...
<quote>Salut, Peut on utiliser un objet TweenFPS et lui repasser de nouveaux paramétre de transition apres un Execute, c'est ce que j'entendais par mise a jour.</quote>
oui, voici la liste des méthodes prévues à cet usage: setTarget, setProperty, setEasing, setDuration, setStartValue et setEndValue