package com.intellectualcrafters.plot.util; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.object.RunnableVal; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; public abstract class TaskManager { public static TaskManager IMP; public static final HashSet<String> TELEPORT_QUEUE = new HashSet<>(); public static final HashMap<Integer, Integer> tasks = new HashMap<>(); public static AtomicInteger index = new AtomicInteger(0); public <T> T sync(final RunnableVal<T> function) { return sync(function, Integer.MAX_VALUE); } public <T> T sync(final RunnableVal<T> function, int timeout) { if (PS.get().isMainThread(Thread.currentThread())) { function.run(); return function.value; } final AtomicBoolean running = new AtomicBoolean(true); RunnableVal<RuntimeException> run = new RunnableVal<RuntimeException>() { @Override public void run(RuntimeException value) { try { function.run(); } catch (RuntimeException e) { this.value = e; } catch (Throwable neverHappens) { neverHappens.printStackTrace(); } finally { running.set(false); } synchronized (function) { function.notifyAll(); } } }; TaskManager.IMP.task(run); try { synchronized (function) { while (running.get()) { function.wait(timeout); } } } catch (InterruptedException e) { e.printStackTrace(); } if (run.value != null) { throw run.value; } return function.value; } public static int runTaskRepeat(Runnable runnable, int interval) { if (runnable != null) { if (IMP == null) { throw new IllegalArgumentException("disabled"); } return IMP.taskRepeat(runnable, interval); } return -1; } public static int runTaskRepeatAsync(Runnable runnable, int interval) { if (runnable != null) { if (IMP == null) { throw new IllegalArgumentException("disabled"); } return IMP.taskRepeat(runnable, interval); } return -1; } public static void runTaskAsync(Runnable runnable) { if (runnable != null) { if (IMP == null) { runnable.run(); return; } IMP.taskAsync(runnable); } } public static void runTask(Runnable runnable) { if (runnable != null) { if (IMP == null) { runnable.run(); return; } IMP.task(runnable); } } /** * Run task later. * @param runnable The task * @param delay The delay in ticks */ public static void runTaskLater(Runnable runnable, int delay) { if (runnable != null) { if (IMP == null) { runnable.run(); return; } IMP.taskLater(runnable, delay); } } public static void runTaskLaterAsync(Runnable runnable, int delay) { if (runnable != null) { if (IMP == null) { runnable.run(); return; } IMP.taskLaterAsync(runnable, delay); } } /** * Break up a series of tasks so that they can run without lagging the server. * @param objects * @param task * @param whenDone */ public static <T> void objectTask(Collection<T> objects, final RunnableVal<T> task, final Runnable whenDone) { final Iterator<T> iterator = objects.iterator(); TaskManager.runTask(new Runnable() { @Override public void run() { long start = System.currentTimeMillis(); boolean hasNext; while ((hasNext = iterator.hasNext()) && System.currentTimeMillis() - start < 5) { task.value = iterator.next(); task.run(); } if (!hasNext) { TaskManager.runTaskLater(whenDone, 1); } else { TaskManager.runTaskLater(this, 1); } } }); } public abstract int taskRepeat(Runnable runnable, int interval); public abstract int taskRepeatAsync(Runnable runnable, int interval); public abstract void taskAsync(Runnable runnable); public abstract void task(Runnable runnable); public abstract void taskLater(Runnable runnable, int delay); public abstract void taskLaterAsync(Runnable runnable, int delay); public abstract void cancelTask(int task); }