Calendrier

Mai 2012
Lu Ma Me Je Ve Sa Di
<< >>
123456
78910111213
14151617181920
21222324252627
28293031

AS3 : Vie des Objets graphiques / injection de comportements

Dernière mise à jour Nov 04 2010

3 Evénements utiles pour la gestion de l'affichage :

Il permettent :

  • d'associer des comportements aux objets graphiques lorsqu'ils sont ajoutés à la liste d'affichage
    stage.addEventListener
    (
        Event.ADDED_TO_STAGE, 
        onAddedToStage, 
        true, // Utiliser la phase de capture sinon... surprise
        true
    );
  • de gérer les relations entre éléments graphiques regroupés dans un DisplayObjectContainer juste avant son rendu :
    displayContainer.addEventListener
    (
        Event.FRAME_CONSTRUCTED,
        onFrameConstructed, 
        false, 
        0, 
        true
    );
  • de nettoyer correctement ces comportements lorsque les objets graphiques sont retirés
    stage.addEventListener
    (
        Event.REMOVED_FROM_STAGE, 
        onRemovedFromStage,
        true,  // Utiliser la phase de capture sinon... surprise
        0,
        true
    );

Un assemblage réfléchi donne une classe utilitaire pour injecter / associer du code aux objets graphiques au bon moment de leur vie.
Des interfaces permettent d'injecter proprement la dépendance logique spécifique à chaque projet (ou au conteneur graphique qui peut-être autre chose que le stage).

package displayListener
{
    import displayListener.interfaces.IDisplayControler;
    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.events.Event;
    /**
     * ...
     * @author Julien BEAUFILS
     */
    public class DisplayListener
    {
        private var displayContainers:Vector.<DisplayObjectContainer> = new Vector.<DisplayObjectContainer>();
        private var displayControler:IDisplayControler;
        public function DisplayListener(displayContainer:DisplayObjectContainer, displayControler:IDisplayControler) 
        {
            this.displayControler = displayControler;
            displayContainer.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, true, 0, true);
            displayContainer.addEventListener(Event.FRAME_CONSTRUCTED, onFrameConstructed, false, 0, true);
            displayContainer.addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage, true, 0, true);
        }
        
        private function onAddedToStage(e:Event):void 
        {
            var display:DisplayObject = e.target as DisplayObject;
            displayControler.ini(display);
            if (display is DisplayObjectContainer) 
                displayContainers[displayContainers.length] = display as DisplayObjectContainer;
        }
        
        private function onFrameConstructed(e:Event):void 
        {
            for each (var displayContainer:DisplayObjectContainer in displayContainers) displayControler.run(displayContainer);
            displayContainers.splice(0, displayContainers.length);
        }
        
        private function onRemovedFromStage(e:Event):void 
        {
            displayControler.del(e.target as DisplayObject);
        }
    }
}

Attention :

Les objets du type SimpleButton ont un comportement inattendu du fait que ce ne sont pas des DisplayObjectContainer . Du coup, si un objet (par ex un TextField) créé dans l'IDE FLash à la racine d'un bouton doit absolument être traité, il faudra l'imbriquer dans un clip.

projet Illustratif:

Les fichiers ci-joints montrent un même faux projet codé selon trois approches pour illustrer l'utilité de cette technique :
behaviours-ctrl.zip

FromScratchDesign.as

  • Le programme est écrit d'un coup en une classe sans utiliser le snippet.
  • Il est très peu évolutif, bien que ça reste vite fait et fonctionnel.
  • le générateur de spaghetti se trouve sur cette ligne (Que ce passe-t-il lorsque "day" deviens "morning" + "afternoon" ):
    if (id == "night") var btName:String = "bt_day" else btName = "bt_night";

BetterDesign.as

  • Toujours en une classe mais en utilisant les événements décrits dans cet article .
  • Le code en lui-même reste peu évolutif (voir les switches).
  • Cependant les données et le graphisme associés peuvent sensiblement évoluer sans toucher au code.

OODesign.as


Le nombre de classes associées est complètement sur-dimensionné pour ce petit projet virtuel.

Cependant :

  • Un cadre est "posé" par l'intermédiaire d'interfaces.
  • Le couplage entre chaque classe est faible (interfaces + classes de bases de type DisplayObject/Event...).
  • Toutes les créations d'instances (sauf pour un vecteur privé) se font dans cette classe principale.

Il en résulte que :

  • Le code est "bidouillable" à souhait .
  • L'ajout de types de comportement est simplifié.
  • La réutilisation des codes dans des contextes différents est simplifiée.

0 Commentaires

Nom : E-mail : Site web : Message :