7
7
import java .util .ArrayList ;
8
8
import java .util .HashMap ;
9
9
10
+ /**
11
+ * Registry for making objects available to listen for events.<br>
12
+ * <br>
13
+ * Implement an EventInterface into your class, then implement the function.<br>
14
+ * <br>
15
+ * In your initializer method, register the instance of the class with {@link EventListenerRegistry#register(EventBase)}
16
+ * <br>
17
+ * Example:
18
+ * <pre>
19
+ * public class ClassWithListener implements EventInit {
20
+ *
21
+ * @ Override
22
+ * public void onEventInit() {
23
+ * // Implement event specific code
24
+ * }
25
+ * }
26
+ * </pre>
27
+ * <br>
28
+ * To create and fire your own events, check {@link EventBase}<br>
29
+ */
10
30
public class EventListenerRegistry {
11
31
12
32
/**
13
- * Eventlistener Registry.<br>
33
+ * Base interface for events.<br>
34
+ * <br>
35
+ * To create a new event, create an interface and extend EventBase.<br>
36
+ * Only 1 method is accepted in an event, so it's best to add {@link FunctionalInterface} to the interface.<br>
37
+ * <br>
38
+ * Example:
39
+ * <pre>
40
+ * @ FunctionalInterface
41
+ * public interface EventInit extends EventBase {
42
+ * public void onEventInit();
43
+ * }
44
+ *
45
+ * @ FunctionalInterface
46
+ * public interface EventAdd extends EventBase {
47
+ * public int onEventAdd(int a, int b); // Accepts parameters and return types
48
+ * }
49
+ * </pre>
50
+ *
51
+ * To fire your event, use {@link EventListenerRegistry#fireEvent(Class)} with the parameter being the event class.<br>
52
+ *
53
+ * <pre>
54
+ * EventListenerRegistry.fireEvent(EventInit.class);
55
+ * </pre>
56
+ *
57
+ * To fire an event with parameters and return types:
58
+ * <pre>
59
+ * int eventResult = (int) EventListenerRegistry.fireEvent(EventAdd.class, a, b);
60
+ * </pre>
61
+ * When using parameters, the type and the amount of parameters has to match!
62
+ */
63
+ public interface EventBase {
64
+ }
65
+
66
+ /**
67
+ * Stores the event listener objects and calls their event methods during {@link EventListenerRegistry#fireEvent(Class, Object...)}<br>
14
68
* <br>
15
69
* Consists of multiple lists seperated by event types.<br>
16
70
* If it were a single ArrayList, firing an event means that you'd have to unnecessarily iterate over the entire list,<br>
@@ -20,7 +74,10 @@ public class EventListenerRegistry {
20
74
*/
21
75
private static final HashMap <Class <?>, ArrayList <EventBase >> EVENTLISTENER_REGISTRY = new HashMap <>();
22
76
23
-
77
+ /**
78
+ * Registers an object to be an event listener. The object must implement an event extending {@link EventBase}
79
+ * @param eventListener The event listener to register
80
+ */
24
81
public static void register (EventBase eventListener ) {
25
82
if (eventListener == null ) {
26
83
throw new NullPointerException ("Tried to register a packethandler with value null" );
@@ -38,6 +95,10 @@ public static void register(EventBase eventListener) {
38
95
}
39
96
}
40
97
98
+ /**
99
+ * Unregisters an object from being an event listener.
100
+ * @param eventListener The event listener to unregister
101
+ */
41
102
public static void unregister (EventBase eventListener ) {
42
103
if (eventListener == null ) {
43
104
throw new NullPointerException ("Tried to unregister a packethandler with value null" );
@@ -74,35 +135,45 @@ public static Object fireEvent(Class<? extends EventListenerRegistry.EventBase>
74
135
* @return The result of the event, might be null if the event returns nothing
75
136
*/
76
137
public static Object fireEvent (Class <? extends EventListenerRegistry .EventBase > eventClass , Object ... eventParams ) {
77
- ArrayList <EventBase > registryList = EVENTLISTENER_REGISTRY .get (eventClass );
78
- if (registryList == null ) {
138
+ ArrayList <EventBase > listenerList = EVENTLISTENER_REGISTRY .get (eventClass );
139
+ if (listenerList == null ) {
79
140
throw new EventException ("The event has not been registered yet" , eventClass );
80
141
}
81
142
143
+ // Exception to be thrown at the end of the method. If null then no exception is thrown
82
144
EventException toThrow = null ;
83
145
84
- Method methodToCheck = getEventMethod (eventClass );
146
+ // Get the method from the event that we are looking for in the event listeners
147
+ Method methodToFind = getEventMethod (eventClass );
85
148
149
+ // Variable for the return value. The last registered listener will return its value
86
150
Object returnValue = null ;
87
- for (EventBase eventListener : registryList ) {
151
+
152
+ // Iterate through the list of eventListeners
153
+ for (EventBase eventListener : listenerList ) {
154
+ // Get all methods in this event listener
88
155
Method [] methodsInListener = eventListener .getClass ().getDeclaredMethods ();
89
156
157
+ // Iterate through all methods
90
158
for (Method method : methodsInListener ) {
91
159
92
- if (!checkName (method , methodToCheck .getName ())) {
160
+ // Check if the current method has the same name as the method we are looking for
161
+ if (!checkName (method , methodToFind .getName ())) {
93
162
continue ;
94
163
}
95
164
165
+ // Check if the length is the same before we check for types
96
166
if (!checkLength (method , eventParams )) {
97
167
toThrow = new EventException (String .format ("Event fired with the wrong number of parameters. Expected: %s, Actual: %s" , method .getParameterCount (), eventParams .length ), eventClass );
98
168
continue ;
99
169
}
100
170
171
+ // Check the types of the method
101
172
if (checkTypes (method , eventParams )) {
102
- toThrow = null ;
173
+ toThrow = null ; // Reset toThrow as the correct method was found
103
174
method .setAccessible (true );
104
175
try {
105
- returnValue = method .invoke (eventListener , eventParams );
176
+ returnValue = method .invoke (eventListener , eventParams ); // Call the method
106
177
} catch (IllegalAccessException | InvocationTargetException e ) {
107
178
throw new EventException (eventClass , e );
108
179
} catch (IllegalArgumentException e ) {
@@ -114,6 +185,7 @@ public static Object fireEvent(Class<? extends EventListenerRegistry.EventBase>
114
185
}
115
186
}
116
187
188
+ // Throw the exception
117
189
if (toThrow != null ) {
118
190
throw toThrow ;
119
191
}
@@ -130,14 +202,29 @@ private static Method getEventMethod(Class<? extends EventListenerRegistry.Event
130
202
return test [0 ];
131
203
}
132
204
205
+ /**
206
+ * @param method The method to check
207
+ * @param name The name to check
208
+ * @return If method.getName equals name
209
+ */
133
210
private static boolean checkName (Method method , String name ) {
134
211
return method .getName ().equals (name );
135
212
}
136
213
214
+ /**
215
+ * @param method The method to check
216
+ * @param parameters The list of parameters
217
+ * @return True, if length of the method parameters is equal to the length of the object parameters
218
+ */
137
219
private static boolean checkLength (Method method , Object ... parameters ) {
138
220
return method .getParameterCount () == parameters .length ;
139
221
}
140
222
223
+ /**
224
+ * @param method The method to check
225
+ * @param parameters The list of parameters
226
+ * @return True, if the types of the parameters equal the object parameters
227
+ */
141
228
private static boolean checkTypes (Method method , Object ... parameters ) {
142
229
Class <?>[] methodParameterTypes = ClassUtils .primitivesToWrappers (method .getParameterTypes ());
143
230
Class <?>[] eventParameterTypes = getParameterTypes (parameters );
@@ -166,7 +253,4 @@ private static Class<?>[] getParameterTypes(Object... parameters) {
166
253
public static void clear () {
167
254
EVENTLISTENER_REGISTRY .clear ();
168
255
}
169
-
170
- public interface EventBase {
171
- }
172
256
}
0 commit comments