ActionStep (plugin View) / Pixlib (MVC FrontController + Remoting) SUSHI Service

Le chef est de retour ^^. Au menu Sushis et MVC “on steroids”.

Montez votre application en MVC. Une fois que le MVC a bien pris, truffez-le d’un FrontController. Parsemez avec quelques MovieClipHelpers. Arrosez finalement le tout avec, selon le choix et l’humeur, un ModelLocator et/ou un ServiceLocator…

Pixlib Remoting SUSHI service ? J’en entends déjà certains dire: il fait dans le recyclage intensif le gars…

Dans cet article je vais vous introduire à un joyau de Pixlib (il y en tellement…c’est une vraie caverne d’Ali Baba !).
SUSHI service repose sur une recette applicative incroyablement puissante et polyvalente basée sur le pattern MVC. “Recette” car ce sont bien des ingrédients qui sont mis à notre disposition. Selon ces ingrédients et l’inspiration on pourra, par exemple, faire gonfler notre MVC traditionnel en MVC à multiples Models (ModelLocator) ou bien comme c’est ici le cas, faire lever le tout en “Super MVC” (FrontController et ServiceLocator).

Get Adobe Flash player

sushiService.zip (541)

- L’ User Interface

C’est toujours du ActionStep (j’ aurai bien voulu tester ASWing but no time):
Cette fois-ci, les “forms” ou “states” sont regroupés dans un module swf autonome chargé au runtime dans l’application principale. Adopter ce design a supposé une nouvelle stratégie d’instantiation.

- “Un système totalement générique”

L’addition du FrontController, du MovieClipHelpers et d’un ModelLocator (classe core.Model) au pattern MVC confère à notre application un degré de modularité exemplaire. L’essentiel de cet article sera consacré à la description de ce “Super MVC”. J’ évoquerai les points qui, d’un point de vue personnel, m’ont semblé les plus pertinents.

- Le service Remoting

Il repose sur la version alpha du package remoting Pixlib. Il est déployé avec souplesse depuis un Singleton ServiceLocator.

Note:
le terme “state” à été employé pour désigner les différentes views contenues dans views.swf. Il n’est donc pas à prendre ici dans son sens premier “d’état” de l’application (généralement stocké dans un SharedObject, ValueObject, instance de Memento ou autre solution)

Commençons en images afin de prendre rapidemment des repères:

La structure du projet

Sushi service flp

Diagramme (maison) de la relation FrontController, MovieClipHelper, ServiceLocator & ModelLocator

Sushi Diagram

L’user Interface en standalone

Désolidariser de la structure de leur précédent hôte (ARP), les différents “states” de l’application (order, viewOrders et navigation) sont de nouveau de banales sous-classes de MovieClip dépourvues de toute fonctionnalité d’ eventdispatching.

Ce nouveau profil de “plugin” a supposé changer la façon d’instancier le container des différents “states” de l’interface. Importée au runtime dans un MovieClip (via GraphicLib), l’UI doit déjà être instanciée sans dépendance de _root si nous souhaitons pouvoir le connecter à chaud tel un plugin.

L’astuce ? packager les classes et procéder à l’ instantiation avec SWFMILL.

La première étape donc: compiler la view
[as]
/**
* @mtasc -version 8 -swf “classes.swf” -header 390:270:60:FCFCFC -trust
*/

// Imports…

class org.actionstep.view.sushi.Application extends MovieClip
{
// MovieClip linkage
static var id = (id=”__Packages.org.actionstep.view.sushi.Application”)+(Object.registerClass(id,Application)?”":”");

private var navigation : MovieClip;
private var order : MovieClip;
private var viewOrders : MovieClip;
private var dataPreloader : MovieClip;

function onLoad()
{
// ActionStep theming
org.actionstep.ASTheme.setCurrent(new
org.actionstep.themes.plastic.ASPlasticTheme());

// Set the initial display state of the application
setInitialDisplayState();

// Views Instantiation (no FLA here)
navigation = attachMovie(Navigation.id,”navigation”, 1);
viewOrders = attachMovie(ViewOrders.id,”viewOrders”, 2);
order = attachMovie(Order.id,”order”, 3);
}
// …
}
[/as]

La deuxième étape: instancier avec SWFMILL

[xml]





[/xml]

L’initialisation MVC

L’application principale (Application.as) est lancée de façon conventionnelle avec main().
Le Model est d’abord instancié. Notre unique vue, une sous-classe MovieClipHelper, s’abonne à l’ écoute du Model. Le controller, un Singleton et sous-classe de FrontController est finalement initialisé. Le controller est le ciment de l’application. C’est lui qui va associer évènements typés et instances de commandes.

[as]
private function _init() : Void
{
var model : Model = new SUSHIExpert();
model.addListener( new SUSHIListUI() );
Controller.getInstance().init();
}
[/as]

I. LES VIEWS

Chargement de la View standalone

GraphicLib et Libstack, du chargement et multichargement intelligent.
Au travers de ces 2 implementations concrètes d’AbstractLib, nos assets sont chargés et stockés avec un identifiant de type String. En l’occurence, ces identifiants sont prédéfinis sous formes de constantes accessibles en static depuis sushi.uis.UIList. Ceci permet une meilleure traçabilité du couplage entre les assets et leurs ‘accesseurs’.

[as]
var gl : GraphicLib = new GraphicLib( this, 20 );
gl.setName( UIList.SUSHI_List );
gl.addEventListener( GraphicLib.onLoadInitEVENT, this, _init );
gl.load( “deploy/views.swf” );
[/as]

ou

[as]
var libs = new LibStack();
libs.enqueue(new GraphicLib(this, 20, false), UIList.SUSHI_List, “deploy/views.swf”);
libs.addEventListener( LibStack.onLoadCompleteEVENT, this, _init );
libs.execute();
[/as]

Les éléments sont ensuite accessibles globalement de plusieurs façons:

- Depuis le Singleton GraphicLibLocator:

[as]
var myView:MovieClip = GraphicLibLocator.getInstance().getGraphicLib( UIList.SUSHI_List ).getView();
[/as]

- Depuis une sous-classe MovieClipHelper:

[as]
// SUSHIListUI.as

class sushi.uis.SUSHIListUI
extends MovieClipHelper
{
public function SUSHIListUI ()
{
super( UIList.SUSHI_List );
}
}
[/as]

- Depuis une sous-classe ViewHelper
[as]
import com.bourre.data.libs.GraphicLib;
import com.bourre.visual.ViewHelper;
import sushi.uis.UIList;

class sushi.uis.SUSHIListUI
extends ViewHelper
{
public function SUSHIListUI ( gl : GraphicLib )
{
super( gl.getView(), UIList.SUSHI_List );

view.app.showDataPreloader();
gl.show();
}
}
[/as]

C’est vraiment très pratique d’avoir un accès global sur les views:
Par exemple, si je souhaite déclencher une action sur une view depuis une Command:

Avec GraphicLibLocator:
[as]
import com.bourre.data.libs.GraphicLibLocator
import sushi.uis.UIList;

class sushi.commands.PlaceOrder
implements Command
{
public function execute( e : IEvent ) : Void
{
var myView:MovieClip = GraphicLibLocator.getInstance().getGraphicLib( UIList.SUSHI_List ).getView();
myView.app.orderProcessed();
}
}
[/as]
avec MovieClipHelper
[as]
import com.bourre.visual.MovieClipHelper
import sushi.uis.UIList;

class sushi.commands.PlaceOrder
implements Command
{
public function execute( e : IEvent ) : Void
{
var myView = MovieClipHelper.getMovieClipHelper(UIList.SUSHI_List);
myView.view.app.showDataPreloader();
myView.traceTest(); // calling a method on SUSHIListUI
}
}
[/as]

Ici, en ce qui nous concerne, Sushi service n’a qu’une seule View de type MovieClipHelper

Sur une instance de MovieClipHelper on va, typiquement:

- définir le comportement des objets (TextField, MovieClips, v2 components…) présents dans la View au moyen de leurs noms d’instances.

Dans le cas de Sushi service, l’UI ActionStep n’est pas qu’une coque vide.

La view externe possède déjà des méthodes:

hideDataPreloader();
showDataPreloader();
orderFormSelect();
viewOrdersFormSelect();

Ensuite, dans chaque “state” ( Navigation, Order, ViewOrders ), les event handlers des boutons sont déjà définis, ex.:

[as]
// NSButton
placeOrderButton = (new NSButton()).initWithFrame(new NSRect(300, 205, 80, 22));
placeOrderButton.setStringValue(“Place order”);
placeOrderButton.setTarget(this);
placeOrderButton.setAction(“placeOrder”);
view.addSubview(placeOrderButton);
[/as]

C’est pas grave du tout ^^. On va piloter et arranger le scope depuis notre sous-classe MovieClipHelper :)

[as]
class sushi.uis.SUSHIListUI
extends MovieClipHelper
{
private function _initBehaviors() : Void
{
_pbCancelOrder.setTarget(this);
_pbCancelOrder.setAction(“cancelOrder”);

_dSelectViewOrders = new Delegate(view.app, view.app.viewOrdersFormSelect);
_dShowPreloader = new Delegate(view.app, view.app.showDataPreloader);
}

private function _gotoViewOrders() : Void
{
_dSelectViewOrders.execute();
_dShowPreloader.execute();
}

private function cancelOrder() : Void
{
_dShowPreloader.execute();
_fireEvent(new BasicEvent(EventList.cancelOrderEVENT, view.app.viewOrders.getOrder() ));
}
}
[/as]

Une “architecture de legos” où nous avons un contrôle total sur chaque pièce autonome pluggée.

Reprenons un peu le fil.
Sur une instance de MovieClipHelper, on va aussi:

- définir les callbacks du ou des Models.
- diffuser (avec notre EventBroadcaster global) des messages de type BasicEvent ou customs (sous-classe BasicEvent) vers les commandes correspondantes.

N’hésitez pas à étendre BasicEvent afin de créer vos propres event objects. C’est une autre pierre angulaire de Pixlib.

Jetez un oeil à la méthode placeOrder(). Vous verrez qu’elle broadcaste un événement de type OrderEvent.
[as]
private function placeOrder() : Void
{
_gotoViewOrders();
_fireEvent(new OrderEvent(EventList.placeOrderEVENT, view.app.order.orderName, view.app.order.orderTicket));
}
[/as]

Attention, la comparaison est malheureuse, mais c’est juste pour faire capter rapidement l’idée à ceux qui sont d’un background ARP:
Voyez OrderEvent comme un Value Object (VO) passant les informations à la commande.
Voilà , vous pouvez vous lacher et crier hérésie haut et fort ^^.

II. Le FrontController

C’est dans sushi.commands.Controller (sous-classe de FrontController) que sont associés et stockés Events et Commands. A la différence du ControllerTemplate d’ARP, le FrontController n’impose aucune référence directe sur les views. Less coupling!

FrontController:
[as]
public function init() : Void
{
push ( EventList.placeOrderEVENT, new PlaceOrder() );
push ( EventList.getOrdersEVENT, new GetOrders() );
push ( EventList.cancelOrderEVENT, new CancelOrder() );
}
[/as]

ControllerTemplate:
[as]

private function addEventListeners ()
{
app.orderForm.addEventListener ( “orderPizza”, this );
app.viewOrdersForm.addEventListener ( “getOrderList”, this );
app.viewOrdersForm.addEventListener ( “cancelOrder”, this );
}

private function addCommands ()
{
addCommand ( “orderPizzaCommand”, OrderPizzaCommand );
addCommand ( “getOrderListCommand”, GetOrderListCommand );
addCommand ( “cancelOrderCommand”, CancelOrderCommand );
}
[/as]

III. ServiceLocator et Commands

Dans le Singleton ServiceLocator nous définissons et stockons un ou plusieurs services remoting (selon nos besoins). Le nom d’alias de chaque service est défini en static.

- La définition du service remoting:

[as]
// sushi.service.ServiceLocator
public static var SUSHISERVICE:String = “dejavue_net.sushi.sushiService”;

public function init( remotingURL : String ) : Void
{
gatewayURL = “http://www.deja-vue.net/amfphp/gateway.php”;
push( ServiceLocator.SUSHISERVICE, ServiceLocator.SUSHISERVICE );
}
[/as]

- Configuration type d’une commande:

1. Localisation du service remoting et appel et de la remote method

Attention, à l’heure où cet article est écrit, le package remoting est toujours en version alpha et non disponible depuis le svn. Je ne m’ étendrai donc pas sur l’implémentation du responder ni sur l’API.

[as]
// class sushi.commands.PlaceOrder

public function PlaceOrder()
{
_service = ServiceLocator.getInstance().getService( ServiceLocator.SUSHISERVICE );
}

public function execute( e : OrderEvent ) : Void
{
_service.order( new ServiceResponder(this), e.getName(), e.getTicket() );
}

public function onResult( e : BasicResultEvent ) : Void
{

}

public function onFault(e : BasicFaultEvent) : Void
{

}
[/as]

2. Tous les chemins mènent à Rome:

Là , c’est GRANDIOSE. Depuis une commande (pas seulement d’ailleurs) nous pouvons:

- appeler la view de notre choix (rappelez-vous de GraphicLibLocator, MovieClipHelper et ViewHelper).
- broadcaster un event typé et déclencher une nouvelle commande.
[as]
EventBroadcaster.getInstance().broadcastEvent( new BasicEvent(EventList.getOrdersEVENT) );
[/as]
- appeler le model de notre choix.
[as]
SUSHIExpert(Model.getModel( ModelList.SUSHI_EXPERT )).onUpdate( e.getResult() );
[/as]

Epoustouflant d’avoir autant de contrôle :)

Le mot de la fin (il est temps! ^^):

Il y a 2 jours, j’ étais parti bille en tête avec l’idée de faire un papier sur le package MVC de Pixlib. En même temps, je me disais que c’ était un peu léger comme sujet. C’est en approfondissant les packages events et visual que j’en suis arrivé au FrontController + MovieClipHelper et à approfondir. Pixlib n’avait pas fini de m’ étonner…
Je reste bluffé. Je ne m’attendais vraiment pas ça. Devinez avec quoi je vais boulonner mon prochain projet ;) .

Chapeau bas à Francis.

Liens de Référence:

-MVC et FrontController
http://www.tweenpix.net/blog/index.php?2004/09/22/460-whiteboard-10
Discussion about models in mvc and front controller patterns on Pixlib list

GraphicLib, LibStack et MovieClipHelper
http://www.get-url.net/blog/?47–pixlib-libstack-ou-le-multi-chargement
http://www.get-url.net/blog/?48–pixlib-graphiclib-et-moviecliphelper-vs-movieclip-parti

ActionStep, Application Architecture, AS2, MVC, Pixlib

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments

26 Responses to “ActionStep (plugin View) / Pixlib (MVC FrontController + Remoting) SUSHI Service”
  • erixtekila says:

    Très bon sujet.
    Si un jour tu avais le temps de (re)définir les utilisations des patterns FrontController et ModelLocator, je serai ravi.

    Un info, depuis swfmill, il est possible de lier une classe avec un clip de façon plus élégante à mon goût. Il suffit d’ajouter un attribut class dans la définition de l’import du . L’association se fait en interne.
    Cela permet de configurer l’ensemble depuis le fichier swfmill.

    respect ;)

  • Mike says:

    >erixtekila

    Très bonne suggestion. Je vais noter ça quelque part dans mon dashboard…

    C’est vrai, j’ai été plutôt expeditif sur le FrontController et j’ai fait l’impasse sur le ModelLocator mais le sujet est si riche, il y a beaucoup à couvrir et je ne voulais pas ennuyer avec un trop long billet :D .

    Concernant swfmill, tu peux donner un exemple de cette association en interne à laquelle tu fais référence ? Je suis pas sûr de connaitre cette façon là.

  • erixtekila says:

    A vot’ service, monseigneur :

    … plus loin, l’instanciation :

    L’association est crée en interne par swfmill (merci Dan)

  • erixtekila says:

    Est-ce que tu peux développer cette façon que tu as d’instancier les classes ?
    [as]
    static var id = (id=”__Packages.org.actionstep.view.sushi.Navigation”)+(Object.registerClass(id,Navigation)?”":”");
    [/as]

    Je ne suis pas sûr de comprendre la procédure de l’identifiant utilisé avant d’être initialisé…

  • Mike says:

    Mais je te reconnais ! Le ptit dernier au fond du post .

    On suivait d’une oreille, je vois… ^^.

    Enfin pour finir, Dave Yang donne ici un exemple très clair pour illustrer en quelques lignes l’astuce dénichée par Peter.

  • erixtekila says:

    Ouh qu’il est vilain lui !
    Ok, je ne me souviendais pûs du post de Dave, mais selon lui :

    Here’s a shortened (and more obscured) example:

    Alors si t’as pas compris non plus, c’est pas une raison pour embêêêêêter les aut’, voilà. ;)

  • ekameleon says:

    Hello :)

    Pour attacher un clip ou un Textfield qui utilise une classe “Custom” pour moi il ne faut pas utiliser la méthode de l’identifiant de liaison dans un attachMovie… cela nécessite de se prendre la tête avec une propriété quelquepart etc….
    Le mieux c’est de manipuler le __proto__, j’en parle déjà ICI et ICI

    Avec au passage ma classe DisplayFactory qui permet dans VEGAS de faire tout cela proprement :)

    C’est vraiment plus “ECMAScript” comme gestion de l’héritage et surtout moins “obscure” comme on peut le lire au dessus dans la citation ^_^

    EKA :)

  • Mike says:

    Salut EKA :) .

    Sois le bienvenu !

    Je viens de jeter un oeil à Vegas et Asgard. Beau boulot! Il y a du matos… :)

    J’ai pris quelques minutes ce matin pour tester le DisplayFactory sur OSFlash Pizza mais ça ne marche pas pour moi.

    [as]
    /*
    navigationForm = NavigationForm(
    attachMovie(NavigationForm.id, “navigationForm”, 1));
    */

    navigationForm = NavigationForm(
    DisplayFactory.createChild ( NavigationForm , “navigationForm” , 1, this) );
    [/as]

    Un examen avec Xray n’a cependant rien révélé de particulier. La classe est bel et bien instanciée.

  • ekameleon says:

    Hello :)

    J’ai pas regardé de prêt ton taf, tu utilises des composants compilés ou sont bien totalement dynamiques ? Car sinon faut se méfier :) Ma classe permet d’utiliser une classe qui hérite de MovieClip et de créer via un createEmptyMovieClip ou un createTextField un clip qui utilise une autre classe que la classe MovieClip pour son héritage.
    Faudrait que je regarde ce qui cloche ? Peut être avec un exemple à part de ce que tu cherches à faire ? Dans tous les cas tu as du le voir je fourni des exemples avec Asgard et Vegas et on y retrouve dans le répertoire bin/test/vegas/util/factory un exemple d’utilisation :) Tu peux peut être te baser là dessus pour tester ma classe ? :)

    Au passage si tu veux utiliser un composant dans la biblio et lui coller une classe tu peux utiliser la classe ConstructorUtil et la méthode createVisualInstance pour ajouter dynamiquement à ton clip qui vient d’être attaché la classe qu’il faut :) Je vais voir si je peux pas goupiller un truc automatisé dans Vegas ce soir :)

    EKA :)

  • Mike says:

    En l’occurence les composants (ActionStep) sont pure ActionScript (l’application est 100% IDE free)

    NavigationForm, par exemple, hérite de org.osflash.arp.ArpForm, la classe de base pour toutes les Views d’un projet ARP. ArpForm heritant de MovieClip.

    Oui j’ai bien vu les exemples. Les commentaires accompagnants DisplayFactory sont déjà très clairs :) .

    La classe ConstructorUtil à l’air très intéressante ;) . Je regarderai moi aussi tout ça de plus près ce soir.

  • ekameleon says:

    J’ai pas pu résister je viens de mettre en place rapidement dans la clase DisplayFactory une nouvelle méthode attachChild qui permet d’utiliser de façon combinée un attachMovie et la modification de l’héritage, exemple :
    [AS]
    import myPackage.RectangleComponent ; // classe qui hérite de MovieClip

    // Initialisation du composant
    var init = {
    t:2 , lc : 0xCCCCCC , la:100 ,
    w:50 , h:50 , _x:50 , _y:50
    }

    var rec:RectangleComponent = DisplayFactory.attachChild( RectangleComponent, “Rectangle”, “rec”, 1, this, init )
    [/AS]

    Mais bon dans tous les cas à part cause extrème je préfère créer des composants à base de full dynamique qui font ensuite dans le constructeur de la classe des attachMovie des éléments graphiques si je ne peux pas faire autrement que d’utiliser des symboles dans la biblio :)

    eKA :)

  • erixtekila says:

    @eka : j’ai toujours privilégié la composition à l’héritage, surtout pour les MovieClip et TextField.

    J’utilise par contre dans toutes mes classes sérialiables :
    [AS]
    // Sérialisation de la classe
    /**
    * Liaison de l’objet à sa classe.
    * Utiliser “__Packages.packageName” si extension d’un clip dynamique.
    */
    public static var linkageID:String = “net.via.ui.GraphicState”;
    public static var classRef:Function = GraphicState;
    public static var className:String = “GraphicState”;
    /**
    * Permet la serialisation d’un objet.
    * 1- Relie un objet avec la classe d’où il provient,
    * une fois remonté par SharedObject ou échangé par LocalConnection.
    * 2- Dans le cas de l’extension d’un MovieClip,
    * effectue la liaison avec un graphique généré dynamiquement.
    */
    public static var serializable:Boolean = Object.registerClass(linkageID, classRef);
    [/AS]

    J’ai puisé cela du framework AsUnit et je trouve la méthode très élégante.
    Dans Eclipse, j’ai un template qui me génère cela très aisément.
    Ainsi, les LocalConnections, SharedObject et services remoting peuvent utiliser simplement une classe personnelisée.

  • ekameleon says:

    Hello :)

    Alors pour le Object.registerClass je ne m’en sert pas car pour FMS … les namespace cela ne fonctionne pas correctement coté SSAS :) Et du coup je préfère utiliser EDEN pour les objets customs. J’ai posé la question justement aujourd’hui sur FCNG ici.

    Ensuite pour ce qui est de la composition ou de l’héritage, pour ma part j’utilise les 2 avec des composants qui restent des classes qui héritent de MovieClip (niveau performance c’est mieux à mon avis et cela permet d’aller assez loin dans l’héritage sans se prendre trop la tête) et dans le reste des cas j’utilise une classe DisplayObject qui utilise la composition et qui se calle sur la classe DisplayObject AS3 et ce que l’on peut voir dans Pixlib avec les MovieClipHelper. A mon avis il suffit de faire le bon choix selon la situation :)

    Sinon un truc au passage en voyant ton code au dessus, dans Vegas pour retrouver le nom de la classe et le package de celle ci, j’utilise les méthodes statiques de ma classe ConstructorUtil :

    [AS]import vegas.util.ConstructorUtil ;

    import vegas.events.BasicEvent ;

    trace ( “constructor name : ” ConstructorUtil.getName(BasicEvent)) ;
    trace ( “constructor package : ” ConstructorUtil.getPackage(BasicEvent)) ;
    trace ( “constructor path : ” ConstructorUtil.getPath(BasicEvent)) ;
    [/AS]

    et cela marche aussi avec les instances :
    [AS]var e = new BasicEvent() ;
    trace ( “constructor name : ” ConstructorUtil.getName(e)) ;
    trace ( “constructor package : ” ConstructorUtil.getPackage(e)) ;
    trace ( “constructor path : ” ConstructorUtil.getPath(e)) ;
    [/AS]

    Du coup à utiliser dans les toString(), les gestions d’erreurs etc.. pas besoin de stocker des static dans la classe pour stocker ces infos également, c’est pratique :)

    EKA :)

  • erixtekila says:

    D’accord, eka, je vais aller faire un tour dans ton framework. C’est vrai que la réflexion en actionscript c’est une drôle d’affaire…
    Si ton ConstructorUtil rempli bien sa tache, je te l’emprunterai.

    Pour ma part, j’ai pris la décision de faire hériter toutes les classes de mon travail d’un BasicClass, qui gère notamment les toString, erreurs, et fonctions par défaut (clone, compare…). Si tu fais mieux, j’adopte ;)

    Mais par contre, eka, ce qui me manque dans ton travail, c’est son orientation générale.
    Je crois depuis le début que vegas == ssas.
    Je m’aperçois que ce n’est pas forcément le cas.

    Je lis en ce moment “Java, plus simple, plus rapide”
    J’ai toujours peur de prendre un framework disproportionné par rapport à mon projet.
    Mais le fait de ne pas trop saisir l l’axe de vegas, ne m’a pas aidé.

    C’est pareil d’ailleurs pour pixlib que je commence à cerner, ou encore aslib qui rempli tellement de taches que l’on s’y perd.
    A mon avis, un framework doit avoir un orientation bien déterminée. S’il répond à plusieurs taches trop disparates, il oblige une utiilsation parcéllaire voire fortuite.
    Cela serait dommage de tomber dans les excès des libs java, voir Spring et hibernate comme décision de desighn plutôt que les entreprise java beans.

  • Ma révérence à ce billet et son auteur qui ont su cerner les finesses (bluffant!!!) de la partie architecturale de pixlib. Well done mike, renversant ! :)

  • ekameleon says:

    Hello :)

    @erixtekila

    Justement Vegas est un framework de base et ensuite tu as des extensions comme Asgard pour gérer tout le reste :)

    Vegas c’est avant tout :

    - la base du framework avec le package core

    - les structures de données dans le package data (Abstract Data Type) avec les Collections, Map, etc.. qui sont nécessaires pour toute la structure du framework.

    - le système événementiel avec le package events

    - le système de Log basé sur le système événementiel dans le package logging

    - la gestion des erreurs dans le package errors basé sur le système de Log

    - Des utilitaires dans le package util et des classes pour manipuler les chaines de caractères dans le package string

    J’aurai pu faire à ce niveau là plusieurs “framework” mais tous ces packages se croisent ou nécessitent une dépendance forte à un autre package ! Donc je pense avoir mesurer le minimum vital dans ce Framework et je peux te dire que j’ai fait beaucoup de découpage depuis le début du projet.

    Ensuite il est vrai que j’ai presque fini de coder la version SSAS de Vegas car le but au final est d’avoir un framework polymorphe à celui de l’AS3 et qui peut s’utiliser aussi bien dans une application Flash que SSAS ou Javascript (c’est la même chose)

    Donc rien de disparatre dans Vegas.. juste ce qu’il faut pour créer une base au niveau des Applications avec tout ce qu’il faut pour rendre homogène le code.

    Ensuite tu as par exemple Asgard qui est le framework spécifique à la réalisation d’UI avec des gestionnaires de chargements de données basé sur JSON, EDEN, etc.. avec un package sur les transitions, etc.. etc. mais attention ASGARD lui peut évoluer (là c’est juste une version 0.1) et se diviser ensuite en plusieurs frameworks plus indépendant… il existe déjà une sous extension de Asgard qui se nomme Lunas mais qui arrivera quand Asgard sera stable complètement. Lunas est un framework de composant qui existe aussi pour Pixlib avec le framework Neo…

    Bref beaucoup de boulot qui me permet de bien évoluer dans mon code avec peut être d’ici peu un vrai changement d’orientation avec le projet SOLO qui m’intéresse encore plus que ce que je suis en train de faire en ce moment et qui permettrait à une équipe de développeur de créer un framework OpenSource utile pour tout le monde :)

    Pour conclure, le mieux, c’est d’utiliser Vegas et ensuite on voit vite ce qu’il permet de faire :) Il y a assez d’exemple dedans maintenant pour cerner l’essentiel. Ensuite c’est pour moi indispensable d’essayer aussi Pixlib etc… Tout est bon à prendre à mon avis dans le boulot de chacun :)

    EKA :)

  • Xavier MARTIN says:

    Salut.
    Je voulais savoir ou il serait possible de choper la version alpha pour les classes remoting.
    Car ton billet est vraiment interressant et je souhaiterai mettre en oeuvre cela ds une api que je dois faire utilisant aussi sushi…

    Merci merci :)

  • Xavier MARTIN says:

    Hope you get the joke above… Rereading it it’s not so clear :)
    Anyway, I’m wainting to see those classes… (I hope so)

  • Mike says:

    Salut Xavier,

    Tu pourras trouver le package remoting pixlib ici (alpha)

    Hope you get the joke above

    I didn’t. Could you try one more time :lol: ?

  • Xavier MARTIN says:

    Thx for the link.
    Nevermind for the joke…
    And be prepared, I’m doing an email for the pixlib mailing list dealing with your tuts.
    Hope you could clear things a bit :)
    Cheers
    Xavier

  • Ok I have small question here.
    In your tut, in the GetOrders.as command in the onResult function, we’re calling the onUpdate function of the Model.
    This function in the model is doing nothing else than broadcasting the event onUpdateOrderList to the view regestered.
    Just asking if we could skip a step and call the function onUpdateOrderList directly from one of the command.

    Why here braodcasting to the model which is braodcasting to the view then???
    You don’t want to use reference to other view / object ?

  • Mike says:

    True.

    As explained in the article, in the command classes you can also use ViewHelper/ MovieClipHelper to interact with your views.

    [as]
    // GetOrder.as

    //import com.bourre.core.Model;
    //import sushi.models.SUSHIExpert;
    //import sushi.models.ModelList;

    import com.bourre.visual.MovieClipHelper
    import sushi.uis.UIList;
    import sushi.uis.SUSHIListUI;

    // … /…

    public function onResult( e : BasicResultEvent ) : Void
    {
    //SUSHIExpert(Model.getModel( ModelList.SUSHI_EXPERT )).onUpdate( e.getResult() );
    SUSHIListUI(MovieClipHelper.getMovieClipHelper(UIList.SUSHI_List)).onUpdateOrderList( e.getResult() );
    }
    [/as]

    Pixlib give us this FLEXibility ;) .

    I use ModelLocator for the purpose of the article. I wanted to show it in action.

    More generally and personally, as a RIA grows, the strategy I would recommend is the ModelLocator strategy. It helps keeping the code disciplined (not mentionned this is the place to store your state).

    But It just depends on you personal needs or design choices and the application complexity.

  • Marcelo says:

    Very good article. Thanks for sharing!

  • Marcelo says:

    Just a question: Haven’t you made the source files available for download!? I’m searching but can’t find it! :(

  • Marcelo says:

    Ooops… sorry, just found it now :P

Leave Comment

(required)

(required)


eXTReMe Tracker