package jane.test.async; import java.util.Comparator; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.PriorityBlockingQueue; public final class AsyncManager { private static final class TaskWrap extends AsyncTimerTask { private final Runnable _r; public TaskWrap(int delayMs, Runnable r) { super(delayMs); _r = r; } @Override public void run() { _r.run(); } } private static final class TaskComparator implements Comparator<AsyncTimerTask> { @Override public int compare(AsyncTimerTask task1, AsyncTimerTask task2) { long d = task1._time - task2._time; return d < 0 ? -1 : (d > 0 ? 1 : 0); } } private static AsyncManager _instance = new AsyncManager(); private static AsyncException _ae; private final ConcurrentLinkedQueue<Runnable> _readyQueue = new ConcurrentLinkedQueue<>(); private final PriorityBlockingQueue<AsyncTimerTask> _taskQueue = new PriorityBlockingQueue<>(16, new TaskComparator()); public static AsyncManager get() { return _instance; } public static AsyncException getAsyncException() { return _ae; } public static void setAsyncException(AsyncException ae) { _ae = ae; } static void onException(Runnable r, Throwable e) { AsyncException ae = _ae; if(ae != null) ae.onException(r, e); } public void submit(Runnable r) { _readyQueue.offer(r); } public void submit(AsyncTimerTask task) { if(task != null) _taskQueue.offer(task); } public void submit(int delayMs, Runnable r) { if(r != null) _taskQueue.offer(new TaskWrap(delayMs, r)); } public int tick() { int done = 0; for(long time = System.currentTimeMillis();;) { AsyncTimerTask task = _taskQueue.peek(); if(task == null || task._time > time) break; try { task = _taskQueue.poll(); if(task == null) break; task.run(); ++done; } catch(Throwable e) { AsyncManager.onException(task, e); } } for(int n = _readyQueue.size(); n > 0; --n) { Runnable r = _readyQueue.poll(); if(r == null) break; try { r.run(); ++done; } catch(Throwable e) { onException(r, e); } } return done; } }