Improve event bus priorities, use method handles

This commit is contained in:
Vankka 2024-12-27 01:53:03 +02:00
parent 05aedf2067
commit bed92a3450
No known key found for this signature in database
GPG Key ID: 62E48025ED4E7EBB
26 changed files with 204 additions and 161 deletions

View File

@ -23,47 +23,19 @@
package com.discordsrv.api.eventbus;
import com.discordsrv.api.events.Processable;
/**
* A simple enum to dictate the order that event listeners will be executed, going from {@link #POST} to {@link #POST}.
*/
public enum EventPriority {
@SuppressWarnings("unused") // "API"
public class EventPriorities {
/**
* This is the first in the priority order, this should be used to observe the event before any processing.
*/
PRE,
/**
* This is the earliest in the processing. This should be used to cancel events.
*/
EARLIEST,
/**
* This should be used to modify events.
*/
EARLY,
/**
* The default priority, right in the middle of the priority order. Use this if you need to override
* one of DiscordSRV's implementations for {@link Processable}s.
*/
DEFAULT,
/**
* This is where DiscordSRV's integrations for other plugins will process {@link Processable}'s.
*/
LATE,
/**
* This is where DiscordSRV's default implementations for {@link Processable}'s will run.
*/
LAST,
/**
* This is the last in the priority order, this should be used to observe the event after all processing is complete.
*/
POST
public static final byte PRE = Byte.MIN_VALUE;
public static final byte EARLIEST = (byte) -96;
public static final byte EARLY = (byte) -48;
public static final byte DEFAULT = (byte) 0;
public static final byte LATE = (byte) 48;
public static final byte LAST = (byte) 96;
public static final byte POST = Byte.MAX_VALUE;
private EventPriorities() {}
}

View File

@ -33,7 +33,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Placed on a public non-abstract non-static method that has only 1 parameters,
* Placed on a public non-abstract non-static method that has only 1 parameter,
* being an event extending {@link Event} or {@link net.dv8tion.jda.api.events.GenericEvent}.
*
* You can register a listener through {@link EventBus#subscribe(Object)}, {@link DiscordSRVApi#eventBus()} to get the event bus.
@ -52,7 +52,8 @@ public @interface Subscribe {
/**
* The priority for this event listener, this determines the order that event listeners receive events.
* @return the priority of this event listener
* @see EventPriorities
*/
EventPriority priority() default EventPriority.DEFAULT;
byte priority() default 0;
}

View File

@ -24,7 +24,7 @@
package com.discordsrv.api.events.channel;
import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.events.Processable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -32,7 +32,7 @@ import org.jetbrains.annotations.Nullable;
/**
* This event is used to lookup {@link GameChannel}s by their name (and optionally plugin name).
* This is also used to determine which plugin's channel should take priority when multiple plugins
* define channels with the same name ({@link EventPriority}).
* define channels with the same name ({@link EventPriorities}).
*
* @see #isDefault()
*/

View File

@ -23,20 +23,20 @@
package com.discordsrv.api.events.lifecycle;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.events.Event;
/**
* Indicates that DiscordSRV is shutting down.
* <p>
* DiscordSRV's own systems will shut down at the following times:
* {@link EventPriority#EARLY}<br/>
* {@link EventPriorities#EARLY}<br/>
* - DiscordSRV's own modules shutdown<br/>
*
* {@link EventPriority#LATE}<br/>
* {@link EventPriorities#LATE}<br/>
* - Discord connections are shutdown<br/>
*
* {@link EventPriority#LAST}<br/>
* {@link EventPriorities#LAST}<br/>
* - DiscordSRV's scheduler is shutdown<br/>
*/
public class DiscordSRVShuttingDownEvent implements Event {

View File

@ -25,7 +25,7 @@ package com.discordsrv.api.events.message.receive.game;
import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.events.PlayerEvent;
import com.discordsrv.api.player.DiscordSRVPlayer;
import org.jetbrains.annotations.NotNull;
@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Indicates that an advancement or achievement message was received will be processed
* at {@link EventPriority#DEFAULT} unless cancelled or processed by a 3rd party.
* at {@link EventPriorities#DEFAULT} unless cancelled or processed by a 3rd party.
*/
public class AwardMessageReceiveEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {

View File

@ -25,7 +25,7 @@ package com.discordsrv.api.events.message.receive.game;
import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.events.PlayerEvent;
import com.discordsrv.api.player.DiscordSRVPlayer;
import org.jetbrains.annotations.NotNull;
@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Indicates that a death message was received and will be processed
* at {@link EventPriority#DEFAULT} unless cancelled or processed by a 3rd party.
* at {@link EventPriorities#DEFAULT} unless cancelled or processed by a 3rd party.
*/
public class DeathMessageReceiveEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {

View File

@ -25,7 +25,7 @@ package com.discordsrv.api.events.message.receive.game;
import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.events.PlayerEvent;
import com.discordsrv.api.player.DiscordSRVPlayer;
import org.jetbrains.annotations.NotNull;
@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Indicates that a chat message was received and will be processed
* at {@link EventPriority#DEFAULT} unless cancelled or processed by a 3rd party.
* at {@link EventPriorities#DEFAULT} unless cancelled or processed by a 3rd party.
*/
public class GameChatMessageReceiveEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {

View File

@ -25,7 +25,7 @@ package com.discordsrv.api.events.message.receive.game;
import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.events.PlayerEvent;
import com.discordsrv.api.player.DiscordSRVPlayer;
import org.jetbrains.annotations.NotNull;
@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Indicates that a join message was received and will be processed
* at {@link EventPriority#DEFAULT} unless cancelled or processed by a 3rd party.
* at {@link EventPriorities#DEFAULT} unless cancelled or processed by a 3rd party.
*/
public class JoinMessageReceiveEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {

View File

@ -25,7 +25,7 @@ package com.discordsrv.api.events.message.receive.game;
import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.events.PlayerEvent;
import com.discordsrv.api.player.DiscordSRVPlayer;
import org.jetbrains.annotations.NotNull;
@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Indicates that a leave message was received and will be processed
* at {@link EventPriority#DEFAULT} unless cancelled or processed by a 3rd party.
* at {@link EventPriorities#DEFAULT} unless cancelled or processed by a 3rd party.
*/
public class LeaveMessageReceiveEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {

View File

@ -24,7 +24,7 @@
package com.discordsrv.api.events.message.receive.game;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.events.PlayerEvent;
import com.discordsrv.api.player.DiscordSRVPlayer;
import org.jetbrains.annotations.NotNull;
@ -32,7 +32,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Indicates that a server switch message was received and will be processed
* at {@link EventPriority#DEFAULT} unless cancelled or processed by a 3rd party.
* at {@link EventPriorities#DEFAULT} unless cancelled or processed by a 3rd party.
*/
public class ServerSwitchMessageReceiveEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {

View File

@ -20,7 +20,7 @@ package com.discordsrv.bukkit.integration;
import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.channel.GameChannelLookupEvent;
import com.discordsrv.api.events.message.receive.game.GameChatMessageReceiveEvent;
@ -149,7 +149,7 @@ public class EssentialsXIntegration
));
}
@Subscribe(priority = EventPriority.LAST)
@Subscribe(priority = EventPriorities.LAST)
public void onGameChannelLookup(GameChannelLookupEvent event) {
if (checkProcessor(event) || !discordSRV.server().getPluginManager().isPluginEnabled("EssentialsChat")) {
return;

View File

@ -18,7 +18,7 @@
package com.discordsrv.bukkit.integration.chat;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.message.receive.game.GameChatMessageReceiveEvent;
import com.discordsrv.api.player.DiscordSRVPlayer;
@ -50,7 +50,7 @@ public class GriefPreventionChatIntegration extends PluginIntegration<BukkitDisc
return super.isEnabled();
}
@Subscribe(priority = EventPriority.EARLY)
@Subscribe(priority = EventPriorities.EARLY)
public void onGameChatMessageReceive(GameChatMessageReceiveEvent event) {
GriefPrevention griefPrevention = (GriefPrevention) discordSRV.server().getPluginManager().getPlugin(
getIntegrationId());

View File

@ -20,7 +20,7 @@ package com.discordsrv.bukkit.integration.chat;
import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.channel.GameChannelLookupEvent;
import com.discordsrv.api.events.message.receive.game.GameChatMessageReceiveEvent;
@ -80,7 +80,7 @@ public class McMMOChatIntegration extends PluginIntegration<BukkitDiscordSRV> im
HandlerList.unregisterAll(this);
}
@Subscribe(priority = EventPriority.EARLY)
@Subscribe(priority = EventPriorities.EARLY)
public void onGameChatMessageReceive(GameChatMessageReceiveEvent event) {
Player player = discordSRV.server().getPlayer(event.getPlayer().uniqueId());
if (!player.hasMetadata("mcMMO: Player Data")) {

View File

@ -20,7 +20,6 @@ package com.discordsrv.common.core.eventbus;
import com.discordsrv.api.eventbus.EventBus;
import com.discordsrv.api.eventbus.EventListener;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.eventbus.internal.EventStateHolder;
import com.discordsrv.api.events.Cancellable;
@ -37,36 +36,40 @@ import net.dv8tion.jda.api.events.GenericEvent;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static com.discordsrv.common.util.ExceptionUtil.minifyException;
public class EventBusImpl implements EventBus {
private static final List<Pair<Function<Object, Boolean>, ThreadLocal<EventListener>>> STATES = Arrays.asList(
Pair.of(event -> event instanceof Cancellable && ((Cancellable) event).isCancelled(), EventStateHolder.CANCELLED),
Pair.of(event -> event instanceof Processable && ((Processable) event).isProcessed(), EventStateHolder.PROCESSED)
private static final List<State<?>> STATES = Arrays.asList(
new State<>(Cancellable.class, Cancellable::isCancelled, EventStateHolder.CANCELLED),
new State<>(Processable.class, Processable::isProcessed, EventStateHolder.PROCESSED)
);
private final Map<Object, List<EventListenerImpl>> listeners = new ConcurrentHashMap<>();
private final List<EventListenerImpl> allListeners = new CopyOnWriteArrayList<>();
private final Map<Class<?>, List<EventListenerImpl>> listenersByEvent = new ConcurrentHashMap<>();
private final Logger logger;
public EventBusImpl(DiscordSRV discordSRV) {
this.logger = new NamedLogger(discordSRV, "EVENT_BUS");
// For debug generation
subscribe(this);
}
public void shutdown() {
listeners.clear();
allListeners.clear();
listenersByEvent.clear();
}
@Override
@ -87,7 +90,10 @@ public class EventBusImpl implements EventBus {
}
listeners.put(eventListener, methods);
allListeners.addAll(methods);
for (EventListenerImpl method : methods) {
listenersByEvent.computeIfAbsent(method.eventClass(), key -> new CopyOnWriteArrayList<>())
.add(method);
}
logger.debug("Listener " + eventListener.getClass().getName() + " subscribed");
}
@ -123,7 +129,8 @@ public class EventBusImpl implements EventBus {
int parameters = parameterTypes.length;
List<Throwable> suppressed = new ArrayList<>();
if (Void.class.isAssignableFrom(method.getReturnType())) {
Class<?> returnType = method.getReturnType();
if (Void.class.isAssignableFrom(returnType)) {
suppressed.add(createReasonException("Must return void"));
}
@ -149,6 +156,14 @@ public class EventBusImpl implements EventBus {
}
}
MethodHandle handle = null;
MethodType methodType = MethodType.methodType(method.getReturnType(), method.getParameterTypes());
try {
handle = MethodHandles.lookup().findVirtual(listenerClass, method.getName(), methodType);
} catch (ReflectiveOperationException e) {
suppressedMethods.add(e);
}
if (!suppressed.isEmpty()) {
Exception methodException = new InvalidListenerMethodException("Method " + method.getName() + "(" +
(parameters > 0 ? Arrays.stream(method.getParameterTypes())
@ -159,7 +174,7 @@ public class EventBusImpl implements EventBus {
return;
}
EventListenerImpl listener = new EventListenerImpl(eventListener, listenerClass, annotation, firstParameter, method);
EventListenerImpl listener = new EventListenerImpl(eventListener, listenerClass, annotation, firstParameter, method, handle);
methods.add(listener);
}
@ -172,7 +187,14 @@ public class EventBusImpl implements EventBus {
public void unsubscribe(@NotNull Object eventListener) {
List<EventListenerImpl> removed = listeners.remove(eventListener);
if (removed != null) {
allListeners.removeAll(removed);
for (EventListenerImpl listener : removed) {
Class<?> eventClass = listener.eventClass();
List<EventListenerImpl> listeners = listenersByEvent.get(eventClass);
listeners.remove(listener);
if (listeners.isEmpty()) {
listenersByEvent.remove(eventClass);
}
}
logger.debug("Listener " + eventListener.getClass().getName() + " unsubscribed");
}
}
@ -187,86 +209,102 @@ public class EventBusImpl implements EventBus {
publishEvent(event);
}
private void gatherListeners(Class<?> eventClass, List<EventListenerImpl> listeners) {
List<EventListenerImpl> listenersForEvent = this.listenersByEvent.get(eventClass);
if (listenersForEvent == null) {
return;
}
listeners.addAll(listenersForEvent);
}
private void publishEvent(Object event) {
List<Boolean> states = new ArrayList<>(STATES.size());
for (Pair<Function<Object, Boolean>, ThreadLocal<EventListener>> entry : STATES) {
if (entry.getKey().apply(event)) {
// If the state is already set before listeners, we mark it as being changed by a 'unknown' event listener
states.add(true);
entry.getValue().set(EventStateHolder.UNKNOWN_LISTENER);
continue;
Class<?> eventClass = event.getClass();
Map<State<?>, Boolean> states = new HashMap<>(STATES.size());
for (State<?> state : STATES) {
if (state.eventClass().isAssignableFrom(eventClass)) {
boolean value = state.statePredicate().test(event);
states.put(state, value);
if (value) {
state.stateHolder().set(EventStateHolder.UNKNOWN_LISTENER);
}
}
states.add(false);
}
Class<?> eventClass = event.getClass();
for (EventPriority priority : EventPriority.values()) {
for (EventListenerImpl eventListener : allListeners) {
if (eventListener.isIgnoringCancelled() && event instanceof Cancellable && ((Cancellable) event).isCancelled()) {
continue;
List<EventListenerImpl> listeners = new ArrayList<>();
while (!Object.class.equals(eventClass)) {
gatherListeners(eventClass, listeners);
for (Class<?> anInterface : eventClass.getInterfaces()) {
gatherListeners(anInterface, listeners);
}
eventClass = eventClass.getSuperclass();
}
listeners.sort(Comparator.comparingInt(EventListenerImpl::priority));
for (EventListenerImpl eventListener : listeners) {
if (eventListener.isIgnoringCancelled() && event instanceof Cancellable && ((Cancellable) event).isCancelled()) {
continue;
}
long startTime = System.currentTimeMillis();
try {
Object listener = eventListener.listener();
eventListener.handle().invoke(listener, event);
} catch (Throwable e) {
String eventClassName = eventClass.getName();
if (eventListener.className().startsWith("com.discordsrv")) {
logger.error("Failed to pass " + eventClassName + " to " + eventListener, e);
} else {
// Print the listener failing without references to the DiscordSRV event bus
// as it isn't relevant to the exception, and often causes users to suspect DiscordSRV is doing something wrong when it isn't
//noinspection CallToPrintStackTrace
e.printStackTrace();
}
if (eventListener.priority() != priority) {
continue;
}
if (!eventListener.eventClass().isAssignableFrom(eventClass)) {
TestHelper.fail(e);
}
long timeTaken = System.currentTimeMillis() - startTime;
logger.trace(eventListener + " took " + timeTaken + "ms to execute");
for (Map.Entry<State<?>, Boolean> entry : states.entrySet()) {
State<?> state = entry.getKey();
boolean currentValue = entry.getValue();
boolean newValue = state.statePredicate().test(event);
if (currentValue == newValue) {
continue;
}
long startTime = System.currentTimeMillis();
try {
Object listener = eventListener.listener();
eventListener.method().invoke(listener, event);
} catch (IllegalAccessException e) {
logger.error("Failed to access listener method: " + eventListener.methodName() + " in " + eventListener.className(), e);
TestHelper.fail(e);
} catch (InvocationTargetException e) {
String eventClassName = eventClass.getName();
Throwable cause = e.getCause();
if (eventListener.className().startsWith("com.discordsrv")) {
logger.error("Failed to pass " + eventClassName + " to " + eventListener, cause);
} else {
// Print the listener failing without references to the DiscordSRV event bus
// as it isn't relevant to the exception, and often causes users to suspect DiscordSRV is doing something wrong when it isn't
//noinspection CallToPrintStackTrace
e.getCause().printStackTrace();
}
TestHelper.fail(cause);
}
long timeTaken = System.currentTimeMillis() - startTime;
logger.trace(eventListener + " took " + timeTaken + "ms to execute");
for (int index = 0; index < STATES.size(); index++) {
Pair<Function<Object, Boolean>, ThreadLocal<EventListener>> state = STATES.get(index);
boolean current = states.get(index);
boolean updated = state.getKey().apply(event);
states.set(index, updated);
ThreadLocal<EventListener> stateHolder = state.getValue();
if (current != updated) {
if (updated) {
stateHolder.set(eventListener);
} else {
stateHolder.remove();
}
}
if (currentValue) {
state.stateHolder().set(eventListener);
} else {
state.stateHolder().set(EventStateHolder.UNKNOWN_LISTENER);
}
}
}
// Clear the states
for (Pair<Function<Object, Boolean>, ThreadLocal<EventListener>> state : STATES) {
state.getValue().remove();
for (State<?> state : states.keySet()) {
state.stateHolder().remove();
}
}
@Subscribe
public void onDebugGenerate(DebugGenerateEvent event) {
StringBuilder builder = new StringBuilder("Registered listeners (" + listeners.size() + "/" + allListeners.size() + "):\n");
StringBuilder builder = new StringBuilder("Registered listeners\n");
builder.append(" (").append(listeners.size()).append(" listeners classes)\n");
builder.append(" (for ").append(listenersByEvent.size()).append(" events)\n");
builder.append(" (for a total of ")
.append(listeners.values().stream().mapToInt(List::size).sum())
.append(" individual listeners methods)\n");
for (Map.Entry<Object, List<EventListenerImpl>> entry : listeners.entrySet()) {
Object listener = entry.getKey();
List<EventListenerImpl> eventListeners = entry.getValue();
eventListeners.sort(Comparator.comparingInt(EventListenerImpl::priority));
builder.append('\n')
.append(listener)
.append(" (")
@ -280,11 +318,37 @@ public class EventBusImpl implements EventBus {
.append(": ")
.append(eventListener.methodName())
.append(" @ ")
.append(eventListener.priority().name())
.append(eventListener.priority())
.append('\n');
}
}
event.addFile(new TextDebugFile("event-bus.txt", builder));
}
private static class State<T> {
private final Class<T> eventClass;
private final Predicate<Object> statePredicate;
private final ThreadLocal<EventListener> stateHolder;
@SuppressWarnings("unchecked") // Converting generic to Object is easier down the line
public State(Class<T> eventClass, Predicate<T> statePredicate, ThreadLocal<EventListener> stateHolder) {
this.eventClass = eventClass;
this.statePredicate = (Predicate<Object>) statePredicate;
this.stateHolder = stateHolder;
}
public Class<T> eventClass() {
return eventClass;
}
public Predicate<Object> statePredicate() {
return statePredicate;
}
public ThreadLocal<EventListener> stateHolder() {
return stateHolder;
}
}
}

View File

@ -19,10 +19,10 @@
package com.discordsrv.common.core.eventbus;
import com.discordsrv.api.eventbus.EventListener;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.Subscribe;
import org.jetbrains.annotations.NotNull;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Method;
public class EventListenerImpl implements EventListener {
@ -32,20 +32,22 @@ public class EventListenerImpl implements EventListener {
private final Subscribe annotation;
private final Class<?> eventClass;
private final Method method;
private final MethodHandle handle;
public EventListenerImpl(Object listener, Class<?> listenerClass, Subscribe annotation, Class<?> eventClass, Method method) {
public EventListenerImpl(Object listener, Class<?> listenerClass, Subscribe annotation, Class<?> eventClass, Method method, MethodHandle handle) {
this.listener = listener;
this.listenerClass = listenerClass;
this.annotation = annotation;
this.eventClass = eventClass;
this.method = method;
this.handle = handle;
}
public boolean isIgnoringCancelled() {
return annotation.ignoreCancelled();
}
public EventPriority priority() {
public byte priority() {
return annotation.priority();
}
@ -72,6 +74,10 @@ public class EventListenerImpl implements EventListener {
return method.getName();
}
public MethodHandle handle() {
return handle;
}
@Override
public String toString() {
return "EventListenerImpl{" + className() + "#" + methodName() + "}";

View File

@ -21,7 +21,7 @@ package com.discordsrv.common.core.module;
import com.discordsrv.api.discord.connection.details.DiscordCacheFlag;
import com.discordsrv.api.discord.connection.details.DiscordGatewayIntent;
import com.discordsrv.api.discord.connection.details.DiscordMemberCachePolicy;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.lifecycle.DiscordSRVReadyEvent;
import com.discordsrv.api.events.lifecycle.DiscordSRVShuttingDownEvent;
@ -200,7 +200,7 @@ public class ModuleManager {
}
}
@Subscribe(priority = EventPriority.EARLY)
@Subscribe(priority = EventPriorities.EARLY)
public void onShuttingDown(DiscordSRVShuttingDownEvent event) {
modules.stream()
.sorted((m1, m2) -> Integer.compare(m2.shutdownOrder(), m1.shutdownOrder()))

View File

@ -18,7 +18,7 @@
package com.discordsrv.common.core.scheduler;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.lifecycle.DiscordSRVShuttingDownEvent;
import com.discordsrv.common.DiscordSRV;
@ -82,7 +82,7 @@ public class StandardScheduler implements Scheduler {
this.forkJoinPool = forkJoinPool;
}
@Subscribe(priority = EventPriority.LAST)
@Subscribe(priority = EventPriorities.LAST)
public void onShuttingDown(DiscordSRVShuttingDownEvent event) {
executorService.shutdownNow();
scheduledExecutorService.shutdownNow();

View File

@ -25,7 +25,7 @@ import com.discordsrv.api.discord.connection.details.DiscordMemberCachePolicy;
import com.discordsrv.api.discord.connection.jda.errorresponse.ErrorCallbackContext;
import com.discordsrv.api.discord.entity.DiscordUser;
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.lifecycle.DiscordSRVShuttingDownEvent;
import com.discordsrv.api.events.placeholder.PlaceholderLookupEvent;
@ -221,7 +221,7 @@ public class JDAConnectionManager implements DiscordConnectionManager {
event.addFile(new TextDebugFile("jda_connection_manager.txt", builder));
}
@Subscribe(priority = EventPriority.EARLIEST)
@Subscribe(priority = EventPriorities.EARLIEST)
public void onPlaceholderLookup(PlaceholderLookupEvent event) {
if (event.isProcessed()) {
return;
@ -433,7 +433,7 @@ public class JDAConnectionManager implements DiscordConnectionManager {
}
}
@Subscribe(priority = EventPriority.LATE)
@Subscribe(priority = EventPriorities.LATE)
public void onDSRVShuttingDown(DiscordSRVShuttingDownEvent event) {
shutdown(DEFAULT_SHUTDOWN_TIMEOUT);
}

View File

@ -18,7 +18,7 @@
package com.discordsrv.common.feature;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.lifecycle.DiscordSRVShuttingDownEvent;
import com.discordsrv.api.reload.ReloadResult;
@ -56,7 +56,7 @@ public class PresenceUpdaterModule extends AbstractModule<DiscordSRV> {
setPresenceOrSchedule();
}
@Subscribe(priority = EventPriority.EARLIEST)
@Subscribe(priority = EventPriorities.EARLIEST)
public void onDiscordSRVShuttingDown(DiscordSRVShuttingDownEvent event) {
serverState.set(ServerState.STOPPING);
setPresenceOrSchedule();

View File

@ -18,7 +18,7 @@
package com.discordsrv.common.feature.channel.global;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.channel.GameChannelLookupEvent;
import com.discordsrv.common.DiscordSRV;
@ -30,7 +30,7 @@ public class GlobalChannelLookupModule extends AbstractModule<DiscordSRV> {
super(discordSRV);
}
@Subscribe(priority = EventPriority.LATE)
@Subscribe(priority = EventPriorities.LATE)
public void onGameChannelLookup(GameChannelLookupEvent event) {
if (event.getChannelName().equalsIgnoreCase("global")) {
if (checkProcessor(event)) {

View File

@ -22,7 +22,7 @@ import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessageCluster;
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.message.forward.game.AwardMessageForwardedEvent;
import com.discordsrv.api.events.message.receive.game.AwardMessageReceiveEvent;
@ -65,7 +65,7 @@ public class AwardMessageModule extends AbstractGameMessageModule<AwardMessageCo
return permit;
}
@Subscribe(priority = EventPriority.LAST)
@Subscribe(priority = EventPriorities.LAST)
public void onAwardMessageReceive(AwardMessageReceiveEvent event) {
if (checkCancellation(event) || checkProcessor(event)) {
return;

View File

@ -22,7 +22,7 @@ import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessageCluster;
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.message.forward.game.DeathMessageForwardedEvent;
import com.discordsrv.api.events.message.receive.game.DeathMessageReceiveEvent;
@ -39,7 +39,7 @@ public class DeathMessageModule extends AbstractGameMessageModule<DeathMessageCo
super(discordSRV, "DEATH_MESSAGES");
}
@Subscribe(priority = EventPriority.LAST)
@Subscribe(priority = EventPriorities.LAST)
public void onDeathMessageReceive(DeathMessageReceiveEvent event) {
if (checkCancellation(event) || checkProcessor(event)) {
return;

View File

@ -22,7 +22,7 @@ import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessageCluster;
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.message.forward.game.JoinMessageForwardedEvent;
import com.discordsrv.api.events.message.receive.game.JoinMessageReceiveEvent;
@ -52,7 +52,7 @@ public class JoinMessageModule extends AbstractGameMessageModule<IMessageConfig,
super(discordSRV, "JOIN_MESSAGES");
}
@Subscribe(priority = EventPriority.LAST)
@Subscribe(priority = EventPriorities.LAST)
public void onJoinMessageReceive(JoinMessageReceiveEvent event) {
if (checkCancellation(event) || checkProcessor(event)) {
return;

View File

@ -22,7 +22,7 @@ import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessageCluster;
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.message.forward.game.LeaveMessageForwardedEvent;
import com.discordsrv.api.events.message.receive.game.LeaveMessageReceiveEvent;
@ -75,7 +75,7 @@ public class LeaveMessageModule extends AbstractGameMessageModule<LeaveMessageCo
}
}
@Subscribe(priority = EventPriority.LAST)
@Subscribe(priority = EventPriorities.LAST)
public void onLeaveMessageReceive(LeaveMessageReceiveEvent event) {
if (checkCancellation(event) || checkProcessor(event)) {
return;

View File

@ -25,7 +25,7 @@ import com.discordsrv.api.discord.entity.message.AllowedMention;
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessage;
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessageCluster;
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.message.forward.game.GameChatMessageForwardedEvent;
import com.discordsrv.api.events.message.receive.game.GameChatMessageReceiveEvent;
@ -54,7 +54,7 @@ public class MinecraftToDiscordChatModule extends AbstractGameMessageModule<Mine
super(discordSRV, "MINECRAFT_TO_DISCORD");
}
@Subscribe(priority = EventPriority.LAST)
@Subscribe(priority = EventPriorities.LAST)
public void onChatReceive(GameChatMessageReceiveEvent event) {
if (checkProcessor(event) || checkCancellation(event) || !discordSRV.isReady()) {
return;

View File

@ -22,7 +22,7 @@ import com.discordsrv.api.channel.GameChannel;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessageCluster;
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
import com.discordsrv.api.eventbus.EventPriority;
import com.discordsrv.api.eventbus.EventPriorities;
import com.discordsrv.api.eventbus.Subscribe;
import com.discordsrv.api.events.message.forward.game.ServerSwitchMessageForwardedEvent;
import com.discordsrv.api.events.message.receive.game.ServerSwitchMessageReceiveEvent;
@ -40,7 +40,7 @@ public class ServerSwitchMessageModule extends AbstractGameMessageModule<ServerS
super(discordSRV, "SERVER_SWITCH_MESSAGES");
}
@Subscribe(priority = EventPriority.LAST)
@Subscribe(priority = EventPriorities.LAST)
public void onServerSwitchMessageReceive(ServerSwitchMessageReceiveEvent event) {
if (checkCancellation(event) || checkProcessor(event)) {
return;