外部ライブラリのロード機能を実装

先日から悩んでいた外部ライブラリ(以下、モジュール)のロードをようやく実装できました。
実行時にリンクされるモジュールは、FlashのSWFファイルとして生成します。
そして、SWFファイルの中に、初期化や実行など、呼び出しに必要な関数を定義しておきます。
また、モジュールを利用するにあたって、葵の関数定義にモジュール関数である旨を指定します。

葵の関数定義は以下のようにします。
一般的な葵の関数定義の後ろに「="SWFファイル名"@番号」のように関数にファイル名、番号を記述します。

## モジュール定義ファイル
## [形式] ●日本語関数名(引数定義)="SWFファイル名"@番号
## 以下定義例
●足す(AにBを)="ModuleMath"@0
●引く(AからBを)="ModuleMath"@1
●乗(Nの,E)="ModuleMath"@2

次に、SWFファイルですが、以下のように定義します。
SWFファイル中に最低「aoimodule_call」という関数だけあれば葵のモジュールとして機能します。

/** ModuleMath.fla の 1フレーム目に記述 */
function aoimodule_call(func_no, arg:ModuleFunctionArg) {
    switch (func_no) {
        case 0: func_add(arg); break;
        case 1: func_sub(arg); break;
        case 2: func_power(arg); break;
    }
}
function func_add(arg:ModuleFunctionArg) {
    arg.return_num( arg.getArgNum(0) + arg.getArgNum(1) );
}
function func_sub(arg:ModuleFunctionArg) {
    arg.return_num( arg.getArgNum(0) - arg.getArgNum(1) );
}
function func_power(arg:ModuleFunctionArg) {
    arg.return_num( arg.getArgNum(0) * arg.getArgNum(1) );
}

フリーのFlashコンパイラMTASCを使う場合は自身のパスを取得できないので、仮想マシンのモジュールのロード先を得てから、「_root.aoimodule["モジュール名"]」に関数を登録するという作業が必要です。

/** ModuleMath.as : Math モジュールの定義例 */
// ライブラリ作成例
class ModuleMath {
    // エントリポイント
    static function main() {
        // 自身のパスを得る
        var mc:MovieClip = _root.aoimodule["ModuleMath"];
        // 関数の登録
        mc.aoimodule_call = function (func_no, arg:ModuleFunctionArg) {
            switch (func_no) {
                case 0: ModuleMath.func_add(arg); break;
                case 1: ModuleMath.func_sub(arg); break;
                case 2: ModuleMath.func_power(arg); break;
            }
        };
    }
    // 静的なメソッドを定義
    static function func_add(arg:ModuleFunctionArg) {
        KLog.write("func_add()");
        arg.return_num( arg.getArgNum(0) + arg.getArgNum(1) );
    }
    static function func_sub(arg:ModuleFunctionArg) {
        arg.return_num( arg.getArgNum(0) - arg.getArgNum(1) );
    }
    static function func_power(arg:ModuleFunctionArg) {
        arg.return_num( arg.getArgNum(0) * arg.getArgNum(1) );
    }
}

Java版ではまだこれを実装していないのですが、Javaの場合は、リフレクションを使うことになりそうです。
参考)http://www.ne.jp/asahi/hishidama/home/tech/java/reflection.html