Туториал Продвинутая регистрация события

DPOH-VAR

Старожил
Пользователь
Баллы
153
В этом посте я хочу поделиться еще одним интересным способом регистрации событий, чуть универсальнее, чем ЭТОТ.
Например, нам надо повесить обработку на заранее неизвестный эвент, который нам передается в виде класса. (Мы получаем Class<? extends Event> clazz)
Делается это так:


1. Создаем обработчик (EventExecutor), который будет обрабатывать наш эвент:
Java:
EventExecutor executor = new EventExecutor() {
    public void execute(Listener listener, Event event) throws EventException {    
        if(clazz.isInstance(event)) { // проверка обязательна, хотя кажется лишней
            // обработка, например
            handle(event);
        }
    }
};
вместо handle(event) можно сделать что угодно.

2. Cоздаем RegisteredListener
Java:
registeredListener = new RegisteredListener(null,executor,priority, plugin,false);
Параметры:
null - обычный Listener. Но он нам не нужен, поэтому ставим null
priority - приоритет обработки, определяет то, каким на очереди будет стоять обработчик.
plugin - ваш плагин.
false - игнорировать обработку, если эвент отменен. лучше поставить false

3. Получаем HandlerList
Java:
handlerList = getEventListeners(getRegistrationClass(clazz));
Но для этого нам понадобятся два простеньких метода:
Java:
public static Class<? extends Event> getRegistrationClass(Class<? extends Event> clazz) {
    try {
        clazz.getDeclaredMethod("getHandlerList");
        return clazz;
    } catch (NoSuchMethodException e) {
        if (clazz.getSuperclass() != null
                && !clazz.getSuperclass().equals(Event.class)
                && Event.class.isAssignableFrom(clazz.getSuperclass())) {
            return getRegistrationClass(clazz.getSuperclass().asSubclass(Event.class));
        } else {
            throw new IllegalPluginAccessException("Unable to find handler list for event " + clazz.getName());
        }
    }
}

public static HandlerList getEventListeners(Class<? extends Event> type) {
    try {
        Method method = getRegistrationClass(type).getDeclaredMethod("getHandlerList");
        method.setAccessible(true);
        return (HandlerList) method.invoke(null);
    } catch (Exception e) {
        throw new IllegalPluginAccessException(e.toString());
    }
}

4. Собственно регистрируем:
Java:
handlerList.register(registeredListener);
Поздравляю! Теперь вы обрабатываете эвент, даже не зная заранее его тип.

5. Отключаем обработчик
если надоест прослушивать этот непонятный эвент, всегда есть возможность воспользоваться методом:
Java:
handlerList.unregister(registeredListener);

Область применения

Я знаю только один вариант применения этого метода: Плагины, основанные на обработке событий (планировщики, триггеры, скрипты и т.д). Хотя возможно и понадобится использовать этот хак в следующих версиях Bukkit, вечно он связывает руки.
 
Последнее редактирование:
Назад
Верх