我做了一个事件系统,但是太慢了。
问题是,我从未实际添加的地图中有多个条目。我不明白他们是如何到达那里的。
public class OrdinalMap<V> {
private final Map<Integer, V> map;
public OrdinalMap(Class<? extends Enum<?>> valueType, V virginValue) {
map = new HashMap<Integer, V>();
Enum<?>[] enums = valueType.getEnumConstants();
for (int i = 0; i < enums.length; i++) {
put(enums[i].ordinal(), virginValue);
}
}
public OrdinalMap(Class<? extends Enum<?>> valueType) {
this(valueType, null);
}
public V put(Integer key, V value) {
return map.put(key, value);
}
public V get(Object o) {
return map.get(o);
}
public Set<Entry<Integer, V>> entrySet() {
return map.entrySet();
}
}
我想让dispatchEvent更快(更少的迭代)。由于registerListener它有太多的迭代
在所有其他优先级中都有事件处理程序方法,但它们不应该存在。我不知道为什么会有,但我确定它在registerListener中。因为它们在所有优先级中,所以我必须使用此检查: if (mapping.getKey().getAnnotation(EventHandler.class).priority().ordinal() == entry.getKey()) {
这使它变得更慢。
@Override
public void dispatchEvent(Event event) {
OrdinalMap<Map<Method, EventListener>> priorityMap = getRegistry().get(event.getClass());
if (priorityMap != null) {
CancellableEvent cancellableEvent = null;
boolean cancellable;
if (cancellable = event instanceof CancellableEvent) {
cancellableEvent = (CancellableEvent) event;
if (cancellableEvent.isCancelled()) return;
}
try {
for (Entry<Integer, Map<Method, EventListener>> entry : priorityMap.entrySet()) {
for (Entry<Method, EventListener> mapping : entry.getValue().entrySet()) {
if (mapping.getKey().getAnnotation(EventHandler.class).priority().ordinal() == entry.getKey()) {
mapping.getKey().invoke(mapping.getValue(), event);
if (cancellable && cancellableEvent.isCancelled()) return;
}
}
}
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public void registerListener(EventListener listener) {
for (Method method : listener.getClass().getMethods()) {
EventHandler handler = method.getAnnotation(EventHandler.class);
if (handler != null) {
Class<?>[] parameters = method.getParameterTypes();
if (parameters.length == 1) {
@SuppressWarnings("unchecked")
Class<? extends Event> event = (Class<? extends Event>) parameters[0];
EventPriority priority = handler.priority();
OrdinalMap<Map<Method, EventListener>> priorityMap = getRegistry().get(event);
if (priorityMap == null) {
priorityMap = new OrdinalMap<Map<Method, EventListener>>(EventPriority.class, (Map<Method, EventListener>) new HashMap<Method, EventListener>());
}
Map<Method, EventListener> methodMap = priorityMap.get(priority.ordinal());
methodMap.put(method, listener);
priorityMap.put(priority.ordinal(), methodMap);
getRegistry().put(event, priorityMap);
}
}
}
}