001 package org.bukkit.plugin; 002 003 import org.bukkit.event.Event; 004 import org.bukkit.event.EventException; 005 import org.bukkit.event.EventPriority; 006 import org.bukkit.event.Listener; 007 008 /** 009 * Extends RegisteredListener to include timing information 010 */ 011 public class TimedRegisteredListener extends RegisteredListener { 012 private int count; 013 private long totalTime; 014 private Class<? extends Event> eventClass; 015 private boolean multiple = false; 016 017 public TimedRegisteredListener(final Listener pluginListener, final EventExecutor eventExecutor, final EventPriority eventPriority, final Plugin registeredPlugin, final boolean listenCancelled) { 018 super(pluginListener, eventExecutor, eventPriority, registeredPlugin, listenCancelled); 019 } 020 021 @Override 022 public void callEvent(Event event) throws EventException { 023 if (event.isAsynchronous()) { 024 super.callEvent(event); 025 return; 026 } 027 count++; 028 Class<? extends Event> newEventClass = event.getClass(); 029 if (this.eventClass == null) { 030 this.eventClass = newEventClass; 031 } else if (!this.eventClass.equals(newEventClass)) { 032 multiple = true; 033 this.eventClass = getCommonSuperclass(newEventClass, this.eventClass).asSubclass(Event.class); 034 } 035 long start = System.nanoTime(); 036 super.callEvent(event); 037 totalTime += System.nanoTime() - start; 038 } 039 040 private static Class<?> getCommonSuperclass(Class<?> class1, Class<?> class2) { 041 while (!class1.isAssignableFrom(class2)) { 042 class1 = class1.getSuperclass(); 043 } 044 return class1; 045 } 046 047 /** 048 * Resets the call count and total time for this listener 049 */ 050 public void reset() { 051 count = 0; 052 totalTime = 0; 053 } 054 055 /** 056 * Gets the total times this listener has been called 057 * 058 * @return Times this listener has been called 059 */ 060 public int getCount() { 061 return count; 062 } 063 064 /** 065 * Gets the total time calls to this listener have taken 066 * 067 * @return Total time for all calls of this listener 068 */ 069 public long getTotalTime() { 070 return totalTime; 071 } 072 073 /** 074 * Gets the class of the events this listener handled. If it handled 075 * multiple classes of event, the closest shared superclass will be 076 * returned, such that for any event this listener has handled, 077 * <code>this.getEventClass().isAssignableFrom(event.getClass())</code> 078 * and no class <code>this.getEventClass().isAssignableFrom(clazz) 079 * && this.getEventClass() != clazz && 080 * event.getClass().isAssignableFrom(clazz)</code> for all handled events. 081 * 082 * @return the event class handled by this RegisteredListener 083 */ 084 public Class<? extends Event> getEventClass() { 085 return eventClass; 086 } 087 088 /** 089 * Gets whether this listener has handled multiple events, such that for 090 * some two events, <code>eventA.getClass() != eventB.getClass()</code>. 091 * 092 * @return true if this listener has handled multiple events 093 */ 094 public boolean hasMultiple() { 095 return multiple; 096 } 097 }