Войти или зарегистрироваться

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

DPOH-VAR

Старожил
Пользователь
Баллы
153
Иногда приходится зарегистрировать событие на небольшой промежуток времени:
Вот примеры:
  • Пользователь ввел команду, и должен что-то выбрать пкм. Тогда требуется создать хандлер для события клика мышкой, а после события - хандлер уничтожить.
  • Создаем динамит, который при взрыве спавнит крипера. Т.е. необходимо зарегистрировать обработчик события взрыва всего лишь для одного действия.
Можно, конечно, реализовать это постоянным прослушиванием события, а объекты, на которые нужно реагировать, передавать в объект хандлера для проверки. Но есть способ проще и элегантнее:
Итак, приступим:
1. Создаем такой класс:
Java:
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, но с методами обработки событий внутри:
Java:
TempListener listener = new TempListener() {
        @EventHandler
        public void handle(SomeEvent event) {
            if(/*все в порядке*/){
                //обработка
                unregister();
            }  
        }
};
listener.register();
Чтобы передать вовнутрь обработчика объект, добавьте ему модификатор final

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

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

Преимущества:
  • Легко создать обработку события прям внутри кода.
  • Listener не будет постоянно проверять событие. Он работает только с момента регистрации и до выполнения нужного действия
Недостатки:
  • Для разрешения сложных ситуаций требуется дополнительная HashMap.
  • При неаккуратном использовании можно породить огромную кучу обработчиков.
Если есть способ это сделать лучше и элегантнее - предлагайте свои варианты!
 
Последнее редактирование:
Назад
Верх