О фреймах во Flash
Запись от alatar размещена 27.04.2011 в 15:50
В контексте флеш-плеера и AVM2 можно выделить три типа кадров.
- Кадр swf файла. Это набор тегов от начала файла и до тега ShowFrame (неважно какого по счету, хоть первого, хоть десятого). Небольшой перевод из спецификации swf. Стр. 29 раздел Processing a SWF file:
Цитата:Flash Player обрабатывает все теги в SWF файле, пока не встретит тег ShowFrame. В этой точке, список отображения копируется на экран и Flash Player переходит в режим ожидания, пока не настанет время обработки следующего кадра. Содержимое первого кадра — это результат кумулятивного выполнения всех управляющих тегов от начала файла и до первого тега ShowFrame. Содержимое второго кадра — это результат кумулятивного выполнения всех управляющих тегов от начала файла и до вторго тега ShowFrame. И т.д. - Кадр MovieClip / Sprite (в контексте файла swf, между ними нет разницы). Sprite по структуре похож на swf файл, т.е. кадром у него является набор тегов между DefineSprite и ShowFrame. Но, есть существенное отличие от первого типа. В рамках спрайте не могут содержаться ресурсы. Никакие, даже объявление шейпа, только управляющие теги.
- Кадр виртуальной машины. Грубо говоря, время между ENTER_FRAME и EXIT_FRAME, когда может выполняться код.
Так вот. Кадров первого типа может и не быть. Спецификация никак не регламентирует порядок и количество / состав тегов в SWF файле. Т.е. нет никаких препятствий собрать валидный SWF файл с одним единственным тегом DoABC (тег в котором содержится скомпилированный код AS3).
При таком подходе есть несколько неприятных (но вполне преодолимых) моментов. Несмотря на то, что файл валидный, его не получится загрузить с помощью Loader'a. Точнее загрузить получится, но мы не получим ниодного события (даже INIT) и код не будет выполнен, ввиду кумулятивного эффекта выполнения.
Переходим к практике
Для начала создадим файл без кадров (примечание: файл изначально не должен содержать внедренных ресурсов). Для этого нам понадобится тулза swfmill.
Процесс простой, берется swf файл, перегоняется с помощью swfmill в xml, после чего можно ручками вырезать все лишнее и перегнать обратно в swf. Для тестов можно взять уже подготовленный файл abc_test.zip.
Можете посмотреть его структуру с помощью swfdump из Flex SDK или из swftools и убедиться, что в нем не осталось ничего, кроме обязательных тегов и тега DoABC.
Теперь осталось только
После чего пишем следующее:
package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.utils.ByteArray; import flash.utils.getDefinitionByName; import org.as3commons.bytecode.abc.AbcFile; import org.as3commons.bytecode.swf.AbcClassLoader; import org.as3commons.bytecode.swf.SWFFile; import org.as3commons.bytecode.swf.SWFFileIO; import org.as3commons.bytecode.tags.DoABCTag; [SWF(width="1024", height="768")] public class ABCTest extends Sprite { private var _urlLoader:URLLoader = new URLLoader(); public function ABCTest() { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; _urlLoader.addEventListener(Event.COMPLETE, bytes_completeHandler); _urlLoader.dataFormat = URLLoaderDataFormat.BINARY; _urlLoader.load(new URLRequest("abc_test.swf")); } private function bytes_completeHandler(event:Event):void { trace("bytes complete"); var io:SWFFileIO = new SWFFileIO(); var swfFile:SWFFile = io.read(_urlLoader.data as ByteArray); var abcTags:Array = swfFile.getTagsByType(DoABCTag); for each(var tag:DoABCTag in abcTags) { var abcFile:AbcFile = tag.abcFile; var abcLoader:AbcClassLoader = new AbcClassLoader(); abcLoader.addEventListener(Event.COMPLETE, classLoader_CompleteHandler); abcLoader.loadAbcFile(abcFile, ApplicationDomain.currentDomain); } } private function classLoader_CompleteHandler(event:Event):void { trace('class loaded'); var TestClass:Class = getDefinitionByName('Airplane') as Class; addChild(new TestClass()); } } }
Всего комментариев 9
Комментарии
28.04.2011 12:08 | |
В конечном итоге он создаст swf с SHOWFRAME и загрузит.
|
28.04.2011 12:59 | |
мне тоже так кажется, что после загрузки классы все равно будут доступны для использования в основной и без танцев с бубном
|
28.04.2011 13:12 | |
Цитата:
В конечном итоге он создаст swf с SHOWFRAME и загрузит.
Цитата:
мне тоже так кажется, что после загрузки классы все равно будут доступны для использования в основной и без танцев с бубном
|
|
Обновил(-а) alatar 28.04.2011 в 18:46
|
28.04.2011 13:38 | |
Цитата:
Классы "грузятся" напрямую в указаный applicationDomain. Без промежуточного создания swf
|
28.04.2011 13:42 | |
Цитата:
Не создаст. Классы "грузятся" напрямую в указаный applicationDomain
UPD. Ничего заумного. Там loader.loadBytes(bytes, context); |
|
Обновил(-а) dimarik 28.04.2011 в 14:37
|
28.04.2011 18:45 | |
Нда, действительно. Сначала создается swf, потом грузится.
|
Последние записи от alatar
- Трансформации вокруг произвольной точки (05.02.2015)
- Декомпозиция матрицы. (25.12.2014)
- Баги TextField в iOS (29.07.2013)
- [Spark] Стрелочный индикатор. (06.12.2012)
- RSLs Monkey Patching (23.01.2012)