Comment puis-je faire un script d'action 3 classe, utilisé dans deux fichiers SWF, résoudre à la même classe quand un fichier SWF charge dynamiquement l'autre?

StackOverflow https://stackoverflow.com/questions/1112111

Question

Historique

Je développe une application modulaire très pur en Action Script 3 (nous utilisons le SDK Flex 4 pour automatiser notre builds, mais tout notre code doit être en mesure de compiler directement dans Flash CS4 Professional).

Nous avons un fichier « framework.swc » qui contient des définitions d'interface qui sont partagées entre tous nos modules, nous avons un « mainmodule.swf » qui charge nos autres modules, puis nous avons différents fichiers .swf pour nos autres modules . Nous utilisons la classe Loader, conjointement avec ApplicationDomain :: getDefinition () pour les classes de chargement dynamique [nous utilisons "nouvelle LoaderContext (faux, ApplicationDomain.currentDomain)"].

Problème

Tous nos modules implémentent l'interface "AbstractModule", qui est défini dans "framework.swc". Lorsque j'instancie un module chargé dynamiquement, cependant, (module est AbstractModule) renvoie faux. Plus important encore, si je l'appelle module.someMethod (SomeObject), où SomeObject implémente une interface définie dans « framework.swc » et où la méthode du module attend un objet de la même interface définie dans « framework.swc », je reçois une erreur d'exécution "TypeError: erreur # 1034: type Coercion a échoué: ne peut pas convertir _ à _."

Il semble que « mainmodule.swf » et « loadedmodule.swf » (le module E ai chargement pour le test), sont, en interne, en utilisant des définitions distinctes pour les interfaces partagé « framework.swc »

Question

Comment puis-je faire « mainmodule.swf » et « loadedmodule.swf » résoudre leurs interfaces communes à une définition partagée, de sorte que la coulée de classe et la comparaison de la classe réussissent correctement?

Était-ce utile?

La solution

Ok. Ce n'est pas la plus jolie solution, mais il fonctionnera. En fait, pour chaque interface « AbstractX » (remplacer « X » avec quelque chose d'autre), vous devez créer deux classes d'emballage: « ImportX » et « ExportX ». L'objectif de ExportX est d'élargir avec succès AbstractX à type d'objet, en enroulant un AbstractX, fournissant toutes les mêmes méthodes que le type AbstractX, mais d'utiliser uniquement les types de données / prédefinis prédéfinis ou les types de données qui font partie du flash dans leurs signatures. Le but de ImportX est de réduire dynamiquement un objet chargé avec les mêmes caractéristiques que le type AbstractX (mais qui ne peuvent pas être exprimées au type AbstractX et qui ne sont pas reconnus en tant que type AbstractX), mais est de type objet à l'interface AbstractX. Les deux ExportX et ImportX utilisent ImportY, Importz, etc .; Cependant, ExportX utilise ImportY, Importz, etc. pour envelopper les paramètres qu'il délègue à un objet de type AbstractX, alors que ImportX les utilise pour envelopper les valeurs de retour, qui se réalisent de déléguer à un objet de type objet. Pour faire un peu plus compréhensible, je vous présente les exemples suivants:

public interface AbstractX
{
    // The export/import functions are mandatory 
    // for all such interfaces. They allow
    // for the wrappers to be correctly manipulated.
    function export() : Object;
    function original() : Object;

    // The interface functions vary from 
    // interface to interface. They can
    // be called something much more appropriate.
    function interfaceFunction1(param : AbstractY) : AbstractZ;
    function interfaceFunction2(param : AbstractA) : AbstractB;
}
// A class of type Import_ always implements Abstract_
public class ImportX implements AbstractX
{
    // The constructor for an Import_ Object
    // is always of type Object.
    public function ImportX(obj : Object) : void {
        _loadedobj = obj;
        _exportobj = obj.export();
    }

    // Every Import_ class must implement a similar "wrap" function:
    public static function wrap(obj : Object) : AbstractX {
        var result : AbstractX = null; 
        if ( obj != null ){
            if ( obj is AbstractX ){ // Don't wrap if convertible, directly.
                result = obj as AbstractX;
            }else if ( obj.original() is AbstractX ){ // Don't double wrap
                result = obj.original() as AbstractX;
            }else{
                // Needs to be wrapped.
                result = new ImportX(obj);
            }
         }
         return result;
     }

    public function export() : Object {
        return _exportobj;
    }

    public function original() : Object {
        return _loadedobj;
    }

    // For the interface functions, we delegate to _exportobj
    // and we wrap the return values, but not the parameters.
    public function interfaceFunction1(param : AbstractY) : AbstractZ {
        return AbstractZ.wrap(_exportobj.interfaceFunction1(param));
    }

    public function interfaceFunction2(param : AbstractA) : AbstractB {
        return AbstractB.wrap(_exportobj.interfaceFunction2(param));
    }

    private var _loadedobj : Object;
    private var _exportobj : Object;
}
// Although an Export_ object provides SIMILAR methods to type Abstract_,
// the signatures need to be changed so that only builtin/predefined types
// appear. Thus Export_ NEVER implements Abstract_.
public class ExportX
{
    // The constructor to Export_ always takes an object of type Abstract_
    public function ExportX(obj : AbstractX) : void {
        _obj = obj;
    }

    public function original() : Object {
        return _obj;
    }

    public function export() : Object {
        return this;
    }

    // For the interface functions, we delegate to _obj
    // and we wrap the parameters, not the return values.
    // Also note the change in signature.
    public function interfaceFunction1(param : Object) : Object {
        return _obj.interfaceFunction1(AbstractY.wrap(param));
    }

    public function interfaceFunction2(param : Object) : Object {
        return _obj.interfaceFunction2(AbstractA.wrap(param));
    }

    private var _obj : AbstractX = null;
}
// The definition of class X can occur in and be loaded by any module.
public class X implements AbstractX
{
    public function X( /* ... */ ) : void {
        //...
    }

    public function export() : Object {
        if ( ! _export ){
            _export = new ExportX(this);
        }
        return _export;
    }

    public function original() : Object {
        return this;
    }

    public function interfaceFunction1(param : AbstractY) : AbstractZ {
        // ...
    }

    public function interfaceFunction2(param : AbstractA) : AbstractB {
       // ...
    }

    private var _export : Object = null;
}
// Ok. So here is how you use this...
var classx   : Class = dynamicallyLoadClassFromModule("X","module.swf"); 
var untypedx : Object = new classx();
var typedx   : AbstractX = ImportX.wrap(untypedx);
// Use typedx ...

Autres conseils

vous devriez essayer -compiler.external-library-path comme documenté ... De cette façon, vous peut construire un SWC ayant sur les dépendances d'une interface, qui est pas, mais vient d'une autre, évitant ainsi les collisions ... ne savent pas comment faire dans CS4 si ...

greetz

back2dos

Vous pouvez utiliser une bibliothèque partagée à l'exécution (RSL). Un RSL vous permet de faire la liaison dynamique. Cependant, je ne sais pas si CS4 peut les construire. Peut-être que vous pourriez revenir sur la « doit être en mesure de compiler directement dans Flash CS4 » exigence ou regarder dans la compilation à l'aide du SDK Flex grâce à des macros / scripts dans le CS4 IDE.

Si c'est absolument pas une option, une autre approche serait d'avoir un couplage plus souple entre les modules, et de compter sur plus d'une interface externe commune implicite pour le module d'intégration au lieu des fonds souverains au niveau du code.

Je ne suis pas sûr à 100% si son que vous avez besoin, mais Cadre Gaia implémente une API globale , partagé d'interagir les uns avec les autres par de nombreux fonds souverains. Vous pouvez le vérifier et peut-être obtenir quelques idées. En ce moment je suis confronté à une situation assez semblable au vôtre, donc je vérifiais alternatives ... ce poste sera très utile, merci!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top