CraftBukkit does not guarantee that a listener for an event class will receive events of all of its subclasses. Events are dispatched only to the HandlerList of the most derived superclass that declares its own getHandlerList method. Any HandlerLists further up the class hiearchy will not receive the event. As such, receiving all events of a particular class is effectively impossible, because any subclass could declare its own getHandlerList. Indeed, many of CraftBukkit's own events do exactly this, so knowing exactly what events a listener will receive involves inspecting the source code of its entire class hiearchy.
This patch changes the method that searches for the HandlerList for an event class to use the least derived superclass instead of the most derived. Any HandlerLists in subclasses are completely unused. The event dispatch code is also changed to find its HandlerList in the same way, instead of calling Event#getHandlers. To make this fast, HandlerLists are cached by event class, so a typical dispatch does not require any reflection or iterating through superclasses.
The new method PluginManager#getHandlerList serves as a replacement for the (now unused) Event#getHandlers, and it uses the cache.
CraftBukkit does not guarantee that a listener for an event class will receive events of all of its subclasses. Events are dispatched only to the
HandlerList
of the most derived superclass that declares its owngetHandlerList
method. AnyHandlerList
s further up the class hiearchy will not receive the event. As such, receiving all events of a particular class is effectively impossible, because any subclass could declare its owngetHandlerList
. Indeed, many of CraftBukkit's own events do exactly this, so knowing exactly what events a listener will receive involves inspecting the source code of its entire class hiearchy.This patch changes the method that searches for the HandlerList for an event class to use the least derived superclass instead of the most derived. Any HandlerLists in subclasses are completely unused. The event dispatch code is also changed to find its HandlerList in the same way, instead of calling
Event#getHandlers
. To make this fast,HandlerList
s are cached by event class, so a typical dispatch does not require any reflection or iterating through superclasses.The new method
PluginManager#getHandlerList
serves as a replacement for the (now unused)Event#getHandlers
, and it uses the cache.