mxmlc/amxmlc のコンパイルの背景
- Date
- 2007-07-30 (Mon)
- Category
- AIR / ActionScript
Flex SDK は
- 無料 で使えて、
- 馴染みのテキストエディタを使ってActionScipt の編集ができて
- .swf か .air がコンパイル出来る
というよいものです。2週間ほど触ってみて理解した事などをまとめてみます。
大事なのは以下の三点。
- mxmlc は .as を .swf へ変換する、(java で書かかれた)コンパイラ
- その中で、画面への描画をしたいなら、DisplayObject を extends したクラスを作る必要がある。
- これは予想だけれども、Display Object と全く同じ signature をもつ別のクラスを作れば、Display Object を extends する必要はないと思う。そのかわり Display Object Container やらいろいろ自分で実装せねばならないけれども。でもこのクラス図が提供する世界観がきらいとか、それではどうにもならない、という人が新しい世界を作れる、というのはすばらしい。
- amxmlc は、mxmlc に Air 用のプリプロセスを含めたコンパイラ。Air 用のプリプロセス、とは
- いくつかの Air 専用メタデータ(アノテーション)を ActionScript 3 の文法内で再現できるようにすること(マクロ展開みたいなもの。でも java のアノテーションも同じように、コンパイル前のプリプロセスでやってるんだよね?)
- mxml を .as ファイルへ変換する事
- 以上の事より、amxmlc が展開する .mxml という xml ファイルは無名パッケージで同名の public class に変換される、ということ。
例えば、Hoge.mxml というファイルで、以下のような内容だったとする
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="0xFFCC00" > <mx:Script source="bootstrap.as"/> </mx:WindowedApplication>
これは、
package
{
import mx.core.WindowedApplication
public class Hoge extends WindowedApplication
{
public var layout:String = "absolute";
public var backgroundColor:uint = "0xFFCC00";
/* bootstrap.as の内容がここに挿入される */
public function Hoge ():void
{
}
}
}
という内容の Hoge.as ファイルが作成される事。
当初の目的
僕がしたかったのは、mxml を作る人(DreamWeaver なり Flex Builder なり、何らかの Visual Editing Software を使う人。)と、.as のコードを書く人を分けたかった。で、そのために一番簡単なのは、.mxml の root content (上の例で云えば mx:WindowedApplication )に何らかの event トリガを仕込む事。creationComplete を使うのが一般的かしらん。
でも、それだと、コード側が全権掌握できない。というか、creationComplete の前に何かしたい時どうする、とか、creationComplete で発動させたい関数の名前が変わる時いちいち mxml 作る人に話さなきゃいけないとか、そもそも静的にはアクセスできない関数をトリガしたい、とかいろいろ問題がある。で、どうするのか考えて、僕なりに出した結論が以下のような bootstrap.as で、上の Hoge.mxml から呼び出されている内容です。
// this code works as a bootstrap import mx.core.Application; import mx.events.FlexEvent; import mx.controls.Alert;
public var myvar:int = 0;
public function initilizer (ev:Event):void { //trace("init: Start"); Alert.show(this); trace(this.myvar); //trace("init: End"); }
Shell.shell.addEventListener(InvokeEvent.INVOKE, function(ev:InvokeEvent):void { // because Application.application is not set yet this moment. Application.application.addEventListener(FlexEvent.CREATION_COMPLETE, Application.application.initilizer); });
一番大きなポイントは、イヴェントの発動が2段構えなところでしょうか。何故こんな面倒な事をしているかというと、上で一度説明していますが、amxmlc がコンパイルする時、この bootstrap.as は変換された Hoge.as の一部に挿入されるだけ、だからなんですね。もし
- Application.application.addEventListener の行を一番外側に持ってこようとすると動かない→実行時にまだその Object は出来てないから。
- Application.application.addEventListener でリスンさせている関数が Application.application.initilizer という見慣れない完全修飾型になっているのは、呼び出し元によって、default の名前空間(端的に言えば this )が変わるから。これは Javascript をやってる人にはなじみが深いと思うのだけれど、instance method 内で this を使うと、普段はちゃんと動くのだけれど、Event からトリガされると this が切り替わってしまって動かないとか。それと同じ。
- Shell.shell の InvokeEvent.INVOKE には、closure をあてているのは、意味のない関数に名前のあてるが癪だから。
これがわかるまで、グローバルに配置しておきたい変数宣言を何処におくかとか、名前空間とか、めちゃくちゃ悩みました。もう遅いので後で、自分が使うプロトタイプなどをアップしておきます。
Comment:0
Trackback:0
- TrackBack URL for this entry
- http://blogs.grf-design.com/mt/mt-tb.cgi/229
- Listed below are links to weblogs that reference
- mxmlc/amxmlc のコンパイルの背景 from The Croton