何かアクセスが増えてると思ったら、fladdict.netさんからトラックバックが来てた。スクリプトエンジンで(一部の)ビルトインクラスのnewが上手くいかないので汎用ファクトリを作ろうという話です。
何気なしに考えてたら、(あまり美しくは無いですが)バイトコード直書き(Cのインラインアセンブラみたいなの)で実現できることに気付いたので書いておきます。
まず、次のコードを1フレーム目とかに書いておきます。長いですが、区切ったり改行入れたりしないで下さい。
__bytecode__("8E2E00637265617465496E7374616E636546726F6D537472696E67000200062A0001706174680002706172616D73005B0096020004011C8701000317960A000402006C656E677468004e8701000417960500070000000087010005179604000405040448129d02001800960400040204054e9602000405508701000517990200daff9605000404040303533e");
これを書くと、createInstanceFromString()というメソッドが定義されます。ので、次のようにして使います。
import flash.display.BitmapData;
var b:BitmapData = createInstanceFromString("flash.display.BitmapData", [10, 10]);
第1引数にクラスのコンストラクタへのパスを文字列で、第2引数にコンストラクタに渡す引数を配列にして呼び出します(要素は何個でも大丈夫です)。すると、オブジェクトが生成されて返ってきます。以上。
実際どんなことをやっているか、flasmで見やすくしたバイトコードを載せておきます。
function2 createInstanceFromString (r:1='path', r:2='params') ()
push r:path
getVariable
setRegister r:3
pop
push r:params, 'length'
getMember
setRegister r:4
pop
push 0
setRegister r:5
pop
label1:
push r:5, r:4
lessThan
not
branchIfTrue label2
push r:params, r:5
getMember
push r:5
increment
setRegister r:5
pop
branch label1
label2:
push r:4, r:3, UNDEF
newMethod
return
end // of function createInstanceFromString
要は配列の要素を push してスタックに積んで、 newMethod を呼んでるだけです。
追記
上のコードバグってました。ストリングからクラスのインスタンスを作る 訂正をご覧下さい。
サイト内関連記事
この記事へのトラックバック
トラックバックはありません。
TrackBack URL:
http://www.be-interactive.org/trackback.php?id=152

っていうか、__bytecode__を実践投入してる人を初めて見ますた。
ナイスなコード勉強になりました。ありがとうございます。
実際、自分も使うのは始めてです..
>arkwさん
バイトコード自体は Player7 で通るはずです。7の仕様書見ながら書きましたし。
__bytecode__がコンパイルできるFlashがどのバージョンかはちょっと分かりません。少なくともFlash8では通りました。
Flash8IDEで作ってるのになんで動かないんだろうって
はまってたら、FlashPlayer8.5だった罠でした。
8.0をインストールして試してみます。