Package org.rsbot.event

Source Code of org.rsbot.event.EventManager$KillEvent

package org.rsbot.event;

import org.rsbot.event.events.RSEvent;

import java.util.EventListener;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

public class EventManager implements Runnable {
  public static class KillEvent extends RSEvent {
    private static final long serialVersionUID = 3426050317048250049L;

    @Override
    public void dispatch(final EventListener el) {
    }

    @Override
    public long getMask() {
      return -1;
    }
  }

  private final Logger log = Logger.getLogger(EventManager.class.getName());

  private final EventMulticaster multicaster = new EventMulticaster();
  private final Map<Integer, EventObject> queue = new HashMap<Integer, EventObject>();

  private final Object threadLock = new Object();

  private Thread eventThread;

  /**
   * Adds the event to the queue for the EventManager to process.
   * <p/>
   * Events are processed with the default mask.
   *
   * @param e The event object to dispatch.
   */
  public void dispatchEvent(final EventObject e) {
    synchronized (queue) {
      boolean added = false;
      for (int off = 0; off < queue.size(); ++off) {
        if (!queue.containsKey(off)) {
          queue.put(off, e);
          added = true;
          break;
        }
      }
      if (!added) {
        queue.put(queue.size(), e);
      }
      queue.notifyAll();
    }
  }

  /**
   * Dispatches the given event. Calling this avoids the use
   * of the event queue.
   *
   * @param event The event to fire.
   */
  public void processEvent(final EventObject event) {
    multicaster.fireEvent(event);
  }

  /**
   * Is this thread the event thread?
   *
   * @return <tt>true</tt> if the thread is an event thread; otherwise <tt>false</tt>.
   */
  boolean isEventThread() {
    synchronized (threadLock) {
      return Thread.currentThread() == eventThread;
    }
  }

  /**
   * Is the event thread alive?
   *
   * @return <tt>true</tt> if the thread is alive; otherwise <tt>false</tt>.
   */
  public boolean isEventThreadAlive() {
    synchronized (threadLock) {
      return eventThread != null;
    }
  }

  /**
   * Kills the event manager thread.
   *
   * @param wait <tt>true</tt> to wait for the kill
   *             event to be processed before returning; otherwise
   *             <tt>false</tt> to submit the kill event and return
   *             immediately.
   */
  public void killThread(final boolean wait) {
    final EventObject event = new KillEvent();
    synchronized (event) {
      dispatchEvent(event);
      if (wait) {
        try {
          event.wait();
        } catch (final InterruptedException e) {
          log.info("wait for kill event interrupted!");
        }
      }
    }
  }

  /**
   * Registers a listener.
   *
   * @param listener the listener to add.
   */
  public void addListener(final EventListener listener) {
    multicaster.addListener(listener);
  }

  /**
   * Registers a listener.
   *
   * @param listener the listener to add.
   * @param mask     the event type mask.
   */
  public void addListener(final EventListener listener, final long mask) {
    multicaster.addListener(listener, mask);
  }

  /**
   * Removes a listener.
   *
   * @param listener the listener to remove.
   */
  public void removeListener(final EventListener listener) {
    multicaster.removeListener(listener);
  }

  /**
   * The thread entry point.
   */
  public void run() {
    if (!isEventThread()) {
      throw new IllegalThreadStateException();
    }
    while (true) {
      try {
        EventObject event = null;
        synchronized (queue) {
          while (queue.isEmpty()) {
            try {
              queue.wait();
            } catch (final Exception e) {
              log.info("Event Queue: " + e.toString());
            }
          }
          int emptySpots = 0;
          for (int off = 0; off < queue.size() + emptySpots; ++off) {
            if (!queue.containsKey(off)) {
              emptySpots++;
              continue;
            }
            event = queue.remove(off);
            break;
          }
        }
        if (event instanceof KillEvent) {
          eventThread = null;
          synchronized (event) {
            event.notifyAll();
          }
          return;
        }
        try {
          processEvent(event);
        } catch (final ThreadDeath td) {
          eventThread = null;
          event.notifyAll();
          return;
        } catch (final Throwable e) {
          e.printStackTrace();
        }
        synchronized (event) {
          event.notifyAll();
        }
      } catch (final Exception e) {
        log.info("Event Queue: " + e.toString());
        e.printStackTrace();
      }
    }
  }

  /**
   * Spawns a daemon event thread. Only one can be created unless it is
   * killed.
   */
  public void start() {
    synchronized (threadLock) {
      if (eventThread != null) {
        throw new IllegalThreadStateException();
      }
      eventThread = new Thread(this, "EventQueue-" + hashCode());
      eventThread.setDaemon(true);
      eventThread.start();
    }
  }
}
TOP

Related Classes of org.rsbot.event.EventManager$KillEvent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.