Open Source Flash Pizza for everyone !

Ouvrir ce blog est un bon prétexte pour déballer et ranger mes vieux cartons.
Il y a quelques mois, bien loin d'imaginer l'arrivée du Free Flex SDK, trouver une alternative sérieuse au framework as2 mx était d'un réel enjeu. C'est à ce titre que je me suis intéressé à ActionStep.

Que puis-j'en dire ?

Franchement, ce n'est pas sa robustesse qui lui fait défaut, mais au jour d'aujourd'hui, on ne peut que se questionner sur sa place et son devenir.
Le Roadmap a complètement explosé et l'annonce il y a quelques mois du Flex framework posa l' intérrogation

Dès la sortie de la version alpha, j'avais donc commencé à experimenter un peu.
Flash Remotien convaincu, je cherchais par ailleurs une alternative à l' implémentation remoting d' Adobe.
De fructueux échanges avec Ray Chuan m' ont permis d'utiliser l' ASRemoting très tôt en production car la librarie est disponible de façon autonome, chargeable ala DLL.

La majorité de mes projets reposant sur ARP, un premier test tout indiqué était le portage de Pizzaservice.

pizzaService.zip (238)

Je ne vais pas rentrer dans le détail de l'API, ce n'est pas mon propos.

Je parlerai néanmoins d'une spécificité fondamentale des rouages d' ActionStep qui m'a conduit à employer un hack (tout à fait legitime) pour le rendre compatible ARP.

L' expression "hack legitime" n'est pas hasardeuse:

- Hack, car ActionStep est déjà en soi un framework structurel.
- Légitime, car ses auteurs ont pensé à laisser des portes ouvertes.

Intégrer ActionStep et ARP est une idée plutôt saugrenue dont la réalisation semble assez compromise. En particulier, pour les raisons suivantes:

- ActionStep nous protège de la manipulation directe des Movieclips, encapsulant cette gestion dans une hiérarchie de type View.
- Les views dépendent d'une view principale (instanciée par NSWindow) dont la référence MovieClip de base a été codée en dur et n'est autre que _root.
- Comme sus-mentionné, Actionstep est aussi un framework de type applicatif, et à priori conçu pour s'initialiser à la racine de votre project (NSapplication).

public function init()
{
    var app:NSApplication = NSApplication.sharedApplication();

    var window:NSWindow = (new NSWindow()).initWithContentRect(
        new NSRect(0,0,500,400));
    var view1:NSView = (new NSView()).initWithFrame(
        new NSRect(50,50,400,300));

    window.setContentView(view1);

    // Some UI instantiation later...
    view1.addSubview(ASLabel);
    view1.addSubview(NSStepper);

    // Start the mug...
    app.run();
}

Comment faire? C'est plus simple qu'il n'y paraît...

La classe NSWindow contemple la possibilité de charger différents types de view principale. Si je simplifie, la view principale est:

- soit issue d'une source externe (chargement SWF).
- soit la view par défaut, de type ASRootWindowView.

De type ? ;) . Eh oui ^^. Vous l'aurez compris, la solution consiste à offrir à NSWindow une view custom où la cible MovieClip sur laquelle s'initie l'application sera de notre choix.

class org.actionstep.window.ASClipWindowView
    extends org.actionstep.window.ASRootWindowView
{
    public function ASClipWindowView() {
        super();
    }

    public function changeRoot(target:MovieClip) {
        WINDOW_CLIP = target
    }
}

// org.osflash.pizza.view.NavigationForm

import org.actionstep.window.ASClipWindowView;
import org.actionstep.*;

// ...

public function initialize()
{
    var app:NSApplication = NSApplication.sharedApplication();

    var window:NSWindow = (new NSWindow()).initWithContentRectViewClass(
        new NSRect(0,0,165,25), ASClipWindowView );

    ASClipWindowView(window.rootView()).changeRoot(this);

    var view:NSView = NSView((new NSView()).initWithFrame(
        new NSRect(0, 0, 165, 25)));

    window.setContentView(view);

    // ...

    // Start the mug...
    app.run()
}

On peut voir ça comme une composition où chaque ArpForm va instancier une NSApplication depuis la méthode initialize().

Mis à part le gradient header et les transitions, tout est oeuvre d'ActionStep.

J'aurais encore beaucoup à dire, notamment concernant sa librairie Remoting.
Ce sera le sujet d'un prochain post où je compte présenter différentes façons de charger en DLL, décortiquer l'ASResponse (equivalent du ResultEvent) et l' ASRecordSet, et souligner la différence d'implémentation dans le ServiceLocator et les sous-classes CommandTemplate.

Parlons maintenant de ce qui n'est pas ActionStep.

Reconstruire pizzaService sans support de fichier FLA était pour moi une condition et ne supposait aucun défi majeur. Embarquer des polices ne présentait pas plus de difficulté. La problématique se posa néanmoins à l'heure d'opter pour le chargement des polices en externe. Là, je me retrouvais de nouveau confronté au supplice des librairies partagées.
La solution vînt d'une suggestion que me fit Chris Bare sur la mailing-list de SWFMILL.
Une solution passant par ce que lui même n' hésite pas à nommer une "analyse éducative". Big thank to him for this invaluable tip.

Voici donc la navigation de notre open source pizzaService pourvu de NSButton dynamiquement stylisé.

Pour les effets de Tween j'ai préféré le package transitions de Pixlib.
Si vous ne connaissez pas encore ce fantastique framework polyvalent, allez tout de suite le découvrir. C'est un vrai couteau-suisse. C'est simple, je ne peux plus m'en passer ^^.

Petite parenthèse à propos de Pixlib (Je lui consacrerai plusieurs tickets).
Personnellement, quand ARP me semble parfois surchargé pour certains types d'applications, je lui préfère généralement le package MVC de Pixlib.

Revenons aux transitions...
Le portage est vraiment très simple:

import mx.transitions.*;
var t:Tween = new Tween(
    target, "prop", pennerEasing, begin, finish, duration, useSeconds);

avec Pixlib

import com.bourre.transitions.*
var t:BasicTweenFPS = (new BasicTweenFPS(
    target, "prop", finish, duration, begin, pennerEasing)).execute();
or
var t:BasicTweenMS = (new BasicTweenMS(
    target, "prop", finish, duration, begin, pennerEasing)).execute();

N'oubliez pas de télécharger et placer dans votre classPath les équations de Penner si vous ne les avez pas déjà .

EventDispatching

Finalement, il ne manque qu'une seule chose à notre service de pizza pour meriter son label OSFlash: s' affranchir de l' EventDispatcher.
La classe EventBroadcaster de Pixlib vient donc le remplacer (de façon totalement polymorphique). Quand je vous dis que Pixlib couvre tous les besoins...

Je vais m'arreter là. Vous en apprendrez davantage par vous mêmes en examinant les sources.
A noter que vous pouvez aussi commencer par explorer l'application en ligne avec Xray (la pizza est livrée avec son connector ^^).

Encore une fois ce n' était qu'une expérience de laboratoire. De plus la révision qui m'a servi est relativement ancienne. Ne soyez donc pas étonnés si la compilation échoue avec la dernière révision.

Le projet à été developpé avec FlashDevelop. J'en profite pour saluer l'equipe de FD et féliciter leur formidable travail!

Merci d'avoir lu ce premier vrai billet :) .

ActionStep, Pixlib, Swfmill

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

4 Responses to “Open Source Flash Pizza for everyone !”

Leave Comment

(required)

(required)