1

わかりました、これは説明するのがかなり紛らわしいです。私は自分のベストを尽くす。

@EventHandler を使用するだけで void をイベント ハンドラーにすることができる Bukkit Event System に触発されました。

例:

@EventHandler
public void aRandomName(PlayerMoveEvent ev) {

}

ご覧のとおり、メソッドの名前は重要ではありません。どのイベントが渡されるかは、イベント引数の型によって決まります。

すべてのイベントは Event クラスを拡張します。1 つのことを除いて、動作すると思われるコードを作成しました。

public List<Object> eventContainers;

public void fireEvent(Event e) {

    Method[] methods;

    for (Object o : eventContainers) {
        Object[] classes = o.getClass().getClasses();

        for (Object clss : classes) {
            methods = clss.getClass().getMethods();
            for (Method m : methods) {
                if (m.getAnnotation(EventHandler.class) != null) {
                    try {
                        Class[] requiredTypes = m.getParameterTypes();
                        for(Class cl : requiredTypes) {
                            if(e.equals(cl)) {
                                m.invoke(clss, e);
                            }
                        }

                    } catch (IllegalAccessException ex) {
                    } catch (IllegalArgumentException ex) {
                    } catch (InvocationTargetException ex) {
                    }
                }
            }
        }
    }
}

私のコードは何をしますか: eventContainers 内のすべてのクラスをループし、@EventHandler アノテーションを持つメソッドを探し、指定されたイベントをそのメソッドに送信します。ただし、fireEvent(Event e) で指定されたイベントがどのようなイベントであるかを確認し、その種類のイベント パラメーターを必要とするメソッドを調べたいと考えています。どうすればいいですか?私はそれを理解します

Class[] requiredTypes = m.getParameterTypes();
for(Class cl : requiredTypes) {
  if(e.equals(cl)) {
    m.invoke(clss, e);
  }
}

動作しないでしょう。

最終的には、イベントをプラグインに渡すことができるようにしたいと考えています。このような:

EventManager.fireEvent(new PlayerMoveEvent(player));

これは、すべてのプラグインとプラグインに送信されます

@EventHandler
public void aVoid(PlayerMoveEvent e) {
//stuff
}

ご不明な点がございましたら、より適切に説明できるよう努めます。よろしくお願いします。

4

4 に答える 4

0

コードを変更して、動作するイベント システムにしました!!!!!! :D andersschullerさん、どうもありがとう!

public void fireEvent(Event e) {

    Method[] methods;

    for (Object o : eventContainers) {
        methods = o.getClass().getMethods();
        for (Method m : methods) {
            if (m.getAnnotation(EventHandler.class) != null) {
                try {

                    if (m.getParameterTypes()[0].isAssignableFrom(e.getClass())) {
                        m.invoke(o, e);
                    }
                } catch (IllegalAccessException ex) {
                } catch (IllegalArgumentException ex) {
                } catch (InvocationTargetException ex) {
                }
            }
        }
    }
}

私はすべての答えを念頭に置いていました、ありがとう!

于 2013-08-27T17:57:24.277 に答える
0

アノテーションEventHandler付きメソッドにパラメーターが 1 つしかない場合

Method[] methods = YourClass.class.getDeclaredMethods();
Object yourInstance = null; // get it
Event e = null; // get it
for (Method method : methods) {
    EventHandler handler = method.getAnnotation(EventHandler.class);
    if (handler != null) {
        Class<?>[] parameterTypes = method.getParameterTypes();
        // you're going to need different logic if you have more than one parameter
        if (parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(e.getClass())) {
            method.invoke(yourInstance, e);
        }
    }
}

例外処理は含めていません。

イベント ハンドラー候補クラスのすべてのメソッドを取得し、それらを反復処理します。メソッドに@EventHandlerアノテーションがある場合、そのパラメーターの型リストを取得します。パラメータが 1 つしかなく、そのタイプがイベント タイプから割り当て可能である場合はe.getClass()、イベントを渡して呼び出します。

于 2013-08-27T17:35:59.490 に答える