mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-12-28 17:37:52 +01:00
Make the EventBus faster by avoiding Map#entrySet
This commit is contained in:
parent
9662d9515f
commit
9cfaae7464
@ -53,6 +53,7 @@ public class EventBusImpl implements EventBus {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private final Map<Object, List<EventListenerImpl>> listeners = new ConcurrentHashMap<>();
|
private final Map<Object, List<EventListenerImpl>> listeners = new ConcurrentHashMap<>();
|
||||||
|
private final List<EventListenerImpl> allListeners = new CopyOnWriteArrayList<>();
|
||||||
private final DiscordSRV discordSRV;
|
private final DiscordSRV discordSRV;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ public class EventBusImpl implements EventBus {
|
|||||||
Class<?> currentClass = listenerClass;
|
Class<?> currentClass = listenerClass;
|
||||||
do {
|
do {
|
||||||
for (Method method : currentClass.getDeclaredMethods()) {
|
for (Method method : currentClass.getDeclaredMethods()) {
|
||||||
checkMethod(listenerClass, method, suppressedMethods, methods, methodsByPriority);
|
checkMethod(eventListener, listenerClass, method, suppressedMethods, methods, methodsByPriority);
|
||||||
}
|
}
|
||||||
} while ((currentClass = currentClass.getSuperclass()) != null);
|
} while ((currentClass = currentClass.getSuperclass()) != null);
|
||||||
|
|
||||||
@ -88,10 +89,11 @@ public class EventBusImpl implements EventBus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
listeners.put(eventListener, methods);
|
listeners.put(eventListener, methods);
|
||||||
|
allListeners.addAll(methods);
|
||||||
logger.debug("Listener " + eventListener.getClass().getName() + " subscribed");
|
logger.debug("Listener " + eventListener.getClass().getName() + " subscribed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMethod(Class<?> listenerClass, Method method,
|
private void checkMethod(Object eventListener, Class<?> listenerClass, Method method,
|
||||||
List<Throwable> suppressedMethods, List<EventListenerImpl> methods,
|
List<Throwable> suppressedMethods, List<EventListenerImpl> methods,
|
||||||
EnumMap<EventPriority, List<EventListenerImpl>> methodsByPriority) {
|
EnumMap<EventPriority, List<EventListenerImpl>> methodsByPriority) {
|
||||||
Subscribe annotation = method.getAnnotation(Subscribe.class);
|
Subscribe annotation = method.getAnnotation(Subscribe.class);
|
||||||
@ -140,7 +142,7 @@ public class EventBusImpl implements EventBus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EventPriority eventPriority = annotation.priority();
|
EventPriority eventPriority = annotation.priority();
|
||||||
EventListenerImpl listener = new EventListenerImpl(listenerClass, annotation, firstParameter, method);
|
EventListenerImpl listener = new EventListenerImpl(eventListener, listenerClass, annotation, firstParameter, method);
|
||||||
|
|
||||||
methods.add(listener);
|
methods.add(listener);
|
||||||
methodsByPriority.computeIfAbsent(eventPriority, key -> new CopyOnWriteArrayList<>())
|
methodsByPriority.computeIfAbsent(eventPriority, key -> new CopyOnWriteArrayList<>())
|
||||||
@ -154,8 +156,11 @@ public class EventBusImpl implements EventBus {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unsubscribe(@NotNull Object eventListener) {
|
public void unsubscribe(@NotNull Object eventListener) {
|
||||||
listeners.remove(eventListener);
|
List<EventListenerImpl> removed = listeners.remove(eventListener);
|
||||||
logger.debug("Listener " + eventListener.getClass().getName() + " unsubscribed");
|
if (removed != null) {
|
||||||
|
allListeners.removeAll(removed);
|
||||||
|
logger.debug("Listener " + eventListener.getClass().getName() + " unsubscribed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -182,44 +187,42 @@ public class EventBusImpl implements EventBus {
|
|||||||
|
|
||||||
Class<?> eventClass = event.getClass();
|
Class<?> eventClass = event.getClass();
|
||||||
for (EventPriority priority : EventPriority.values()) {
|
for (EventPriority priority : EventPriority.values()) {
|
||||||
for (Map.Entry<Object, List<EventListenerImpl>> entry : listeners.entrySet()) {
|
for (EventListenerImpl eventListener : allListeners) {
|
||||||
Object listener = entry.getKey();
|
if (eventListener.isIgnoringCancelled() && event instanceof Cancellable && ((Cancellable) event).isCancelled()) {
|
||||||
for (EventListenerImpl eventListener : entry.getValue()) {
|
continue;
|
||||||
if (eventListener.isIgnoringCancelled() && event instanceof Cancellable && ((Cancellable) event).isCancelled()) {
|
}
|
||||||
continue;
|
if (eventListener.priority() != priority) {
|
||||||
}
|
continue;
|
||||||
if (eventListener.priority() != priority) {
|
}
|
||||||
continue;
|
if (!eventListener.eventClass().isAssignableFrom(eventClass)) {
|
||||||
}
|
continue;
|
||||||
if (!eventListener.eventClass().isAssignableFrom(eventClass)) {
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
eventListener.method().invoke(listener, event);
|
Object listener = eventListener.listener();
|
||||||
} catch (IllegalAccessException e) {
|
eventListener.method().invoke(listener, event);
|
||||||
discordSRV.logger().error("Failed to access listener method: " + eventListener.methodName(), e);
|
} catch (IllegalAccessException e) {
|
||||||
} catch (InvocationTargetException e) {
|
discordSRV.logger().error("Failed to access listener method: " + eventListener.methodName(), e);
|
||||||
discordSRV.logger().error("Failed to pass " + event.getClass().getSimpleName() + " to " + eventListener, e.getCause());
|
} catch (InvocationTargetException e) {
|
||||||
}
|
discordSRV.logger().error("Failed to pass " + event.getClass().getSimpleName() + " to " + eventListener, e.getCause());
|
||||||
long timeTaken = System.currentTimeMillis() - startTime;
|
}
|
||||||
logger.trace(eventListener + " took " + timeTaken + "ms to execute");
|
long timeTaken = System.currentTimeMillis() - startTime;
|
||||||
|
logger.trace(eventListener + " took " + timeTaken + "ms to execute");
|
||||||
|
|
||||||
for (int index = 0; index < STATES.size(); index++) {
|
for (int index = 0; index < STATES.size(); index++) {
|
||||||
Pair<Function<Object, Boolean>, ThreadLocal<EventListener>> state = STATES.get(index);
|
Pair<Function<Object, Boolean>, ThreadLocal<EventListener>> state = STATES.get(index);
|
||||||
|
|
||||||
boolean current = states.get(index);
|
boolean current = states.get(index);
|
||||||
boolean updated = state.getKey().apply(event);
|
boolean updated = state.getKey().apply(event);
|
||||||
states.set(index, updated);
|
states.set(index, updated);
|
||||||
|
|
||||||
ThreadLocal<EventListener> stateHolder = state.getValue();
|
ThreadLocal<EventListener> stateHolder = state.getValue();
|
||||||
if (current != updated) {
|
if (current != updated) {
|
||||||
if (updated) {
|
if (updated) {
|
||||||
stateHolder.set(eventListener);
|
stateHolder.set(eventListener);
|
||||||
} else {
|
} else {
|
||||||
stateHolder.remove();
|
stateHolder.remove();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,14 @@ import java.lang.reflect.Method;
|
|||||||
|
|
||||||
public class EventListenerImpl implements EventListener {
|
public class EventListenerImpl implements EventListener {
|
||||||
|
|
||||||
|
private final Object listener;
|
||||||
private final Class<?> listenerClass;
|
private final Class<?> listenerClass;
|
||||||
private final Subscribe annotation;
|
private final Subscribe annotation;
|
||||||
private final Class<?> eventClass;
|
private final Class<?> eventClass;
|
||||||
private final Method method;
|
private final Method method;
|
||||||
|
|
||||||
public EventListenerImpl(Class<?> listenerClass, Subscribe annotation, Class<?> eventClass, Method method) {
|
public EventListenerImpl(Object listener, Class<?> listenerClass, Subscribe annotation, Class<?> eventClass, Method method) {
|
||||||
|
this.listener = listener;
|
||||||
this.listenerClass = listenerClass;
|
this.listenerClass = listenerClass;
|
||||||
this.annotation = annotation;
|
this.annotation = annotation;
|
||||||
this.eventClass = eventClass;
|
this.eventClass = eventClass;
|
||||||
@ -47,6 +49,10 @@ public class EventListenerImpl implements EventListener {
|
|||||||
return annotation.priority();
|
return annotation.priority();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object listener() {
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
|
|
||||||
public Class<?> eventClass() {
|
public Class<?> eventClass() {
|
||||||
return eventClass;
|
return eventClass;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user