Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Dismiss Notice

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

Discussion in 'Руководства, инструкции, утилиты' started by DPOH-VAR, Jul 16, 2013.

  1. Автор темы
    DPOH-VAR

    DPOH-VAR Старожил Пользователь

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


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

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

    3. Получаем HandlerList
    Code:
    handlerList = getEventListeners(getRegistrationClass(clazz));
    Но для этого нам понадобятся два простеньких метода:
    Code:
    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. Собственно регистрируем:
    Code:
    handlerList.register(registeredListener);
    Поздравляю! Теперь вы обрабатываете эвент, даже не зная заранее его тип.

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

    Я знаю только один вариант применения этого метода: Плагины, основанные на обработке событий (планировщики, триггеры, скрипты и т.д). Хотя возможно и понадобится использовать этот хак в следующих версиях Bukkit, вечно он связывает руки.
     
    Last edited: Nov 6, 2013
  2. Хостинг MineCraft
    <

Share This Page