diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java index 9e012877..8c078be2 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java @@ -7,10 +7,64 @@ import java.util.ArrayList; import java.util.HashMap; +/** + * Registry for making objects available to listen for events.
+ *
+ * Implement an EventInterface into your class, then implement the function.
+ *
+ * In your initializer method, register the instance of the class with {@link EventListenerRegistry#register(EventBase)} + *
+ * Example: + *
+ *     public class ClassWithListener implements EventInit {
+ *
+ *          @ Override
+ *          public void onEventInit() {
+ *              // Implement event specific code
+ *          }
+ *     }
+ * 
+ *
+ * To create and fire your own events, check {@link EventBase}
+ */ public class EventListenerRegistry { /** - * Eventlistener Registry.
+ * Base interface for events.
+ *
+ * To create a new event, create an interface and extend EventBase.
+ * Only 1 method is accepted in an event, so it's best to add {@link FunctionalInterface} to the interface.
+ *
+ * Example: + *
+     *     @ FunctionalInterface
+     *     public interface EventInit extends EventBase {
+     *         public void onEventInit();
+     *     }
+     *
+     *     @ FunctionalInterface
+     *     public interface EventAdd extends EventBase {
+     *         public int onEventAdd(int a, int b); // Accepts parameters and return types
+     *     }
+     * 
+ * + * To fire your event, use {@link EventListenerRegistry#fireEvent(Class)} with the parameter being the event class.
+ * + *
+     *     EventListenerRegistry.fireEvent(EventInit.class);
+     * 
+ * + * To fire an event with parameters and return types: + *
+     *     int eventResult = (int) EventListenerRegistry.fireEvent(EventAdd.class, a, b);
+     * 
+ * When using parameters, the type and the amount of parameters has to match! + */ + public interface EventBase { + } + + /** + * Stores the event listener objects and calls their event methods during {@link EventListenerRegistry#fireEvent(Class, Object...)}
*
* Consists of multiple lists seperated by event types.
* If it were a single ArrayList, firing an event means that you'd have to unnecessarily iterate over the entire list,
@@ -20,7 +74,10 @@ public class EventListenerRegistry { */ private static final HashMap, ArrayList> EVENTLISTENER_REGISTRY = new HashMap<>(); - + /** + * Registers an object to be an event listener. The object must implement an event extending {@link EventBase} + * @param eventListener The event listener to register + */ public static void register(EventBase eventListener) { if (eventListener == null) { throw new NullPointerException("Tried to register a packethandler with value null"); @@ -38,6 +95,10 @@ public static void register(EventBase eventListener) { } } + /** + * Unregisters an object from being an event listener. + * @param eventListener The event listener to unregister + */ public static void unregister(EventBase eventListener) { if (eventListener == null) { throw new NullPointerException("Tried to unregister a packethandler with value null"); @@ -74,35 +135,45 @@ public static Object fireEvent(Class * @return The result of the event, might be null if the event returns nothing */ public static Object fireEvent(Class eventClass, Object... eventParams) { - ArrayList registryList = EVENTLISTENER_REGISTRY.get(eventClass); - if (registryList == null) { + ArrayList listenerList = EVENTLISTENER_REGISTRY.get(eventClass); + if (listenerList == null) { throw new EventException("The event has not been registered yet", eventClass); } + // Exception to be thrown at the end of the method. If null then no exception is thrown EventException toThrow = null; - Method methodToCheck = getEventMethod(eventClass); + // Get the method from the event that we are looking for in the event listeners + Method methodToFind = getEventMethod(eventClass); + // Variable for the return value. The last registered listener will return its value Object returnValue = null; - for (EventBase eventListener : registryList) { + + // Iterate through the list of eventListeners + for (EventBase eventListener : listenerList) { + // Get all methods in this event listener Method[] methodsInListener = eventListener.getClass().getDeclaredMethods(); + // Iterate through all methods for (Method method : methodsInListener) { - if (!checkName(method, methodToCheck.getName())) { + // Check if the current method has the same name as the method we are looking for + if (!checkName(method, methodToFind.getName())) { continue; } + // Check if the length is the same before we check for types if (!checkLength(method, eventParams)) { toThrow = new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass); continue; } + // Check the types of the method if (checkTypes(method, eventParams)) { - toThrow = null; + toThrow = null; // Reset toThrow as the correct method was found method.setAccessible(true); try { - returnValue = method.invoke(eventListener, eventParams); + returnValue = method.invoke(eventListener, eventParams); // Call the method } catch (IllegalAccessException | InvocationTargetException e) { throw new EventException(eventClass, e); } catch (IllegalArgumentException e) { @@ -114,6 +185,7 @@ public static Object fireEvent(Class } } + // Throw the exception if (toThrow != null) { throw toThrow; } @@ -130,14 +202,29 @@ private static Method getEventMethod(Class[] methodParameterTypes = ClassUtils.primitivesToWrappers(method.getParameterTypes()); Class[] eventParameterTypes = getParameterTypes(parameters); @@ -166,7 +253,4 @@ private static Class[] getParameterTypes(Object... parameters) { public static void clear() { EVENTLISTENER_REGISTRY.clear(); } - - public interface EventBase { - } }