Event system optimizations. Addresses BUKKIT-813

- Made the handlers field a simple array instead of an array of arrays.
- Got rid of the "baked" field.
This commit is contained in:
TomyLobo 2012-02-28 19:37:27 -06:00 committed by EvilSeph
parent 07f964813c
commit 93521af608
3 changed files with 38 additions and 51 deletions

View File

@ -37,14 +37,12 @@ public class TimingsCommand extends Command {
boolean separate = "separate".equals(args[0]); boolean separate = "separate".equals(args[0]);
if ("reset".equals(args[0])) { if ("reset".equals(args[0])) {
for (HandlerList handlerList : HandlerList.getHandlerLists()) { for (HandlerList handlerList : HandlerList.getHandlerLists()) {
for (RegisteredListener[] listeners : handlerList.getRegisteredListeners()) { for (RegisteredListener listener : handlerList.getRegisteredListeners()) {
for (RegisteredListener listener : listeners) {
if (listener instanceof TimedRegisteredListener) { if (listener instanceof TimedRegisteredListener) {
((TimedRegisteredListener)listener).reset(); ((TimedRegisteredListener)listener).reset();
} }
} }
} }
}
sender.sendMessage("Timings reset"); sender.sendMessage("Timings reset");
} else if ("merged".equals(args[0]) || separate) { } else if ("merged".equals(args[0]) || separate) {

View File

@ -14,7 +14,7 @@ public class HandlerList {
/** /**
* Handler array. This field being an array is the key to this system's speed. * Handler array. This field being an array is the key to this system's speed.
*/ */
private RegisteredListener[][] handlers = new RegisteredListener[EventPriority.values().length][]; private RegisteredListener[] handlers = null;
/** /**
* Dynamic handler lists. These are changed using register() and * Dynamic handler lists. These are changed using register() and
@ -23,15 +23,6 @@ public class HandlerList {
*/ */
private final EnumMap<EventPriority, ArrayList<RegisteredListener>> handlerslots; private final EnumMap<EventPriority, ArrayList<RegisteredListener>> handlerslots;
/**
* Whether the current HandlerList has been fully baked. When this is set
* to false, the Map<EventPriority, List<RegisteredListener>> will be baked to RegisteredListener[][]
* next time the event is called.
*
* @see org.bukkit.plugin.SimplePluginManager#callEvent
*/
private boolean baked = false;
/** /**
* List of all HandlerLists which have been created, for use in bakeAll() * List of all HandlerLists which have been created, for use in bakeAll()
*/ */
@ -56,7 +47,7 @@ public class HandlerList {
for (List<RegisteredListener> list : h.handlerslots.values()) { for (List<RegisteredListener> list : h.handlerslots.values()) {
list.clear(); list.clear();
} }
h.baked = false; h.handlers = null;
} }
} }
@ -102,7 +93,7 @@ public class HandlerList {
public void register(RegisteredListener listener) { public void register(RegisteredListener listener) {
if (handlerslots.get(listener.getPriority()).contains(listener)) if (handlerslots.get(listener.getPriority()).contains(listener))
throw new IllegalStateException("This listener is already registered to priority " + listener.getPriority().toString()); throw new IllegalStateException("This listener is already registered to priority " + listener.getPriority().toString());
baked = false; handlers = null;
handlerslots.get(listener.getPriority()).add(listener); handlerslots.get(listener.getPriority()).add(listener);
} }
@ -123,9 +114,8 @@ public class HandlerList {
* @param listener listener to remove * @param listener listener to remove
*/ */
public void unregister(RegisteredListener listener) { public void unregister(RegisteredListener listener) {
if (handlerslots.get(listener.getPriority()).contains(listener)) { if (handlerslots.get(listener.getPriority()).remove(listener)) {
baked = false; handlers = null;
handlerslots.get(listener.getPriority()).remove(listener);
} }
} }
@ -144,7 +134,7 @@ public class HandlerList {
} }
} }
} }
if (changed) baked = false; if (changed) handlers = null;
} }
/** /**
@ -162,18 +152,19 @@ public class HandlerList {
} }
} }
} }
if (changed) baked = false; if (changed) handlers = null;
} }
/** /**
* Bake HashMap and ArrayLists to 2d array - does nothing if not necessary * Bake HashMap and ArrayLists to 2d array - does nothing if not necessary
*/ */
public void bake() { public void bake() {
if (baked) return; // don't re-bake when still valid if (handlers != null) return; // don't re-bake when still valid
List<RegisteredListener> entries = new ArrayList<RegisteredListener>();
for (Entry<EventPriority, ArrayList<RegisteredListener>> entry : handlerslots.entrySet()) { for (Entry<EventPriority, ArrayList<RegisteredListener>> entry : handlerslots.entrySet()) {
handlers[entry.getKey().getSlot()] = (entry.getValue().toArray(new RegisteredListener[entry.getValue().size()])); entries.addAll(entry.getValue());
} }
baked = true; handlers = entries.toArray(new RegisteredListener[entries.size()]);
} }
/** /**
@ -181,7 +172,8 @@ public class HandlerList {
* *
* @return the array of registered listeners * @return the array of registered listeners
*/ */
public RegisteredListener[][] getRegisteredListeners() { public RegisteredListener[] getRegisteredListeners() {
bake();
return handlers; return handlers;
} }

View File

@ -431,11 +431,9 @@ public final class SimplePluginManager implements PluginManager {
*/ */
public synchronized void callEvent(Event event) { public synchronized void callEvent(Event event) {
HandlerList handlers = event.getHandlers(); HandlerList handlers = event.getHandlers();
handlers.bake(); RegisteredListener[] listeners = handlers.getRegisteredListeners();
RegisteredListener[][] listeners = handlers.getRegisteredListeners();
for (int i = 0; i < listeners.length; i++) { for (RegisteredListener registration : listeners) {
for (RegisteredListener registration : listeners[i]) {
if (!registration.getPlugin().isEnabled()) { if (!registration.getPlugin().isEnabled()) {
continue; continue;
} }
@ -465,7 +463,6 @@ public final class SimplePluginManager implements PluginManager {
} }
} }
} }
}
public void registerEvents(Listener listener, Plugin plugin) { public void registerEvents(Listener listener, Plugin plugin) {
if (!plugin.isEnabled()) { if (!plugin.isEnabled()) {