Skip to content

Instantly share code, notes, and snippets.

@aikar

aikar/TaskChain.java

Created Feb 12, 2014
Embed
What would you like to do?
package com.empireminecraft.util;
import org.bukkit.Bukkit;
import java.util.concurrent.ConcurrentLinkedQueue;
public class TaskChain {
// Tells a task it will perform call back later.
public static final Object WAIT = new Object();
ConcurrentLinkedQueue<Task> chainQueue = new ConcurrentLinkedQueue<>();
boolean executed = false;
Object previous = null;
boolean async = !Bukkit.isPrimaryThread();
public static TaskChain newChain() {
return new TaskChain();
}
public <T, R> TaskChain add(Task<T, R> task) {
synchronized (this) {
if (executed) {
throw new RuntimeException("TaskChain is executing");
}
}
chainQueue.add(task);
return this;
}
public void execute() {
synchronized (this) {
if (executed) {
throw new RuntimeException("Already executed");
}
executed = true;
}
nextTask();
}
private void nextTask() {
final TaskChain chain = this;
final Task task = chainQueue.poll();
if (task.async) {
if (async) {
task.run(this);
} else {
BukkitUtil.runTaskAsync(new Runnable() {
@Override
public void run() {
chain.async = true;
task.run(chain);
}
});
}
} else {
if (async) {
BukkitUtil.runTask(new Runnable() {
@Override
public void run() {
chain.async = false;
task.run(chain);
}
});
} else {
task.run(this);
}
}
}
public abstract static class Task<R, A> {
TaskChain chain = null;
boolean async = false;
private void run(TaskChain chain) {
final Object arg = chain.previous;
chain.previous = null;
this.chain = chain;
chain.previous = this.run((A) arg);
if (chain.previous != WAIT) {
chain.nextTask();
}
}
public abstract R run(A arg);
public void next(R resp) {
chain.previous = resp;
chain.nextTask();
}
}
public abstract static class GenericTask extends Task<Object, Object> {}
public abstract static class FirstTask<R> extends Task<R, Object> {}
public abstract static class LastTask<A> extends Task<Object, A> {}
public abstract static class GenericAsyncTask extends Task<Object, Object> {{async = true;}}
public abstract static class AsyncTask<R, A> extends Task<R, A> {{async = true;}}
public abstract static class AsyncFirstTask<R> extends FirstTask<R> {{async = true;}}
public abstract static class AsyncLastTask<A> extends LastTask<A> {{async = true;}}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment