Многозадачность во флеше

Ранее, в этом блоге, уже была статься-конспект о Worker-ах сделанных с доклада на Adobe Max 2011. Сейчас же делаем слудующий шаг - Сокращенное изложение, не менее краткого обзора, от Тибо — многознадачности в actionscript: http://www.bytearray.org/?p=4423 .

Во-первых, многозадачность обещает выйти из prelease на свет божий уже со следующей бетой, тогда же Тибо обещает выложить более полное руковоство о многозадачности (а учитывая популярность данной темы, постараюсь и я).



В основе многозадачности лежат все те же Worker-ы – которые выбраны из-за популярности данного API.

Создание


Так выглядит создание Worker-а из swf-файла, встроенного (Embed tag) в переменную Workers.EncoderWorker.

var worker:Worker = WorkerDomain.current.createWorker(Workers.EncoderWorker);

запустить Worker очень просто


worker.start();

Можно создавать и запускать сколько угодно потоков, но стоит помнить, что каждый поток поднимает с собой отдельный flash player, что обойдется системе в среднем ~7mb.

Коммуникация


Для коммуникации между потоками используется MessageChannel API.

1
var mainToBack:MessageChannel = Worker.current.createMessageChannel(worker);
на стороне клиента мы используем setSharedProperty API, для связывания вызовов

для primordial worker-а


worker.setSharedProperty("mainToBack", mainToBack);
*Primordial worker - это тот, единственный UI-поток, с которым мы работали раньше.

и для дочернего worker-а


mainToBack = Worker.current.getSharedProperty("mainToBack");

Мелкие данные


для пересылки данных используется функция:


mainToBack.send(100);
вместо 100 можно подставить любой простой тип: Number, int, Boolean, String, Object, Null, Array, Object, XML. В качестве транспортного формата используется AMF3, а значит DisplayObject передать не получится.

Так получаем значение:


var value:uint = mainToBack.receive();
что желательно делать в обработчике события Event.CHANNEL_MESSAGE от MessageChannel.

Получение набора данных отправленных таким образом:


mainToBack.send(100);
mainToBack.send(true);
mainToBack.send([10,20]);
выглядит так:


while ( mainToBack.messageAvailable )
mainToBack.receive();

Крупная рыба (данные)


Если же надо передать более крупные данные, необходимо расшаривать память.
Для чего в ByteArray добавлено специальное свойство shareable. Теперь, если мы передаем данный ByteArray через send, то данные не сериализируются, а передаются в другой Worker ссылка. После чего новый Worker может читать и изменять полученные данные.

Эффект Вау! от ByteArray

В связке с новой функцией у BitmapData.copyPixelsToByteArray, можно переносить обработку графического изображения в отдельный Worker.

Так сгружаем данные в ByteArray


myBitmapData.copyPixelsToByteArray(myBitmapData.rect, sharedMemory);

Дележка памяти

Чтобы справиться с одновременной записью, чтением в память, Adobe добавили пакет flash.concurrent, а в нем 2 класса: Mutex и Condition. В дальнейшем Тибо обещает поведать тонкости работы с ними.

Ограничения

Есть кое какие ограничения на дочерние Worker-ы: нельзя работать с визуализацией через дерево DisplayObject-ов, с мышью, камерой и др. функциями пользовательского интерфейса.
С другой стороны, доступна работа с сетью, изображение можно подготавливать в дочернем и передавать в основной Worker.

Демонстрация

Тибо портировал библиотеку Alchemy lib (ShineMP3Encoder) о Cyril Diagne (flash-kikko), в которой wave-файл перегоняется в mp3 в отдельном потоке


A sneak peek: Concurrency with ActionScript Workers from Thibault Imbert on Vimeo.

На этом пока все, в следующий раз надеюсь будет, что пощупать руками, тогда уж - напишем!

Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями. Для этого воспользуйтесь предлагаемыми ниже кнопками:



Блог: http://romanlovetext.blogspot.com/