问题描述
背景
我开发的纯动作脚本3(我们使用Flex 4 SDK用来自动化生成,但我们所有的code必须是能够直接在Flash CS4 Professional中编译)。
I am developing a highly modular application in pure Action Script 3 (we are using Flex 4 SDK to automate our builds, but all our code must be able to compile directly in Flash CS4 Professional).
我们有一个framework.swc文件,该文件中包含有我们所有的模块之间共享接口的定义,我们有一个mainmodule.swf加载了其它模块,然后我们有我们的其他模块不同的SWF文件。我们使用Loader类,在同一起选择:: ApplicationDomain中getDefinition()用于加载类动态[我们用的新LoaderContext(假,ApplicationDomain.currentDomain来)]。
We have a "framework.swc" file which contains interface definitions which are shared between all our modules, we have a "mainmodule.swf" that loads our other modules, and then we have various .swf files for our other modules. We are using the Loader class, in conjuction with ApplicationDomain::getDefinition() for loading classes dynamically [we use "new LoaderContext(false,ApplicationDomain.currentDomain)"].
问题
我们所有的模块执行AbstractModule接口,它是在framework.swc定义。当我实例化一个动态加载的模块,但是,(模块AbstractModule)返回false。更重要的是,如果我叫module.someMethod(someobject),其中someobject实现了framework.swc并在模块的方法,预计framework.swc中定义的同一接口的对象定义的接口,我得到一个运行时错误类型错误:错误#1034:类型强制失败:无法转换为_ _。
All our modules implement the "AbstractModule" interface, which is defined in "framework.swc". When I instantiate a dynamically loaded module, however, (module is AbstractModule) returns false. More importantly, if I call module.someMethod(someobject), where someobject implements an interface defined in "framework.swc" and where the module's method expects an object of the same interface defined in "framework.swc", I get a runtime error "TypeError: Error #1034: Type Coercion failed: cannot convert _ to _."
看来,mainmodule.swf和loadedmodule.swf(模块我一直在加载测试),都在内部,使用单独的定义为framework.swc
It seems that "mainmodule.swf" and "loadedmodule.swf" (the module I have been loading for testing), are, internally, using separate definitions for the shared interfaces in "framework.swc"
问题
我怎样才能让mainmodule.swf和loadedmodule.swf解决他们的公共接口到共享的定义,使类铸件类比较正确的成功吗?
How can I make "mainmodule.swf" and "loadedmodule.swf" resolve their common interfaces to a shared definition, so that class casting and class comparison succeed correctly?
推荐答案
确定。这不是prettiest解决方案,但它的工作。基本上,每一个接口AbstractX(替换X别的东西),你需要创建两个包装类:ImportX和ExportX。 ExportX的目标是成功地扩大AbstractX键入对象,通过包装AbstractX,提供所有相同的方法类型AbstractX,而是利用pdefined仅内建/ $ P $数据类型或数据类型,它们是闪光灯在它们的签名部分。 ImportX的目标是缩小动态加载对象具有相同的特性类型AbstractX(但不能转换为类型AbstractX并没有被识别为类型AbstractX),但是Object类型的AbstractX接口。既ExportX和ImportX使用ImportY,ImportZ等;然而,ExportX使用ImportY,ImportZ等包装参数,它代表类型AbstractX的对象,而ImportX用它们来包装的返回值,这都从大约委托给Object类型的对象。为了使这个多一点理解,我present下面的例子:
Ok. This isn't the prettiest solution, but it will work. Basically, for every interface "AbstractX" (replace "X" with something else), you need to create two wrapper classes: "ImportX" and "ExportX". The goal of ExportX is to successfully widen AbstractX to type Object, by wrapping an AbstractX, providing all the same methods as type AbstractX, but to use only builtin/predefined data types or data types which are part of flash in their signatures. The goal of ImportX is to narrow a dynamically loaded object with the same characteristics as type AbstractX (but which cannot be cast to type AbstractX and which is not recognized as type AbstractX) but is of type Object to the AbstractX interface. Both ExportX and ImportX use ImportY, ImportZ, etc.; however, ExportX uses ImportY, ImportZ, etc. to wrap parameters, which it delegates to an object of type AbstractX, while ImportX uses them to wrap return values, which come about from delegating to an object of type Object. To make this a little more understandable, I present the following examples:
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 ...
这篇关于如何让我的动作脚本3类,在两个SWF文件中使用,解决同一类当一个SWF动态加载其他的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!