Event Managers

Apr 21, 2011
292
39
0
Here are some event managers I wrote in my spare time, these were inspired by Graham Edgecombe's implementation.

Code:
package net.exion.evt;
 
import java.util.LinkedList;

/**
 * This is an implementation of single thread event processing, I wrote it for
 * my server, Exion. Although it can be used for many functions. As of now this
 * is no longer single threaded, there will be 2 threads, but will only activate
 * the second thread if the time spent processing on the first thread exceeds 
 * the CYCLE_INTERVAL. I also decided to go with enforcing a set cycle
 * interval, because the RuneScape client runs on a 600ms interval, it just 
 * wouldn't be right not to enforce this..
 * 
 * @author Smokey`
 */
public class EventManager implements Runnable {

	/**
	 * The time spent processing the events.
	 */
	public static long timeSpent = 0;
	
	/**
	 * A controller, or hook if you will; to determine
	 * whether the event manager is running or not.
	 */
	private boolean running = true;
	
	/**
	 * A linked list of events to execute; on a set interval
	 */
	private LinkedList<Event> events = new LinkedList<Event>();
	
	/**
	 * The offload worker, or back-up thread. This will
	 * handle other events if the timeSpent is equal 
	 * to or greater then the specified interval.
	 */
	private OffloadWorker offloadWorker = new OffloadWorker();
	
	/**
	 * The current time before the events have been processed.
	 */
	private long startTime;
	
	/**
	 * The interval at which to execute the events.
	 */
	final long CYCLE_INTERVAL = 600; 
	
	/**
	 * Another hook; (is) whether or not to offload
	 * events to the OffloadWorker
	 */
	private boolean offloadEvents = false; 

	/**
	 * Initialize the EventManager, start a new thread to process the events.
	 */
	public EventManager() {
		new Thread(this).start();
	}

	/**
	 * Processes all the events in a syncrhonized fashion using a 
	 * LinkedList. We'll set the startTime, process the events, and
	 * set the timeSpent then we'll sleep for the CYCLE_INTERVAL
	 *  - timeSpent, This will ensure close to perfect timing every time.
	 *  Note: I'm not sure if nano time would be better, seems like it would be, 
	 *  being such a tiny measurement of time. 
	 */
	public void run() {
		while (isRunning()) { 
			try {
				//set the starting time
				startTime = System.currentTimeMillis();
				
				for (Event event : events) { 
					//execute the events
					synchronized (event) {
						event.execute();
					}
				}
				//time spent = currentTime - startTime
				timeSpent = System.currentTimeMillis() - startTime;
				
				//Remove the last event and add it to the offload worker.
				if (timeSpent >= CYCLE_INTERVAL 
						|| events.size() >= 10) {
					events.remove(events.getLast());
					//signal to offload new events being added
					offloadEvents = true;
					offloadWorker.thread.start();
				}
				Thread.sleep(CYCLE_INTERVAL - timeSpent);
			} catch (Exception ex) {
				ex.printStackTrace();
				destruct();
				return;
			}
		}
	}

	/**
	 * Add an event to either the OffloadWorker or this
	 * thread.
	 * 
	 * @param evt the event to be added
	 */
	public void put(Event evt) {
		if(offloadEvents) {
			offloadWorker.events.add(evt);
		} else
			events.add(evt);
	}

	/**
	 * Stops an event from being executed.
	 * 
	 * @param evt the event to be halted from execution
	 */
	public void halt(Event evt) {
		synchronized (events) {
			if(!events.remove(evt)){
				offloadWorker.events.remove(evt);
			}
		}
	}

	/**
	 * @return whether or not the event manager is running
	 */
	public boolean isRunning() {
		return running;
	}

	/**
	 * Stop all events.
	 */
	public void destruct() {
		running = false;
		events = null;
	}

	/**
	 * Gets the instance of this class.
	 * 
	 * @return the instance
	 */
	public static EventManager getInstance() {
		return InstanceHolder.instance;
	}

	/**
	 * Instance holder for this class
	 */
	static class InstanceHolder {
		public static final EventManager instance = new EventManager();
	}
}

Code:
package net.exion.evt;
 
import java.util.LinkedList;

/**
 * A back up thread, to handle excess events when 
 * the EventManager is being over used; basicly 
 * just a way to handle huge loads.
 * 
 * @author Smokey`
 */
public class OffloadWorker implements Runnable {

	/**
	 * A linked list of events to execute.
	 */
	public LinkedList<Event> events = new LinkedList<Event>();
	
	/**
	 * Thread for the OffloadWorker
	 */
	public Thread thread = null;
	
	/**
	 * Initialize the thread.
	 */
	public OffloadWorker() {
		thread = new Thread(this);
	}
	
	/**
	 * Execute all off-loaded events on the given interval.
	 */
	@Override
	public void run() {
		while (true) {
			long startTime = System.currentTimeMillis();
			try {
				for(Event event : events) {
					synchronized(event) { 
						event.execute();
					}
				}
				
				Thread.sleep(EventManager.getInstance().CYCLE_INTERVAL 
						- (System.currentTimeMillis() - startTime));
			} catch (Exception ex) {
				ex.printStackTrace();
				return;
			}
		}
	}
}

Code:
package net.exion.evt; 

/**
 * Represents an event to be executed.
 * 
 * @author Smokey` 
 */
public abstract class Event {

	/**
	 * Being called on a set interval 
	 */
	public abstract void execute();  
	
}

This is 100% my code, I will give credits though.

Credits:

  1. Daniel(GhostSnyper) - Discussion/Ideas
  2. Impulser' - Discussion/Ideas
  3. Graham - Inspiration

The reason I wrote this is simple. I didn't want to be dependant on someone elses code, mainly Graham's. So I wrote this for my server.

I'm open to new ideas/discussion.

Also, I DIDN'T KNOW WHERE TO POST THIS.. SO IT'S HERE..

~Smokey`
 
Resembles Graham's original too much.

It's similar, but has higher load capabilities.

Also this uses an abstract class, not an interface. And executes the events differently if I remember correctly. (y)

Just because it resembles Graham's doesn't mean it's useless.
 
Agreed, this reminds me of Grahams too much, and it isn't nearly as good as his. His seems to be more stabled for me, and allows for much more room for customization. Just my personal opinion.

Nonetheless, you did an alright job with yours.
 
Agreed, this reminds me of Grahams too much, and it isn't nearly as good as his. His seems to be more stabled for me, and allows for much more room for customization. Just my personal opinion.

Nonetheless, you did an alright job with yours.

yubumpreallyoldthread?
 
yubumpreallyoldthread?


Watch out everyone 3 months is a really old thread!!!!


This ok, but I would rather stick with Grahams. The only thing I can think of is, won't this have sync issues when it uses both threads for events?
 
When you remove the last event it isn't added to the "offload" worker, it gets lost.


do you guys seriously not know what events are
According to some old naming scheme these are events, whoever decided on it needs to be shot
 

Users who are viewing this thread (total: 1, members: 0, guests: 1)

Who read this thread (total members: 2)