-
Notifications
You must be signed in to change notification settings - Fork 497
/
PipeEventBus.java
123 lines (101 loc) · 3.65 KB
/
PipeEventBus.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package buildcraft.transport;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import buildcraft.transport.pipes.events.PipeEvent;
import buildcraft.transport.pipes.events.PipeEventPriority;
public class PipeEventBus {
private class EventHandler {
public Method method;
public Object owner;
public EventHandler(Method m, Object o) {
this.method = m;
this.owner = o;
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof EventHandler)) {
return false;
}
EventHandler e = (EventHandler) o;
return e.method.equals(method) && e.owner == owner;
}
}
private static class EventHandlerCompare implements Comparator<EventHandler> {
private int getPriority(EventHandler eh) {
PipeEventPriority p = eh.method.getAnnotation(PipeEventPriority.class);
return p != null ? p.priority() : 0;
}
@Override
public int compare(EventHandler o1, EventHandler o2) {
int priority1 = getPriority(o1);
int priority2 = getPriority(o2);
return priority2 - priority1;
}
}
private static final EventHandlerCompare COMPARATOR = new EventHandlerCompare();
private static final HashSet<Object> globalHandlers = new HashSet<Object>();
private final HashSet<Object> registeredHandlers = new HashSet<Object>();
private final HashMap<Object, Map<Method, Class<? extends PipeEvent>>> handlerMethods = new HashMap<Object, Map<Method, Class<? extends PipeEvent>>>();
private final HashMap<Class<? extends PipeEvent>, List<EventHandler>> eventHandlers = new HashMap<Class<? extends PipeEvent>, List<EventHandler>>();
public PipeEventBus() {
for (Object o : globalHandlers) {
registerHandler(o);
}
}
public static void registerGlobalHandler(Object globalHandler) {
globalHandlers.add(globalHandler);
}
private List<EventHandler> getHandlerList(Class<? extends PipeEvent> event) {
if (!eventHandlers.containsKey(event)) {
eventHandlers.put(event, new ArrayList<EventHandler>());
}
return eventHandlers.get(event);
}
public void registerHandler(Object handler) {
if (registeredHandlers.contains(handler)) {
return;
}
registeredHandlers.add(handler);
Map<Method, Class<? extends PipeEvent>> methods = new HashMap<Method, Class<? extends PipeEvent>>();
for (Method m: handler.getClass().getDeclaredMethods()) {
if ("eventHandler".equals(m.getName())) {
Class[] parameters = m.getParameterTypes();
if (parameters.length == 1 && PipeEvent.class.isAssignableFrom(parameters[0])) {
Class<? extends PipeEvent> eventType = (Class<? extends PipeEvent>) parameters[0];
List<EventHandler> eventHandlerList = getHandlerList(eventType);
eventHandlerList.add(new EventHandler(m, handler));
updateEventHandlers(eventHandlerList);
methods.put(m, eventType);
}
}
}
handlerMethods.put(handler, methods);
}
private void updateEventHandlers(List<EventHandler> eventHandlerList) {
eventHandlerList.sort(COMPARATOR);
}
public void unregisterHandler(Object handler) {
if (!registeredHandlers.contains(handler)) {
return;
}
registeredHandlers.remove(handler);
Map<Method, Class<? extends PipeEvent>> methodMap = handlerMethods.get(handler);
for (Method m : methodMap.keySet()) {
getHandlerList(methodMap.get(m)).remove(new EventHandler(m, handler));
}
handlerMethods.remove(handler);
}
public void handleEvent(Class<? extends PipeEvent> eventClass, PipeEvent event) {
for (EventHandler eventHandler : getHandlerList(eventClass)) {
try {
eventHandler.method.invoke(eventHandler.owner, event);
} catch (Exception e) {
}
}
}
}