12

「登録された」イベント ハンドラ クラスのリスナー メソッドを呼び出してイベントをディスパッチするイベント ディスパッチャ クラスを持つゲーム エンジン/ライブラリを作成しています。適切なディスパッチャー メソッドを呼び出すことで、イベント ハンドラー/リスナーをイベント ディスパッチャーに登録できます。

これは明らかに、すべてのイベント ハンドラーを登録するためのボイラープレート コードにつながります (また、私のエンジンの他の側面にも同様のボイラープレート コードがあります)。そのため、コーディング中にイベント ディスパッチャに明示的に登録する必要はありません。プログラムの実行時に、ディスパッチャの register メソッドの呼び出しが自動的に追加されます。

インストルメンテーションを使用するには、何らかのバイトコード修飾子 API を使用する必要があることを理解しています。ASM と BCEL の 2 つを知っています。どちらを使用する必要がありますか? 明らかに、これは私が行おうとしているやや単純なタスクであるため、学習しやすく、より適切に文書化されたタスクが必要です。

編集:これは具体的な例です。

元のイベント ハンドラ クラス:

@Handler //indicates this this class should be transformed
public class MouseEventHandler implements EventHandler<MouseEvent>
{
    //hidden default constructor
    public void handleEvent(MouseEvent event)
    { ... }
}

変換後:

@Handler
public class MouseEventHandler implements EventHandler<MouseEvent>
{
    public MouseEventHandler()
    {
        //add this line of code to default constructor
        Game.getEventDispatcher().addEventHandler(this);
    }
    public void handleEvent(MouseEvent event)
    { ... }
}
4

2 に答える 2

25

Java バイトコード ライブラリ:

  • ASMは高速で積極的に開発されています。
  • BCELは比較的遅いです。
  • Java バイトコードに慣れていない場合は、Javassistを使用するのがおそらく最も簡単です。
  • cglibは ASM の上に構築され、より高いレベルの抽象化を提供します。
  • Byte Buddyは、DSL を介してクラスを生成します。積極的にメンテナンスされ、使用量が増加しています。

ただし、バイトコード操作に飛び込む前に、他のオプションを検討します。

于 2012-04-18T08:31:00.947 に答える
6

いくつかのクラスにロジックを追加するのは退屈かもしれませんが、何千ものハンドラーがない限り、それが私のやり方です。シンプルにしてください

そうは言っても、

Game.registerHandler( this );

よりオブジェクト指向になります。

各クラスにロジックを追加する代わりに、ハンドラのインスタンス化を担当するファクトリを導入することもできます。

HandlerFactory.createMouseHandler();

メソッドcreateMouseHandlerには次のようなものが含まれています

Handler mh = new MousheHandler();
registerHandler(mh);
return mh;

これらのオプションのいずれも必要ない場合は、アスペクト フレームワーク(おそらく AspectJ) または制御の反転用のコンテナー(おそらく Spring IoC) のいずれかを検討します。アスペクトを使用すると、ソースに注釈を付けて、選択した場所にコードを「織り込む」ことができます。IoC コンテナーを使用すると、オブジェクトのライフサイクルを制御できます (インスタンス化など)。どちらもバックグラウンドでバイトコード インストルメンテーションを使用します。

しかし、インストルメンテーションを自分で行いたい場合は、私が個人的に使用した Javassist と ASM しか比較できません。

ASMは低レベルであり、実際には Java バイトコードのレベルで動作します。あなたはそれに精通している必要があります。フレームワークは非常によく設計されており、マニュアルは優れており、優れたライブラリです。いわゆる「ステートフル」変換が必要なため、バイトコードのパターンを置き換えるのは複雑になる場合があります。一方では、バイトコードを完全に制御できます。

Javassistはより高レベルです。フィールドの読み取り/書き込み、メッセージ送信、コンストラクターなど、バイトコードの生のレベル、つまりわずかに高いレベルでは操作しません。また、フレームワークによってコンパイルされる通常の Java 構文を使用して変更を指定することもできます。プロジェクトが長年にわたって成長したため、API は少し混乱しています。フレームワークに関するドキュメントがありますが、ASM ほど集中化されていません。

于 2012-04-18T09:08:20.227 に答える