Расширение проектора: Продолжение 4. Синхронные вызовы.
Мда.. перерывчик вышел долгонький. Но он того стоил.
В "Продолжении 2" я говорил о том, что реализация оболочки на основе только класса LocalConnection не позволяет осуществить синхронное выполнение АС-кода и кода оболочки.
Цитата:
Из сказанного видно, что наша оболочка обладает одной весьма важной и не очень приятной особенностью: команды, отсылаемые оболочке выполняются асинхронно с кодом, их пославшим, т.е. с АС-кодом.
Но, кто ищет - тот найдет! И нашел, кажется.
Общение плеера в внешним миром во время выполнения кода ролика может быть построено разными способами. Для этого есть классы, позволяющие подгружать данные из-вне и отправлять данные наружу. Те же LC, XML, XMLSocket, MovieclipLoader... Но работа с этими классами не подразумевает синхронного выполнения кода изначально, что диктуется логикой клиент-серверного взаимодействия: отправили запрос - ждем ответа. А ответ придет не мгновенно..
Но есть класс, который общается с внешним миром синхронно, это SharedObject.
Этот класс работает с файловой сисемой непосредственно, скажем возврат метода SharedObject.getLocal() произойдет, когда нужный шаред-файл будет считан и его содержимое будет разложено по полям в соответствующем объекте. Сравним два примера работы с XML и SO:
var xml:XML = new XML(); xml.load("myXMLsource.xml"); // здесь содержимое объекта xml еще недоступно // т.е. бъект здесь пуст, мы просто отправили "запрос" // на чтение файла myXMLsource.xml. // ... xml.onLoad=function(success:Boolean){ // ну вот, файл myXMLsource.xml прочитан. // только здесь мы можем что-то делать с // загруженным xml. // причем неважно, из сети грузим или с жесткого диска } var so:SharedObject = SharedObject.getLocal('mySOsource'); // файл mySOsource.sol уже прочитан. // содержимое объекта so доступно уже здесь, в следующей строчке кода.
Разница в том, что при работе с SO плеер выполняет файловые операции и AS-код в одном потоке. А значит, можно перехватить обращение плеера к диску, выполнить "оболочечный" код, и вернуть управление обратно. Т.е. код оболочки будет выполнен синхронно с АС-кодом.
В обращение к шареду на этапе записи можно зашить команду:
var so_query:SharedObject = SharedObject.getLocal('mySOquery'); so_query.data.command = "команда_такая-то"; so_query.data.args = "строка_с_аргументами"; so_query.flush();
var so_answer:SharedObject = SharedObject.getLocal('mySOanswer'); // все, в so_answer.data сидит ответ.
function execCommand(command:String, param:String):Object { var so_query:SharedObject = SharedObject.getLocal('mySOquery'); so_query.data.command = command; so_query.data.args = param; so_query.flush(); // вот здесь мы и перехватим попытку записи на винт. // и за одно узнаем, что плеер вознамерился записать, // т.е. команду и ее аргументы // тут, собственно, и выполняется оболочечный код, формируется результат работы команды var so_answer:SharedObject = SharedObject.getLocal('mySOanswer'); // a вот здесь мы перехватим попытку чтения // и запишем в буфер, припасенный плеером для этой операции // наши данные return so_answer.data; } // где-то в коде вызов var result:Object = execCommand('команда','аргументы'); // объект result содержит результат выполнения команды. ву-аля!
Технически реализовать на строне оболочки перехват не так уж и сложно. Труднее подстроиться под реализацию работы c SO в плеере. Дело в том, что операции чтения/записи сопровождаются некоторыми предварительными действиями, как-то проверка файла на существование, определение его размера, чтение и применеие настроек LocalStorage, да и сам порядок этих действий варьируется в зависимости от последовательности действий с SO в АС-коде. Более того, как оказалось, 8-ой и 9/10-ый плееры применяют разные АПИ вызовы при работе с шаредами. Есть разница и в протоколе, т.е. 9-ка поддерживает и AMF0 и AMF3, 8-ка только AMF0. Есть некоторые заморочки с именами файлов SO. Вобщем, есть чисто технические сложности, но принципиальных препятствий для осуществления синхронных вызовов по такой схеме нет.
В настоящий момент мне удалось заставить работать синхронно с оболочкой 8-ой и 9-ый плеер (10-ку не проверял, но бегло осмотрев, увидел, что там то же, что и в 9-ке).
Потому, следующее "Продолжение", видимо будет не скоро. В связи, так сказать, с вновь открывшимися...
Но, преимущества такого подхода на лицо: упрощение кода, возможно создавать что-то на-вроде геттеров/сеттеров для классов оболочки, неограниченный объем передаваемых данных в обе стороны. Плюс остается LC, через него можно засылать ивенты в плеер, и осуществлять асинхронные операции, скажем, "анимировать иконку в трее в течение 10 сек." и т.п.)).
Ну, и в заключение, небольшой оффтоп.
Когда-то давно, я писал в каком-то топике (если вспомню, покажу) про глюк в цинке (<= 2.5.0.34), точнее про mdm.FileSystem.saveFile(). Глюк заключался в том, что при попытке сохранить за раз больше 100кб данных вываливалось плеерное окошечко "Settings.." c предупреждением о превышении размера LocalStorage. Если учесть, что по дефолту этот размер как раз и есть 100кб, то все это наводит на мысли, что разработчики цинка в тех версиях тоже юзали перехват обращений к диску через SO. Ни фига себе! Никогда бы не подумал! Вот тебе и ... mdm. Им что, СОМ-интерфейсов мало было? Хотя, скорее, неспроста все это ...
Косвенно это подтверждается еще и глюком с невозможностью сохранять шареды из цинка, кроме как в папку "/". Возможно, чего-то там с перенаправлением путей накосячили.
Во всяком случае, у меня это окошечко не вываливается)).
Всего комментариев 14
Комментарии
24.08.2009 17:23 | |
Цитата:
если пользователь установит НЕ СОХРАНЯТЬ ни байта в SO
Запускаю просто проектор - ограничение 100кб, например, показывает.(правая кнопка->Settings...). Параллельно запускаю проектор с длл - показывает то, что я ему подсунул. Анлимит, скажем. Если файл настроек отсутствует, прежде чем дергаться распаковываю дефолтный файл из ресурсов, дальше все как описано выше. При выходе удаляю.Хотя можно и оставить, в принципе. Конечно, если работать с шаредами обычным образом - то лучше после инициализации оболочки, но это не страшно)). К сожалению, полностью исключить обращения к диску не удается(( - вот это не есть кулл. Приходится иметь все же темповские шареды на винте, хоть и пустые. Для восьмого можно было бы и без них, проверял и получалось. Но вот 9/10 - не хотят без них. Как-то хитро там организована работа с этими файлами, во всяком случае функции kernel32 юзаются меньше, CreateFile() вообще не юзаетсоя, к примеру. Сейчас пытаюсь реализовать все это под AS3/AMF3. Из AMF3 планирую реализовать string и byte array. Из AMF0 string и large string. |
|
Обновил(-а) alexcon314 24.08.2009 в 17:30
|
07.09.2009 19:27 | |
Цитата:
что такое scale Form, ссылку дали бы что ли..
http://en.wikipedia.org/wiki/Scaleform |
07.09.2009 19:29 | |
Создать проектор можно при помощи stand-alone плеера. Скачать его можно в любое время с сайта адоба.
|
05.02.2010 08:53 | |
Добил вчера класс для наложения ПНГ-маски на окно проектора. Маску можно брать из файла, из ресурсов длл/ехе или генерить налету в плеере. Можно так же цеплять анимированные гифы.
|
|
Обновил(-а) alexcon314 05.02.2010 в 08:56
|
05.02.2010 15:21 | |
alexcon314, а каков механизм получения маски "генерить налету в плеере"?
Неужто удалось добраться до битмапы в AVM1? |
Последние записи от alexcon314
- Пишем свою оболочку для FP под Windows. Шаг 6. (19.05.2011)
- Пишем свою оболочку для FP под Windows. Шаг 5. (18.05.2011)
- Пишем свою оболочку для FP под Windows. Шаг 4. (18.05.2011)
- Пишем свою оболочку для FP под Windows. Шаг 3. (18.05.2011)
- Пишем свою оболочку для FP под Windows. Шаг 2. (17.05.2011)