Created
February 12, 2014 07:10
-
-
Save aikar/8951207 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 instanceof AsyncTask) { | |
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<A, R> { | |
TaskChain chain = null; | |
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 AsyncTask<A, R> extends Task<A, R> {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment