Использование Flex вместе с haXe
Это черновая версия статьи о том, как совместить Flex-фреймворк и haXe. Здесь описан один из способов разработки Flex-приложения для 9-го флэш-плеера с использованием кода на haXe.
Статья требует базовых знаний о Flex, haXe, AS3 и MXML. Решение, описанное в статье, разрабатывалось и отлаживалось на релиз-версии 9-го флэш-плеера. На более ранних бета-версиях оно может не работать.
В примере используется минимальный MXML-файл и AS3 класс для инициализации Flex-приложения и загрузки внешнего swf-файла, содержащего классы haXe в виде байт-кода флэш-плеера.
Минимальное Flex-приложение содержит довольно много кода. Его можно посмотреть, если при компиляции указать опцию "compiler.keep-generated-actionscript". При этом компилятор mxmlc сохранит промежуточный AS-код, сгенерированный из MXML. Там вы обнаружите массу кода, выполняющего загрузку и инициализацию Flex-приложения.
Код во Flex-приложении размещен в двух отдельных кадрах фильма. Первый кадр содержит SystemManager и классы загрузчика, инициирующие процесс загрузки, второй кадр содержит весь остальной код приложения. Это позволяет быстро загрузить и выполнить код первого кадра и отслеживать загрузку остального кода приложения.
В идеале, нужно было бы скомпилировать минимальное Flex-приложение компилятором mxmlc, а затем внедрить наши haXe классы во второй кадр сгенерированного swf-файла. Однако я не уверен, что это получится, поэтому пошел другим путем -- Flex-приложение динамически загружает swf-файл, содержащий haXe классы, затем AS3 классы создают и вызывают haXe классы и наоборот.
Минимальное Flex-приложение
Создайте новый файл со следующим MXML кодом:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:base="*"> <base:ApplicationCanvas/> </mx:Application>
Сохрание его как haxeflex.mxml. Это самый минимальный MXML файл который просто создает экземпляр класса ApplicationCanvas на сцене. Мы определим класс ApplicationCanvas в отдельном AS3 файле. Создайте новый файлы с именем ApplicationCanvas.as и добавьте в него код:
package { import flash.display.*; import flash.net.URLRequest; import flash.events.Event; import mx.core.*; import mx.controls.*; import mx.containers.*; import flash.system.ApplicationDomain; import flash.system.LoaderContext; public class ApplicationCanvas extends Canvas { public function ApplicationCanvas() { // load haxeApplication swf var ldr:Loader = new Loader(); var swfUrl:String = "haxeApplication.swf"; var req:URLRequest = new URLRequest(swfUrl); var ldrContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain); ldr.load(req, ldrContext); ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoaded); // Nested callback function for SWF loading function swfLoaded(e:Event):void { // TODO - load an instance of the HaxeApplication class } } } }
Наконец, скомпилируйте приложение компилятором mxmlc:
"mxmlc haxeflex.mxml"
Будет сгенерирован файл haxeflex.swf.
Создаем haXe-библиотеку
Теперь создадим базовый swf-файл, содержащий пустой haXe класс. Мы добавим его позже. Создайте новый файл с именем HaxeApplication.hx:
class HaxeApplication { // contructor public function new() { } }
Скомпилируйте haXe приложение:
"haxe -swf-version 9 -swf haxeApplication.swf HaxeApplication"
Будет сгенерирован swf-файл с именем haxeApplication.swf содержащий пустой класс.
Загружаем haXe-библиотеку
Система безопасности флэш-плеера по умолчанию не разрешает загрузку внешнего фильма в локальной файловой системе. Я уверен, что есть способ обойти это ограничение, но я избежал этого, просто используя локальный веб-сервер (Apache). Так что теперь нужно скопировать swf-файлы в document root веб-сервера и загрузить их с помощью браузера:
http://localhost/haxeflex.swf
Если все в порядке (не возникло никаких исключений), то вы увидите пустой серой фон Flex-приложения. Это значит, что Flex-приложение успешно загрузило swf-файл с haXe классом.
Создаем экземпляры haXe классов из AS3
Экземпляр класса HaxeApplication создается в два шага: загрузка определения класса и использование оператора new с этим определением. Замените тело функции swfLoaded в ApplicationCanvas.as следующим кодом:
// Get the definition of the HaxeApplication class from the application domain var haxeApplicationDef:Class = ApplicationDomain.currentDomain.getDefinition("HaxeApplication") as Class; // Use the new operator to create a new instance of the class var haxeApplication:Object = new haxeApplicationDef();
Снова скомпилируйте haxeflex.mxml и откройте приложение в браузере. Вы не увидите никаких изменений, но и никаких ошибок не возникнет. Значит экземпляр класса успешно создан.
Создаем и вызываем AS3 классы из haXe
Последний шаг в нашем примере -- создать новый компонент Flex button в классе HaxeApplication и вернуть его экземпляру AS3 canvas, который, в свою очередь добавит его как child.
Чтобы создать экземпляр не-haXe класса, нужно предоставить компилятору описание интерфейса этого класса. Для этого мы создадим описание внешнего класса -- каркас, описывающий только public методы и свойства. Ключевое слово extern скажет компилятору, что этот класс будет скомпилирован отдельно.
Чтобы компилятор имел описания всех классов пакета mx, нужно установить библиотеку Flex haXe, запустив команду:
haxelib install flex
Теперь можно просто добавить"-lib flex" к параметрам компиляции и собрать проект компилятором haXe.
Компилятор будет знать о Flex-классе Button так что мы можем подключить его конструкцией import, создать экземпляр и обращаться к его свойствам, как и с обычным haXe классом. Добавьте такой import и новый метод в HaxeApplication.hx и скомпилируйте его:
import mx.controls.Button; //-- SNIP -- public function getButton():Button { var button:Button = new Button(); button.label = "Hello Flex world from haXe"; return button; }
Теперь добавьте в ApplicationCanvas.as вызов метода getButton:
// fetch the button instance - call to a haXe class var button: Button = haxeApplication.getButton(); // add the button to the canvas addChild(button);
Скомпилируйте MXML приложение и загрузите haxetest.swf в браузере. Вы увидите серый фон и кнопку с надписью Hello Flex world from haXe.
Наше AS3 Flex-приложение создало экземпляр haXe класса HaxeApplication, вызвало его метод, который, в свою очередь, создал и вернул экземпляр AS3 класса. Теперь AS3 и haXe классы могут взаимодействовать в обоих направлениях.