Как известно, дублировать как в AS2 клипы уже нельзя - нет такого метода. Странно конечно, и зря. В шаблонной структуре приложения это было бы очень полезно.
Но в AS3 есть множество средств, которыми можно это сделать. Для начала, порыщем в Google.
Duplicate Movie Clip Action Script 3 (взято у Senocular, в котором есть этот исходник).
Этот метод уже стал классикой, судя по тому, как много на него ссылается блогов и форумов. Он также описан на Flashere. Идея такова: извлекается класс исходного дисплей-объекта var targetClass:Class = Object(target).constructor;
, инстанцируется, и в него переносятся основные свойства исходного дисплей-объекта.
as3 duplicate DisplayObject. Здесь класс исходного дисплей-объекта получается аналогичным образом. Отличие лишь в том, что передаваемые свойства автоматически извлекаются посредством рефлексии - метода describeType
.
Creating Class Instances from a DisplayObject in AS3. Здесь имя класса получается более хитрым способом - из строки, возвращаемой getQualifiedClassName
. Затем, getDefinitionByName
возвращает класс исходного дисплей-объекта.
Других, более вменяемых способов решения я пока не нашел. Почему "более вменяемых"? Да потому, что все эти способы имеют одно очень существенное ограничение. Они не дублируют произвольный дисплей-объект. То есть дублируемый объект должен обязательно иметь обозначенное в Linkage имя класса. Если мы протрейсим имя класса произвольного клипа, это будет MovieClip или SimpleButton, а инстанцируя их, мы получаем просто пустые клипы.
Таким образом, дублировать клип вышеперечисленными способами нельзя если клип не имеет имени класса в Linkage.
Это еще полбеды. Ведь мы всегда можем просто взять, да и указать это имя.
Но.
А если мы внедряем в наше приложение некий клип при помощи [Embed] , который в дальнейшем надо распарсить и что-то в нем дублировать?
Это что-то мы никогда не сможем дублировать, т.к. никакие Linkage-классы из внедряемой библиотеки не распознаются - они не переносятся в ApplicationDomain.
Кстати, интересное замечание по второму способу с рефлексией: describeType для объектов из внедряемой библиотеки выдает тэги описания свойств как "accessor", в то время как для объектов из подгруженной библиотеки - "variable".
Итак, вывод - универсального решения нет, и выход один - всё делать "ручками". Или я ошибаюсь?
* * *
Спасение пришло с другой стороны: Включение файлов в SWF в виде байтовой последовательности. Проблема внедряемых файлов будет устранена, остальное, в принципе решаемо.
* * *
Да, интуиция поискать по запросу loadBytes
не подвела. Внедрил SWF вышеуказанным способом, загрузил через Loader.loadBytes
. Отлично! Даже фреймовые скрипты работают. Всё как обычный Loader.load
.
Единственная оговорка: Я загружаю классы в ApplicationDomain.currentDomain
. При этом, параметр checkPolicyFile необходимо установить в false:var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
Еще раз спасибо Garbage Collector. Глядя на дату спасительного поста, я понимаю, что здорово отстаю :(.