diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java
index 8c078be2..b0d868e7 100644
--- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java
+++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java
@@ -12,245 +12,268 @@
*
* 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)}
- *
+ * In your initializer method, register the instance of the class with
+ * {@link EventListenerRegistry#register(EventBase)}
* Example:
+ *
*
- * public class ClassWithListener implements EventInit {
+ * public class ClassWithListener implements EventInit {
*
- * @ Override
- * public void onEventInit() {
- * // Implement event specific code
- * }
- * }
+ * @Override
+ * public void onEventInit() {
+ * // Implement event specific code
+ * }
+ * }
*
+ *
*
* To create and fire your own events, check {@link EventBase}
*/
public class EventListenerRegistry {
- /**
- * 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 {
- }
+ /**
+ * 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,
+ * to find the correct events.
+ *
+ * With multiple lists like this, you iterate only over the objects, that have
+ * the correct event applied.
+ */
+ 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");
+ }
+ for (Class> type : eventListener.getClass().getInterfaces()) {
+ if (EventBase.class.isAssignableFrom(type)) {
- /**
- * 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,
- * to find the correct events.
- *
- * With multiple lists like this, you iterate only over the objects, that have the correct event applied.
- */
- private static final HashMap, ArrayList> EVENTLISTENER_REGISTRY = new HashMap<>();
+ // If a new event type is being registered, add a new arraylist
+ ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>());
+ if (registryList == null) {
+ registryList = EVENTLISTENER_REGISTRY.get(type);
+ }
+ registryList.add(eventListener);
+ }
+ }
+ }
- /**
- * 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");
- }
- for (Class> type : eventListener.getClass().getInterfaces()) {
- if (EventBase.class.isAssignableFrom(type)) {
+ /**
+ * 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");
+ }
+ for (Class> type : eventListener.getClass().getInterfaces()) {
+ if (EventBase.class.isAssignableFrom(type)) {
+ ArrayList registryList = EVENTLISTENER_REGISTRY.get(type);
+ if (registryList != null) {
+ registryList.remove(eventListener);
- // If a new event type is being registered, add a new arraylist
- ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>());
- if (registryList == null) {
- registryList = EVENTLISTENER_REGISTRY.get(type);
- }
- registryList.add(eventListener);
- }
- }
- }
+ if (registryList.isEmpty()) {
+ EVENTLISTENER_REGISTRY.remove(type);
+ }
+ }
+ }
+ }
+ }
- /**
- * 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");
- }
- for (Class> type : eventListener.getClass().getInterfaces()) {
- if (EventBase.class.isAssignableFrom(type)) {
- ArrayList registryList = EVENTLISTENER_REGISTRY.get(type);
- if (registryList != null) {
- registryList.remove(eventListener);
+ /**
+ * Fires an event without parameters
+ *
+ * @param eventClass The event class to fire e.g. EventClientInit.class
+ * @return The result of the event, might be null if the event returns nothing
+ */
+ public static Object fireEvent(Class extends EventListenerRegistry.EventBase> eventClass) {
+ return fireEvent(eventClass, new Object[] {});
+ }
- if (registryList.isEmpty()) {
- EVENTLISTENER_REGISTRY.remove(type);
- }
- }
- }
- }
- }
+ /**
+ * Fires an event with parameters
+ *
+ * @param eventClass The event class to fire e.g. EventClientInit.class
+ * @param eventParams List of parameters for the event. Number of arguments and
+ * types have to match.
+ * @return The result of the event, might be null if the event returns nothing
+ */
+ public static Object fireEvent(Class extends EventListenerRegistry.EventBase> eventClass, Object... eventParams) {
+ ArrayList listenerList = EVENTLISTENER_REGISTRY.get(eventClass);
+ if (listenerList == null) {
+ return null;
+ }
- /**
- * Fires an event without parameters
- *
- * @param eventClass The event class to fire e.g. EventClientInit.class
- * @return The result of the event, might be null if the event returns nothing
- */
- public static Object fireEvent(Class extends EventListenerRegistry.EventBase> eventClass) {
- return fireEvent(eventClass, new Object[]{});
- }
+ // Exception to be thrown at the end of the method. If null then no exception is
+ // thrown
+ EventException toThrow = null;
- /**
- * Fires an event with parameters
- *
- * @param eventClass The event class to fire e.g. EventClientInit.class
- * @param eventParams List of parameters for the event. Number of arguments and types have to match.
- * @return The result of the event, might be null if the event returns nothing
- */
- public static Object fireEvent(Class extends EventListenerRegistry.EventBase> eventClass, Object... eventParams) {
- ArrayList listenerList = EVENTLISTENER_REGISTRY.get(eventClass);
- if (listenerList == null) {
- throw new EventException("The event has not been registered yet", eventClass);
- }
+ // Get the method from the event that we are looking for in the event listeners
+ Method methodToFind = getEventMethod(eventClass);
- // Exception to be thrown at the end of the method. If null then no exception is thrown
- EventException toThrow = null;
+ // Variable for the return value. The last registered listener will return its
+ // value
+ Object returnValue = null;
- // Get the method from the event that we are looking for in the event listeners
- Method methodToFind = getEventMethod(eventClass);
+ // Iterate through the list of eventListeners
+ for (EventBase eventListener : listenerList) {
+ // Get all methods in this event listener
+ Method[] methodsInListener = eventListener.getClass().getDeclaredMethods();
- // Variable for the return value. The last registered listener will return its value
- Object returnValue = null;
+ // Iterate through all methods
+ for (Method method : methodsInListener) {
- // Iterate through the list of eventListeners
- for (EventBase eventListener : listenerList) {
- // Get all methods in this event listener
- Method[] methodsInListener = eventListener.getClass().getDeclaredMethods();
+ // Check if the current method has the same name as the method we are looking
+ // for
+ if (!checkName(method, methodToFind.getName())) {
+ continue;
+ }
- // Iterate through all methods
- for (Method method : methodsInListener) {
+ // 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 if the current method has the same name as the method we are looking for
- if (!checkName(method, methodToFind.getName())) {
- continue;
- }
+ // Check the types of the method
+ if (checkTypes(method, eventParams)) {
+ toThrow = null; // Reset toThrow as the correct method was found
+ method.setAccessible(true);
+ try {
+ returnValue = method.invoke(eventListener, eventParams); // Call the method
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new EventException(eventClass, e);
+ } catch (IllegalArgumentException e) {
+ throw new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass, e);
+ }
+ } else {
+ toThrow = new EventException("Event seems to be fired with the wrong parameter types or in the wrong order", eventClass);
+ }
+ }
+ }
- // 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;
- }
+ // Throw the exception
+ if (toThrow != null) {
+ throw toThrow;
+ }
- // Check the types of the method
- if (checkTypes(method, eventParams)) {
- toThrow = null; // Reset toThrow as the correct method was found
- method.setAccessible(true);
- try {
- returnValue = method.invoke(eventListener, eventParams); // Call the method
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new EventException(eventClass, e);
- } catch (IllegalArgumentException e) {
- throw new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass, e);
- }
- } else {
- toThrow = new EventException("Event seems to be fired with the wrong parameter types or in the wrong order", eventClass);
- }
- }
- }
+ return returnValue;
+ }
- // Throw the exception
- if (toThrow != null) {
- throw toThrow;
- }
+ private static Method getEventMethod(Class extends EventListenerRegistry.EventBase> eventClass) {
+ Method[] test = eventClass.getDeclaredMethods();
+ if (test.length != 1) {
+ throw new EventException("The event method is not properly defined. Only one method is allowed inside of an event", eventClass);
+ }
- return returnValue;
- }
+ return test[0];
+ }
- private static Method getEventMethod(Class extends EventListenerRegistry.EventBase> eventClass) {
- Method[] test = eventClass.getDeclaredMethods();
- if (test.length != 1) {
- throw new EventException("The event method is not properly defined. Only one method is allowed inside of an event", eventClass);
- }
+ /**
+ * @param method The method to check
+ * @param name The name to check
+ * @return If method.getName equals name
+ */
+ private static boolean checkName(Method method, String name) {
+ return method.getName().equals(name);
+ }
- return test[0];
- }
+ /**
+ * @param method The method to check
+ * @param parameters The list of parameters
+ * @return True, if length of the method parameters is equal to the length of
+ * the object parameters
+ */
+ private static boolean checkLength(Method method, Object... parameters) {
+ return method.getParameterCount() == parameters.length;
+ }
- /**
- * @param method The method to check
- * @param name The name to check
- * @return If method.getName equals name
- */
- private static boolean checkName(Method method, String name) {
- return method.getName().equals(name);
- }
+ /**
+ * @param method The method to check
+ * @param parameters The list of parameters
+ * @return True, if the types of the parameters equal the object parameters
+ */
+ private static boolean checkTypes(Method method, Object... parameters) {
+ Class>[] methodParameterTypes = ClassUtils.primitivesToWrappers(method.getParameterTypes());
+ Class>[] eventParameterTypes = getParameterTypes(parameters);
- /**
- * @param method The method to check
- * @param parameters The list of parameters
- * @return True, if length of the method parameters is equal to the length of the object parameters
- */
- private static boolean checkLength(Method method, Object... parameters) {
- return method.getParameterCount() == parameters.length;
- }
+ for (int i = 0; i < methodParameterTypes.length; i++) {
+ Class> paramName = methodParameterTypes[i];
+ Class> eventName = eventParameterTypes[i];
- /**
- * @param method The method to check
- * @param parameters The list of parameters
- * @return True, if the types of the parameters equal the object parameters
- */
- private static boolean checkTypes(Method method, Object... parameters) {
- Class>[] methodParameterTypes = ClassUtils.primitivesToWrappers(method.getParameterTypes());
- Class>[] eventParameterTypes = getParameterTypes(parameters);
+ if (paramName == null || eventName == null) {
+ continue;
+ }
- for (int i = 0; i < methodParameterTypes.length; i++) {
- Class> paramName = methodParameterTypes[i];
- Class> eventName = eventParameterTypes[i];
- if (!paramName.equals(eventName)) {
- return false;
- }
- }
- return true;
- }
+ if (!paramName.equals(eventName) && !paramName.isAssignableFrom(eventName)) {
+ return false;
+ }
+ }
+ return true;
+ }
- private static Class>[] getParameterTypes(Object... parameters) {
- Class>[] out = new Class[parameters.length];
- for (int i = 0; i < parameters.length; i++) {
- out[i] = parameters[i].getClass();
- }
- return out;
- }
+ private static Class>[] getParameterTypes(Object... parameters) {
+ Class>[] out = new Class[parameters.length];
+ for (int i = 0; i < parameters.length; i++) {
+ out[i] = parameters[i] == null ? null : parameters[i].getClass();
+ }
+ return out;
+ }
- /**
- * Removes all registry entries
- */
- public static void clear() {
- EVENTLISTENER_REGISTRY.clear();
- }
+ /**
+ * Removes all registry entries
+ */
+ public static void clear() {
+ EVENTLISTENER_REGISTRY.clear();
+ }
}
diff --git a/src/test/java/mctcommon/event/EventTest.java b/src/test/java/mctcommon/event/EventTest.java
index d1b98727..cf1bdd3a 100644
--- a/src/test/java/mctcommon/event/EventTest.java
+++ b/src/test/java/mctcommon/event/EventTest.java
@@ -164,9 +164,6 @@ void testUnregister() {
EventListenerRegistry.unregister(event);
- Exception exception = assertThrows(EventException.class, () -> EventListenerRegistry.fireEvent(TestEvent.class));
-
- String expected = "mctcommon.event.EventTest$TestEvent: The event has not been registered yet";
- assertEquals(expected, exception.getMessage());
+ assertNull(EventListenerRegistry.fireEvent(TestEvent.class));
}
}