이벤트 리스너

이벤트를 호출받으려면 이벤트 리스너를 등록해야 합니다. 이벤트 리스너를 등록하려면 아무런 이름으로 메소드를 하나 정의하고, 메소드의 첫번째 매개 변수로 원하는 이벤트 종류를 대입하세요. 그 다음 이 메소드의 꼭대기에 Listener 어노테이션을 아래 예제 코드처럼 붙이면 됩니다.

import org.spongepowered.api.event.Listener;

@Listener
public void onSomeEvent(SomeEvent event) {
    // Do something with the event
}

참고로 이러한 메소드는 이벤트 매니저에 등록시켜야 비로소 동작합니다:

플러그인의 메인 클래스에서 정의한 (Plugin 어노테이션이 붙은) 이벤트 리스너들에 한해서는 Sponge가 자동으로 이벤트 매니저에 리스너를 등록시켜 줍니다.

참고

이벤트 버스는 부모 타입을 지원합니다. 예를 들어, ChangeBlockEvent.BreakChangeBlockEvent를 상속합니다. 따라서 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 어노테이션이 붙은 것도 포함하여 모든 이벤트 리스너를 비활성화시킨다는 점을 명심하십시오.

MyPlugin plugin = ...
Sponge.getEventManager().unregisterPluginListeners(plugin);

@Listener 에 대하여

@Listener 어노테이션에는 몇 가지 필드 옵션이 있습니다:

  • order는 이벤트 리스너가 동작하는 우선순위입니다. 옵션의 종류를 보려면 Order enum을 참고하세요.

  • beforeModifications는 Forge 모드와 같은 다른 서버 모드들 보다 우선적으로 이벤트를 호출받을지 여부를 결정합니다. 기본적으로 false 값을 갖습니다.

Cancellable 인터페이스를 구현하는 이벤트에 한해서 다른 플러그인에 의해 이벤트의 동작이 중단되면, 기본적으로는 @Listener 가 붙은 당신의 이벤트 리스너는 호출되지 않도록 설계되어 있습니다.

GameReloadEvent

플러그인들이 각자의 리로드 커맨드를 제공하는 것을 막기 위해, Sponge는 플러그인이 리로드를 수행할 시기를 알려주는 내장 이벤트를 제공합니다. ‘리로드’의 기능을 어떤 식으로 구성할지는 여러분에게 달렸습니다. 플러그인 설정 파일을 재로드하는 것 만으로 제약을 둘 필요는 없습니다. GameReloadEvent 이벤트는 플레이어가 /sponge plugins reload 커맨드를 실행하면 호출됩니다.

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.SpongeEventFactory;
import org.spongepowered.api.event.action.LightningEvent;
import org.spongepowered.api.event.cause.Cause;

LightningEvent lightningEvent = SpongeEventFactory.createLightningEvent(Cause.source(plugin).build());
Sponge.getEventManager().post(lightningEvent);

경고

매개 변수에 Cause 를 빈 값으로 대입할 수 없습니다. 최소한으로 플러그인 컨테이너는 포함시키세요.