BeInteractive!

何かアクセスが増えてると思ったら、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

この記事へのコメント

Taka wrote:
SUGEEE!
っていうか、__bytecode__を実践投入してる人を初めて見ますた。

ナイスなコード勉強になりました。ありがとうございます。
arkw wrote:
Flash Player 8.0系だけの技ですか?
yossy wrote:
>Takaさん
実際、自分も使うのは始めてです..

>arkwさん
バイトコード自体は Player7 で通るはずです。7の仕様書見ながら書きましたし。
__bytecode__がコンパイルできるFlashがどのバージョンかはちょっと分かりません。少なくともFlash8では通りました。
arkw wrote:
ありがとうございます。

Flash8IDEで作ってるのになんで動かないんだろうって
はまってたら、FlashPlayer8.5だった罠でした。

8.0をインストールして試してみます。

コメント書き込み:

カテゴリ

タグ

アーカイブ