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 }