mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Implement annotation based registration for EventManager
The EventManager will now allow classes to be registered and all methods of the class annotated with @Event will be added as event handlers. PluginManager provides a proxy to some of the registration functions in EventManager to allow it to track EventHandlers that belong to a plugin.
This commit is contained in:
parent
ef20c0fa3a
commit
14564dde5d
3 changed files with 88 additions and 49 deletions
|
@ -29,10 +29,15 @@ package org.geysermc.connector.event;
|
|||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.event.annotations.Event;
|
||||
import org.geysermc.connector.event.events.CancellableGeyserEvent;
|
||||
import org.geysermc.connector.event.events.GeyserEvent;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
|
@ -40,6 +45,7 @@ import java.util.PriorityQueue;
|
|||
@AllArgsConstructor
|
||||
public class EventManager {
|
||||
private final Map<Class<? extends GeyserEvent>, PriorityQueue<EventHandler<? extends GeyserEvent>>> eventHandlers = new HashMap<>();
|
||||
private final Map<Object, ArrayList<EventHandler<?>>> classEventHandlers = new HashMap<>();
|
||||
|
||||
private final GeyserConnector connector;
|
||||
|
||||
|
@ -125,6 +131,59 @@ public class EventManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all Events contained in an instantiated class. The methods must be annotated by @Event
|
||||
*/
|
||||
public EventHandler<?>[] registerEvents(Object obj) {
|
||||
List<EventHandler<?>> handlers = new ArrayList<>();
|
||||
for (Method method : obj.getClass().getMethods()) {
|
||||
Event eventAnnotation = method.getAnnotation(Event.class);
|
||||
|
||||
// Check that the method is annotated with @Event
|
||||
if (eventAnnotation == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure it only has a single Event parameter
|
||||
if (method.getParameterCount() != 2 || !GeyserEvent.class.isAssignableFrom(method.getParameters()[1].getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
EventHandler<?> handler = on((Class<? extends GeyserEvent>)method.getParameters()[1].getType(), (ctx, event) -> {
|
||||
try {
|
||||
method.invoke(obj, ctx, event);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, eventAnnotation.priority(), eventAnnotation.ignoreCancelled());
|
||||
|
||||
if (!classEventHandlers.containsKey(obj.getClass())) {
|
||||
classEventHandlers.put(obj, new ArrayList<>());
|
||||
}
|
||||
|
||||
classEventHandlers.get(obj).add(handler);
|
||||
handlers.add(handler);
|
||||
}
|
||||
|
||||
return handlers.toArray(new EventHandler[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all events in class
|
||||
*/
|
||||
public void unregisterEvents(Object obj) {
|
||||
if (!classEventHandlers.containsKey(obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (EventHandler<?> handler : classEventHandlers.get(obj)) {
|
||||
unregister(handler);
|
||||
}
|
||||
|
||||
classEventHandlers.remove(obj);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static class Context implements EventContext {
|
||||
private final EventManager manager;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.geysermc.connector.plugin.annotations;
|
||||
package org.geysermc.connector.event.annotations;
|
||||
|
||||
import org.geysermc.connector.event.EventHandler;
|
||||
|
|
@ -30,13 +30,10 @@ import lombok.AllArgsConstructor;
|
|||
import lombok.Getter;
|
||||
import org.geysermc.connector.event.EventHandler;
|
||||
import org.geysermc.connector.event.events.GeyserEvent;
|
||||
import org.geysermc.connector.plugin.annotations.Event;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* All GeyserPlugins extend from this
|
||||
|
@ -44,67 +41,50 @@ import java.util.Map;
|
|||
@Getter
|
||||
@AllArgsConstructor
|
||||
public abstract class GeyserPlugin {
|
||||
private final Map<Object, ArrayList<EventHandler<?>>> classEventHandlers = new HashMap<>();
|
||||
// List of EventHandlers associated with this Plugin
|
||||
private final List<EventHandler<?>> pluginEventHandlers = new ArrayList<>();
|
||||
|
||||
private final PluginManager pluginManager;
|
||||
private final PluginClassLoader pluginClassLoader;
|
||||
|
||||
// We provide some methods already provided in EventManager as we want to keep track of which EventHandlers
|
||||
// belong to a particular plugin. That way we can unregister them all easily.
|
||||
|
||||
/**
|
||||
* Register all Events contained in a class
|
||||
* Create a new EventHandler using an Executor
|
||||
*/
|
||||
public void registerEvents(Object obj) {
|
||||
for (Method method : obj.getClass().getMethods()) {
|
||||
Event eventAnnotation = method.getAnnotation(Event.class);
|
||||
public <T extends GeyserEvent> EventHandler<T> on(Class<? extends T> cls, EventHandler.Executor<T> executor, int priority, boolean ignoreCancelled) {
|
||||
EventHandler<T> handler = pluginManager.getConnector().getEventManager().on(cls, executor, priority, ignoreCancelled);
|
||||
pluginEventHandlers.add(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
// Check that the method is annotated with @Event
|
||||
if (eventAnnotation == null) {
|
||||
continue;
|
||||
}
|
||||
public <T extends GeyserEvent> EventHandler<T> on(Class<? extends T> cls, EventHandler.Executor<T> executor) {
|
||||
return on(cls, executor, EventHandler.PRIORITY.NORMAL, true);
|
||||
}
|
||||
|
||||
// Make sure it only has a single Event parameter
|
||||
if (method.getParameterCount() != 2 || !GeyserEvent.class.isAssignableFrom(method.getParameters()[1].getType())) {
|
||||
continue;
|
||||
}
|
||||
public <T extends GeyserEvent> EventHandler<T> on(Class<? extends T> cls, EventHandler.Executor<T> executor, boolean ignoreCancelled) {
|
||||
return on(cls, executor, EventHandler.PRIORITY.NORMAL, ignoreCancelled);
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
EventHandler<?> handler = pluginManager.getConnector().getEventManager()
|
||||
.on((Class<? extends GeyserEvent>)method.getParameters()[1].getType(), (ctx, event) -> {
|
||||
try {
|
||||
method.invoke(obj, ctx, event);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
if (!classEventHandlers.containsKey(obj.getClass())) {
|
||||
classEventHandlers.put(obj, new ArrayList<>());
|
||||
}
|
||||
|
||||
classEventHandlers.get(obj).add(handler);
|
||||
}
|
||||
public <T extends GeyserEvent> EventHandler<T> on(Class<? extends T> cls, EventHandler.Executor<T> executor, int priority) {
|
||||
return on(cls, executor, priority, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister events in class
|
||||
* Register all Events contained in an instantiated class. The methods must be annotated by @Event
|
||||
*/
|
||||
public void unregisterEvents(Object obj) {
|
||||
if (!classEventHandlers.containsKey(obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (EventHandler<?> handler : classEventHandlers.get(obj)) {
|
||||
pluginManager.getConnector().getEventManager().unregister(handler);
|
||||
}
|
||||
|
||||
classEventHandlers.remove(obj);
|
||||
public void registerEvents(Object obj) {
|
||||
EventHandler<?>[] handlers = pluginManager.getConnector().getEventManager().registerEvents(obj);
|
||||
pluginEventHandlers.addAll(Arrays.asList(handlers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all events for a plugin
|
||||
*/
|
||||
public void unregisterPluginEvents(Class<?> plugin) {
|
||||
for (Object obj : classEventHandlers.keySet()) {
|
||||
unregisterEvents(obj);
|
||||
public void unregisterAllEvents() {
|
||||
for (EventHandler<?> handler : pluginEventHandlers) {
|
||||
pluginManager.getConnector().getEventManager().unregister(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue