背景
我正在开发的纯动作脚本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”解决他们的共同界面,共享的定义,使类铸件和分类比较正确地成功吗?
好。 这是不是最漂亮的解决方案,但它会奏效。 基本上,每个接口“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 ...
你应该尝试-compiler.external-library-path
作为记录在这里 ......这样一来,就可以在接口上建立一个SWC有依赖关系,这不是它,而是来自另一个,从而避免冲突...别知道该怎么做,在CS4虽然...
格尔茨
back2dos
您可能需要使用运行时共享库(RSL)。 一个RSL允许你这样做动态链接。 但是,我不知道是否CS4可以建立的。 也许你会重新考虑“必须能够直接在Flash CS4编译”的要求,或可考虑通过在CS4 IDE宏/脚本使用Flex SDK编译。
如果这是绝对不是一个选择,另一种方法是将有模块之间的松散耦合,并依靠更多的主权财富基金模块,而不是代码级集成隐含常见的外部接口。
我不知道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?