diff --git a/src/main/java/dev/xatuos/chatrobo/api/commands/ICommandManager.java b/src/main/java/dev/xatuos/chatrobo/api/commands/ICommandManager.java index 5490b07..3205401 100644 --- a/src/main/java/dev/xatuos/chatrobo/api/commands/ICommandManager.java +++ b/src/main/java/dev/xatuos/chatrobo/api/commands/ICommandManager.java @@ -7,6 +7,4 @@ default int performPrefixedCommand(S source, String string) { string = string.startsWith("/") ? string.substring(1) : string; return this.performCommand(source, string); } - - } diff --git a/src/main/java/dev/xatuos/chatrobo/api/events/IEvent.java b/src/main/java/dev/xatuos/chatrobo/api/events/Event.java similarity index 58% rename from src/main/java/dev/xatuos/chatrobo/api/events/IEvent.java rename to src/main/java/dev/xatuos/chatrobo/api/events/Event.java index 2f162e9..8f8da37 100644 --- a/src/main/java/dev/xatuos/chatrobo/api/events/IEvent.java +++ b/src/main/java/dev/xatuos/chatrobo/api/events/Event.java @@ -1,4 +1,4 @@ package dev.xatuos.chatrobo.api.events; -public interface IEvent { +public abstract class Event { } diff --git a/src/main/java/dev/xatuos/chatrobo/api/events/IEventBus.java b/src/main/java/dev/xatuos/chatrobo/api/events/IEventBus.java index b41b7bf..7caf82d 100644 --- a/src/main/java/dev/xatuos/chatrobo/api/events/IEventBus.java +++ b/src/main/java/dev/xatuos/chatrobo/api/events/IEventBus.java @@ -1,4 +1,34 @@ package dev.xatuos.chatrobo.api.events; +import org.jetbrains.annotations.NotNull; + public interface IEventBus { + /** + * 注册事件监听器 + * + * @param namespace 命名空间 + * @param event 事件类型 + * @param listener 事件监听器 + */ + void register(@NotNull String namespace, @NotNull Class event, @NotNull IEventListener listener); + + /** + * 注册事件监听器 + * + * @param namespace 命名空间 + * @param listener 事件监听器 + */ + void register(@NotNull String namespace, @NotNull Object listener); + + /** + * 发布事件 + * + * @param event 事件 + */ + void call(@NotNull Event event); + + @FunctionalInterface + interface IEventListener { + void call(Event event); + } } diff --git a/src/main/java/dev/xatuos/chatrobo/impl/events/EventBus.java b/src/main/java/dev/xatuos/chatrobo/impl/events/EventBus.java new file mode 100644 index 0000000..ba1317c --- /dev/null +++ b/src/main/java/dev/xatuos/chatrobo/impl/events/EventBus.java @@ -0,0 +1,62 @@ +package dev.xatuos.chatrobo.impl.events; + +import dev.xatuos.chatrobo.ChatRobo; +import dev.xatuos.chatrobo.api.events.Event; +import dev.xatuos.chatrobo.api.events.IEventBus; +import dev.xatuos.chatrobo.api.events.SubscribeEvent; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; + +public class EventBus implements IEventBus { + private final Map, Map>> listeners; + + public EventBus() { + this.listeners = new ConcurrentHashMap<>(); + } + + @Override + public void register(@NotNull String namespace, @NotNull Class event, @NotNull IEventListener listener) { + Map> listeners = this.listeners.getOrDefault(event, new ConcurrentHashMap<>()); + List listenerList = listeners.getOrDefault(namespace, new Vector<>()); + listenerList.add(listener); + if (!listeners.containsKey(namespace)) listeners.put(namespace, listenerList); + if (!this.listeners.containsKey(event)) this.listeners.put(event, listeners); + } + + @Override + public void register(@NotNull String namespace, @NotNull Object listener) { + Method[] methods = listener.getClass().getMethods(); + for (Method method : methods) { + if (method.getAnnotation(SubscribeEvent.class) == null) continue; + if (method.getParameterCount() != 1) continue; + if (Event.class.isAssignableFrom(method.getParameterTypes()[0])) continue; + Class clazz = method.getParameterTypes()[0]; + if (!(clazz.isAssignableFrom(Event.class))) continue; + Class event = clazz.asSubclass(Event.class); + this.register(namespace, event, (event1) -> { + try { + method.invoke(listener, event1); + } catch (IllegalAccessException | InvocationTargetException exception) { + ChatRobo.LOGGER.printStackTrace(exception); + } + }); + } + } + + @Override + public void call(@NotNull Event event) { + Map> listeners = this.listeners.getOrDefault(event.getClass(), null); + if (listeners == null) return; + for (List listenerList : listeners.values()) { + for (IEventListener listener : listenerList) { + listener.call(event); + } + } + } +}