Actionscript 3 - Библиотеки скриптов
Я пытаюсь загрузить полученный SWF-файл из сборки SWC вручную. Из-за моей специфической среды нам необходимо разделить определения классов на swcs (где это имеет смысл), чтобы удалить избыточный код из выходных swfs.
В двух словах, я определяю класс (LibA
) в SWF, который я строю с compc
, Я компилирую его как в формат SWC, так и в каталог, так что я могу легко извлечь файл library.swf из каталога для загрузки во время выполнения (внешнее связывание) и использовать SWC для компиляции из любого SWF, созданного либо с помощью Flash CS5, либо mxmlc
,
LibA.as:
package
{
public class LibA
{
public function LibA()
{
trace("*** LibA()");
}
}
}
Main.as:
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.LoaderContext;
public class Main extends Sprite
{
private var self:Main;
private var context:LoaderContext;
public function Main()
{
var l:Loader = new Loader();
self = this;
l.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event) {
self.addChild(l.content);
var liba:LibA = new LibA();
});
l.load(new URLRequest("./libs/build/liba.swf"));
}
}
}
Я создаю SWC / каталог SWC с
compc -output libs/build/liba.swc -include-sources libs/LibA.as -debug=true
и я устанавливаю соответствующую связь в настройках AS3 во Flash CS5 при сборке Main
(класс связан непосредственно со сценой).
Все публикуется без проблем.
Тем не менее, во время выполнения я получаю VerifyError: Error #1014: Class LibA could not be found.
Что мне здесь не хватает? Я хочу иметь возможность загружать и использовать классы, определенные в liba.swf
от моего Main.swf
,
Полный дамп трассировки:
verify Function/<anonymous>()
stack:
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
0:getlex 4
stack: Main?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
2:getlex 7
stack: Main? flash.display::Loader?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
4:getproperty content
stack: Main? flash.display::DisplayObject?
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
6:callpropvoid addChild 1
stack:
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
9:findpropstrict LibA
stack: Object
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
11:constructprop 10 0
stack: *
scope: [global Object$ flash.events::EventDispatcher$ flash.display::DisplayObject$ flash.display::InteractiveObject$ flash.display::DisplayObjectContainer$ flash.display::Sprite$ Main$ Main Main]
locals: Object flash.events::Event? *
14:coerce LibA
VerifyError: Error #1014: Class LibA could not be found.
2 ответа
Если вы хотите загрузить классы из SWF, вам нужно сделать что-то вроде (в вашем обработчике событий):
var li:LoaderInfo = e.target as LoaderInfo; // get the loaderInfo object from the event
var swf:MovieClip = li.loader.content as MovieClip; // get the swf
var c:Class = swf.loaderInfo.applicationDomain.getDefinition( "LibA" ) as Class; // get the class definition for LibA
Создание нового c
должен дать вам свой LibA
объект. Вам понадобится полное определение класса в качестве имени.
Если я понимаю, что вы пытаетесь сделать, я уверен, что вы можете настроить SWC для встраивания внешней библиотеки - то есть вы получаете завершение кода, но ни один из классов не включен, и SWC ищется во время выполнения.
РЕДАКТИРОВАТЬ
Просто попробовал что-то вроде того, что ты делаешь. В моем примере выше, когда вы создаете c
, если вы проследите это, он проследит LibA
, Однако, если вы явно ссылаетесь на него, вы получите ошибку, которую вы описали. Я думаю, что это потому, что Flash путается с по существу двумя определениями LibA
- тот, на который ссылались, и тот, который вы загружаете - они находятся в 2 разных доменах приложений.
Исправление таково, как описывает @turbosqel, загрузите его с LoaderContext
объект:
var l:Loader = new Loader();
var context:LoaderContext = new LoaderContext( false, ApplicationDomain.currentDomain );
l.contentLoaderInfo.addEventListener(Event.COMPLETE, this._onLoadComplete );
l.load(new URLRequest("./libs/build/liba.swf"), context);
Это работает для меня, теперь я могу явно ссылаться на LibA
учебный класс.
liba не существует, пока ваш SWF не загружен, потому что вы не импортируете его в main.
Что означает, что во время компиляции его там нет
Переехать var liba:LibA = new LibA();
в вызов функции в загруженном корне SWF и вызов функции после загрузки e.currentTarget.someFunc