package mightypork.utils.eventbus;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import mightypork.utils.Reflect;
import mightypork.utils.Str;
import mightypork.utils.eventbus.clients.DelegatingClient;
import mightypork.utils.eventbus.events.flags.DelayedEvent;
import mightypork.utils.eventbus.events.flags.DirectEvent;
import mightypork.utils.eventbus.events.flags.NotLoggedEvent;
import mightypork.utils.interfaces.Destroyable;
import mightypork.utils.logging.Log;
/**
* An event bus, accommodating multiple EventChannels.
* Channel will be created when an event of type is first encountered.
*
* @author Ondřej Hruška (MightyPork)
*/
final public class EventBus implements Destroyable {
/**
* Queued event holder
*/
private class DelayQueueEntry implements Delayed {
private final long due;
private final BusEvent> evt;
public DelayQueueEntry(double seconds, BusEvent> event)
{
super();
this.due = System.currentTimeMillis() + (long) (seconds * 1000);
this.evt = event;
}
@Override
public int compareTo(Delayed o)
{
return Long.valueOf(getDelay(TimeUnit.MILLISECONDS)).compareTo(o.getDelay(TimeUnit.MILLISECONDS));
}
@Override
public long getDelay(TimeUnit unit)
{
return unit.convert(due - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
public BusEvent> getEvent()
{
return evt;
}
}
/**
* Thread handling queued events
*/
private class QueuePollingThread extends Thread {
public volatile boolean stopped = false;
public QueuePollingThread()
{
super("Queue Polling Thread");
}
@Override
public void run()
{
DelayQueueEntry evt;
while (!stopped) {
evt = null;
try {
evt = sendQueue.take();
} catch (final InterruptedException ignored) {
//
}
if (evt != null) {
try {
dispatch(evt.getEvent());
} catch (final Throwable t) {
Log.w(logMark + "Error while dispatching event: ", t);
}
}
}
}
}
static final String logMark = "(bus) ";
private static Class> getEventListenerClass(BusEvent> event)
{
return Reflect.getGenericParameters(event.getClass())[0];
}
/** Log detailed messages (debug) */
public boolean detailedLogging = false;
/** Queue polling thread */
private final QueuePollingThread busThread;
/** Registered clients */
private final Set