如何让我的动作脚本3级,在两个SWF文件使用,解决同一类当一个SWF动态加载其他?(How do I

2019-09-18 06:55发布

背景

我正在开发的纯动作脚本3(我们使用Flex 4 SDK自动建立我们的,但我们所有的代码必须能够直接在Flash CS4 Professional中编译)一个高度模块化的应用程序。

我们有一个“framework.swc”文件,该文件中包含有我们所有的模块之间共享接口的定义,我们有我们的加载其他模块“mainmodule.swf”,然后我们有我们的其他模块的各种SWF文件。 我们使用Loader类,符合的ApplicationDomain :: getDefinition方法()一起选择用于加载类动态[我们用“的新LoaderContext(假,ApplicationDomain.currentDomain来)”]。

问题

我们所有的模块实现了“AbstractModule”界面,该界面中的“framework.swc”定义。 当我实例化一个动态加载的模块,但是,(模块是AbstractModule)返回false。 更重要的是,如果我叫module.someMethod(someobject),其中someobject实现了“framework.swc”并在模块的方法,预计“framework.swc”的定义相同接口的对象定义的接口,我得到一个运行时错误“类型错误:错误#1034:类型强制失败:不能转换到_ _”。

看来,“mainmodule.swf”和“loadedmodule.swf”(我一直在加载测试的模块),是在内部,使用单独的定义为“framework.swc”共享接口

我怎样才能让“mainmodule.swf”和“loadedmodule.swf”解决他们的共同界面,共享的定义,使类铸件和分类比较正确地成功吗?

Answer 1:

好。 这是不是最漂亮的解决方案,但它会奏效。 基本上,每个接口“AbstractX”(替换“X”用别的东西),你需要创建两个包装类:“ImportX”和“ExportX”。 ExportX的目标是成功扩大AbstractX键入对象,通过包装AbstractX,提供所有相同的方法类型AbstractX,但仅内建/预定义数据类型或它们在它们的签名闪光的一部分的数据类型使用。 ImportX的目的是缩小动态加载的对象与作为类型AbstractX相同的特性(但不能转换为类型AbstractX并没有被识别为类型AbstractX),但类型对象到AbstractX接口。 无论ExportX和ImportX使用ImportY,ImportZ等; 然而,使用ExportX ImportY,ImportZ等包参数,它代表以式AbstractX的目的,而ImportX使用它们来包裹的返回值,从委托给对象类型的对象来对。 为了使这个多一点理解,我提出下面的例子:

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 ...


Answer 2:

你应该尝试-compiler.external-library-path作为记录在这里 ......这样一来,就可以在接口上建立一个SWC有依赖关系,这不是它,而是来自另一个,从而避免冲突...别知道该怎么做,在CS4虽然...

格尔茨

back2dos



Answer 3:

您可能需要使用运行时共享库​​(RSL)。 一个RSL允许你这样做动态链接。 但是,我不知道是否CS4可以建立的。 也许你会重新考虑“必须能够直接在Flash CS4编译”的要求,或可考虑通过在CS4 IDE宏/脚本使用Flex SDK编译。

如果这是绝对不是一个选择,另一种方法是将有模块之间的松散耦合,并依靠更多的主权财富基金模块,而不是代码级集成隐含常见的外部接口。



Answer 4:

我不知道100%如果你需要什么,但是盖亚框架实现一个全球性的API,许多主权财富基金共享彼此交互。 你可以检查出来,也许得到一些想法。 现在,我面临着不少类似的情况是你的,所以我检查的替代品......这个职位将是非常有用的,谢谢!



文章来源: How do I make an Action Script 3 class, used in two SWF files, resolve to the same class when one SWF dynamically loads the other?