이벤트 리스너
이벤트를 호출받으려면 이벤트 리스너를 등록해야 합니다. 이벤트 리스너를 등록하려면 아무런 이름으로 메소드를 하나 정의하고, 메소드의 첫번째 매개 변수로 원하는 이벤트 종류를 대입하세요. 그 다음 이 메소드의 꼭대기에 Listener 어노테이션을 아래 예제 코드처럼 붙이면 됩니다.
import org.spongepowered.api.event.Listener;
@Listener
public void onSomeEvent(SomeEvent event) {
// Do something with the event
}
참고로 이러한 메소드는 이벤트 매니저에 등록시켜야 비로소 동작합니다:
팁
플러그인의 메인 클래스에서 정의한 (Plugin 어노테이션이 붙은) 이벤트 리스너들에 한해서는 Sponge가 자동으로 이벤트 매니저에 리스너를 등록시켜 줍니다.
참고
이벤트 버스는 부모 타입을 지원합니다. 예를 들어, ChangeBlockEvent.Break는 ChangeBlockEvent를 상속합니다. 따라서 ChangeBlockEvent
이벤트 리스너를 등록하면 해당 이벤트뿐만 아니라 ChangeBlockEvent.Break
도 호출받을 수 있습니다. 하지만 상속의 정의에 따라 반대의 경우는 성립하지 않습니다.
이벤트 리스너 등록과 등록 해지
플러그인의 메인 클래스가 아닌 곳에서 정의된 @Listener
어노테이션이 붙은 이벤트 리스너를 활성화시키려면, EventManager#registerListeners(Object, Object) 를 사용하세요. 이 메소드는 첫번째 매개 변수로 플러그인, 두번째 매개 변수로 이벤트 리스너를 포함하는 클래스를 대입하면 해당 리스너가 Sponge 서버에 등록됩니다.
예제 코드: 외부 클래스에서 이벤트 리스너를 등록하기
import org.spongepowered.api.Sponge;
public class ExampleListener {
@Listener
public void onSomeEvent(SomeEvent event) {
// Do something with the event
}
}
Sponge.getEventManager().registerListeners(this, new ExampleListener());
이벤트 리스너를 동적으로 등록하기
(스크립트 플러그인처럼) 이벤트 리스너를 동적으로 등록시켜야 할 경우도 있습니다. 이 경우엔 클래스가 EventListener
인터페이스를 구현하면 됩니다. 단, 리스너 메소드에는 @Listener
어노테이션을 붙이지 마세요. 이제 EventManager#registerListener
메소드를 호출하여 첫번째 매개 변수로 플러그인을, 두번째로 이벤트 종류를 식별하는 이벤트 클래스
를, 세 번째 매개 변수로 현재 클래스(리스너)를 대입하면 이벤트 리스너가 동적으로 등록됩니다. 부가적으로, 세 번째 매개 변수에 리스너의 우선순위를 결정할 Order를 대입할 수 있고, 네 번째 매개 변수(리스너 인스턴스 앞)에 boolean을 대입하여 서버가 수정되기 전에 리스너 호출을 받을 여부를 정의할 수도 있습니다. 추신: 동적 이벤트 리스너란 한 마디로 하나의 이벤트를 하나의 클래스로 관리한다는 것으로 해석됩니다.
예제: EventListener 클래스 구현하기
import org.spongepowered.api.event.EventListener;
import org.spongepowered.api.event.block.ChangeBlockEvent;
public class ExampleListener implements EventListener<ChangeBlockEvent.Break> {
@Override
public void handle(ChangeBlockEvent.Break event) throws Exception {
[...]
}
}
예제: EventListener를 동적으로 등록하기
EventListener<ChangeBlockEvent.Break> listener = new ExampleListener();
Sponge.getEventManager().registerListener(this, ChangeBlockEvent.Break.class, listener);
팁
@Listener
어노테이션이 붙은 이벤트 리스너에 한해서, About @Listener 를 참고하여 호출 우선순위를 지정할 수 있습니다. 하지만 위 예제처럼 동적 이벤트의 경우, 이벤트를 등록시킬 때 사용한 EventManager#registerListener
의 세 번째 매개 변수에 호출 순서를 정의하는 Order
를 대입하면 됩니다.
이벤트 리스너 등록 해지하기
매개 변수로 클래스의 객체를 받는 EventManager#unregisterListeners(Object) 메소드를 사용하면, 해당 클래스에 등록된 이벤트 리스너들을 등록 해지할 수 있습니다.
EventListener listener = ...;
Sponge.getEventManager().unregisterListeners(listener);
또는, EventManager#unregisterPluginListeners(Object) 메소드에 플러그인을 매개 변수로 대입시켜 호출하면, 해당 플러그인에 등록된 모든 이벤트 리스너가 등록 해지됩니다. 이 메소드는 @Listener
어노테이션이 붙은 것도 포함하여 모든 이벤트 리스너를 비활성화시킨다는 점을 명심하십시오.
PluginContainer plugin = ...;
Sponge.getEventManager().unregisterPluginListeners(plugin);
@Listener 에 대하여
@Listener
어노테이션에는 몇 가지 필드 옵션이 있습니다:
order
is the priority in which the event listener is to be run. See the Order enum in SpongeAPI to see the available options.beforeModifications
는 Forge 모드와 같은 다른 서버 모드들 보다 우선적으로 이벤트를 호출받을지 여부를 결정합니다. 기본적으로 false 값을 갖습니다.
Cancellable 인터페이스를 구현하는 이벤트에 한해서 다른 플러그인에 의해 이벤트의 동작이 중단되면, 기본적으로는 @Listener
가 붙은 당신의 이벤트 리스너는 호출되지 않도록 설계되어 있습니다.
GameReloadEvent
To prevent all plugins providing their own reload commands, Sponge provides a built-in callback for plugins to listen
to, and when executed, perform any reloading actions. What constitutes as a ‘reloading action’ is purely up to the
plugin to decide. The GameReloadEvent will fire when a player executes the
/sponge plugins reload
command. The event is not necessarily limited to reloading configuration.
import org.spongepowered.api.event.game.GameReloadEvent;
@Listener
public void reload(GameReloadEvent event) {
// Do reload stuff
}
이 이벤트는 플러그인들에게 리로드 기능을 수행하도록 지시하는 회신일 뿐, 이벤트 자체가 서버에 수행하는 기능(서버 재시작 등)은 없습니다. 일반적으로 여러분이 ‘리로드’라고 생각하는 것과 이것은 다를 수 있습니다.
이벤트 호출하기
이벤트를 배포하여 이벤트 리스너들을 호출시키려면, Event 인터페이스를 구현하는 객체가 필요합니다.
이벤트 버스(EventManager) 를 통해 이벤트를 발생시킬 수 있습니다:
boolean cancelled = Sponge.getEventManager().post(theEventObject);
이 메소드는 이벤트 실행이 취소되면 true
, 그렇지 않으면 false
값을 반환합니다.
Sponge 이벤트 호출하기
정적 클래스 SpongeEventFactory
를 통해 서버의 내장 이벤트의 인스턴스를 생성할 수 있습니다. 이 클래스는 자동으로 생성되므로 Javadoc이 없습니다. IDE의 자동완성 기능으로 클래스의 메소드 목록을 확인하세요. SpongeEventFactory
로 이벤트를 생성하면 인스턴스가 EventManager#post(Event) 로 넘어갑니다.
예제: LightningEvent 호출하기
import org.spongepowered.api.event.action.LightningEvent;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.event.cause.EventContext;
import org.spongepowered.api.event.cause.EventContextKeys;
import org.spongepowered.api.event.SpongeEventFactory;
PluginContainer plugin = ...;
EventContext eventContext = EventContext.builder().add(EventContextKeys.PLUGIN, plugin).build();
LightningEvent lightningEvent = SpongeEventFactory.createLightningEventPre(Cause.of(eventContext, plugin));
Sponge.getEventManager().post(lightningEvent);
경고
매개 변수에 Cause 를 빈 값으로 대입할 수 없습니다. 최소한으로 플러그인 컨테이너는 포함시키세요.