Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > alatar

Рейтинг: 5.00. Голосов: 2.

О фреймах во Flash

Запись от alatar размещена 27.04.2011 в 15:50

В контексте флеш-плеера и AVM2 можно выделить три типа кадров.
  1. Кадр swf файла. Это набор тегов от начала файла и до тега ShowFrame (неважно какого по счету, хоть первого, хоть десятого). Небольшой перевод из спецификации swf. Стр. 29 раздел Processing a SWF file:
    Цитата:
    Flash Player обрабатывает все теги в SWF файле, пока не встретит тег ShowFrame. В этой точке, список отображения копируется на экран и Flash Player переходит в режим ожидания, пока не настанет время обработки следующего кадра. Содержимое первого кадра — это результат кумулятивного выполнения всех управляющих тегов от начала файла и до первого тега ShowFrame. Содержимое второго кадра — это результат кумулятивного выполнения всех управляющих тегов от начала файла и до вторго тега ShowFrame. И т.д.
  2. Кадр MovieClip / Sprite (в контексте файла swf, между ними нет разницы). Sprite по структуре похож на swf файл, т.е. кадром у него является набор тегов между DefineSprite и ShowFrame. Но, есть существенное отличие от первого типа. В рамках спрайте не могут содержаться ресурсы. Никакие, даже объявление шейпа, только управляющие теги.
  3. Кадр виртуальной машины. Грубо говоря, время между ENTER_FRAME и EXIT_FRAME, когда может выполняться код.

Так вот. Кадров первого типа может и не быть. Спецификация никак не регламентирует порядок и количество / состав тегов в SWF файле. Т.е. нет никаких препятствий собрать валидный SWF файл с одним единственным тегом DoABC (тег в котором содержится скомпилированный код AS3).

При таком подходе есть несколько неприятных (но вполне преодолимых) моментов. Несмотря на то, что файл валидный, его не получится загрузить с помощью Loader'a. Точнее загрузить получится, но мы не получим ниодного события (даже INIT) и код не будет выполнен, ввиду кумулятивного эффекта выполнения.

Переходим к практике
Для начала создадим файл без кадров (примечание: файл изначально не должен содержать внедренных ресурсов). Для этого нам понадобится тулза swfmill.
Процесс простой, берется swf файл, перегоняется с помощью swfmill в xml, после чего можно ручками вырезать все лишнее и перегнать обратно в swf. Для тестов можно взять уже подготовленный файл abc_test.zip.

Можете посмотреть его структуру с помощью swfdump из Flex SDK или из swftools и убедиться, что в нем не осталось ничего, кроме обязательных тегов и тега DoABC.

Теперь осталось только захотеть, что бы картинка ожила запустить код из этого swf. Для этого понадобится набор библиотек из проекта AS3Commons. Если конкретно, то нужны библиотеки Bytecode, Lang, Logging и Reflect.

После чего пишем следующее:
Код AS3:
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());
        }
    }
}
В результате, в текущий applicationDomain будут загружены классы из abc_test.swf и их можно будет инстанцировать с помощью getDefinitionByName.
Всего комментариев 9

Комментарии

Старый 28.04.2011 12:08 etc вне форума
etc
 
Аватар для etc
В конечном итоге он создаст swf с SHOWFRAME и загрузит.
Старый 28.04.2011 12:59 in4core вне форума
in4core
 
Аватар для in4core
мне тоже так кажется, что после загрузки классы все равно будут доступны для использования в основной и без танцев с бубном
Старый 28.04.2011 13:12 alatar вне форума
alatar
 
Аватар для alatar
Цитата:
В конечном итоге он создаст swf с SHOWFRAME и загрузит.
Не создаст. Классы "грузятся" напрямую в указаный applicationDomain. Без промежуточного создания swf.
Цитата:
мне тоже так кажется, что после загрузки классы все равно будут доступны для использования в основной и без танцев с бубном
Не будут.
Обновил(-а) alatar 28.04.2011 в 18:46
Старый 28.04.2011 13:38 gloomyBrain вне форума
gloomyBrain
 
Аватар для gloomyBrain
Цитата:
Классы "грузятся" напрямую в указаный applicationDomain. Без промежуточного создания swf
А как? Мне просто сам принцип интересен
Старый 28.04.2011 13:42 dimarik вне форума
dimarik
 
Аватар для dimarik
Цитата:
Не создаст. Классы "грузятся" напрямую в указаный applicationDomain
Научите этому кунг-фу )

UPD. Ничего заумного. Там loader.loadBytes(bytes, context);
Обновил(-а) dimarik 28.04.2011 в 14:37
Старый 28.04.2011 18:45 alatar вне форума
alatar
 
Аватар для alatar
Нда, действительно. Сначала создается swf, потом грузится.
Старый 28.04.2011 22:48 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Ага. Давно ещё проводили тесты, и пришли к выводу, что Loader умеет отображать только флешки. Это объясняет нужду преобразования картинок в swf. Картинки, кстати, преобразовываются в AVM1 movie, т.к. только с него можно считать байты до Event.COMPLETE/INIT, что неплохо.
Старый 29.04.2011 00:13 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
Цитата:
Сообщение от Psycho Tiger
Картинки, кстати, преобразовываются в AVM1 movie, т.к. только с него можно считать байты до Event.COMPLETE/INIT, что неплохо.
вот это новость ... а можно ссылку на первоисточник?
Старый 29.04.2011 12:42 dimarik вне форума
dimarik
 
Аватар для dimarik
Про преобразование или что "только с него (AVM1 movie) можно считать байты"? Первое верно, если глянуть дамп bytes. Дамп не содержит DoABC тегов, а значит не будет исполняться ни в AVM1, ни в AVM2. Про второе не понял. Байтики невозможно считать до COMPLETE.
 

 


Часовой пояс GMT +4, время: 10:59.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.