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

Туториал Временная регистрация события

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

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

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

    Trophy Points:
    153
    Skype:
    dpohvar
    Иногда приходится зарегистрировать событие на небольшой промежуток времени:
    Вот примеры:
    • Пользователь ввел команду, и должен что-то выбрать пкм. Тогда требуется создать хандлер для события клика мышкой, а после события - хандлер уничтожить.
    • Создаем динамит, который при взрыве спавнит крипера. Т.е. необходимо зарегистрировать обработчик события взрыва всего лишь для одного действия.
    Можно, конечно, реализовать это постоянным прослушиванием события, а объекты, на которые нужно реагировать, передавать в объект хандлера для проверки. Но есть способ проще и элегантнее:
    Итак, приступим:
    1. Создаем такой класс:
    Code:
    public abstract class TempListener implements Listener {
      
        private boolean registered = false;
    
        public final TempListener register() {
            registered = true;
            Bukkit.getPluginManager().registerEvents(this, YourPlugin.plugin);
            return this;
        }
    
        public final TempListener unregister() {
            registered = false;
            HandlerList.unregisterAll(this);
            return this;
        }
    
        public final boolean isRegistered() {
            return registered;
        }
    }
    где YourPlugin.plugin - статическая ссылка на объект вашего плагина. (Можно, конечно, передавать плагин вовнутрь функции register() - но не красиво ;) )

    2. В том месте, где нужно зарегистрировать обработчик - создаем анонимный TempListener, но с методами обработки событий внутри:
    Code:
    TempListener listener = new TempListener() {
            @EventHandler
            public void handle(SomeEvent event) {
                if(/*все в порядке*/){
                    //обработка
                    unregister();
                }  
            }
    };
    listener.register();
    Чтобы передать вовнутрь обработчика объект, добавьте ему модификатор final

    Таким образом, TempListener будет прослушивать события ровно столько, сколько это нужно. Как только потребуется снова реакция на событие, создается новый TempListener.

    Может возникнуть ситуация, когда на одного игрока/на один объект требуется установить не более одного обработчика события. Например, когда игрок должен ввести команду, а потом пкм выбрать блок или объект. Решается проблема хранением связки (игрок=>listener) внутри HashMap.

    Преимущества:
    • Легко создать обработку события прям внутри кода.
    • Listener не будет постоянно проверять событие. Он работает только с момента регистрации и до выполнения нужного действия
    Недостатки:
    • Для разрешения сложных ситуаций требуется дополнительная HashMap.
    • При неаккуратном использовании можно породить огромную кучу обработчиков.
    Если есть способ это сделать лучше и элегантнее - предлагайте свои варианты!
     
    Last edited: Nov 6, 2013
    kaban1997 and DoctorBooooom like this.
  2. Хостинг MineCraft
    <

Share This Page