Created
February 12, 2014 07:50
-
-
Save aikar/8951549 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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