Skip to content

Instantly share code, notes, and snippets.

@hamza-cskn
Last active December 5, 2022 22:27
Show Gist options
  • Save hamza-cskn/38a6fea701e7038f2273e05774d18323 to your computer and use it in GitHub Desktop.
Save hamza-cskn/38a6fea701e7038f2273e05774d18323 to your computer and use it in GitHub Desktop.
Simple Task Chain for Bukkit
import org.bukkit.Bukkit;
import java.util.function.Function;
public class ChainExecutor {
private ChainTask first;
private static Function<ChainTask, Boolean> toBooleanFunction(Runnable runnable) {
return chain -> {
runnable.run();
return true;
};
}
private void registerTask(Function<ChainTask, Boolean> task, boolean sync) {
ChainTask chainTask = new ChainTask(task, sync);
if (this.first == null) {
this.first = chainTask;
return;
}
this.first.addToTail(chainTask);
}
private void registerTask(Runnable task, boolean sync) {
registerTask(ChainExecutor.toBooleanFunction(task), sync);
}
public ChainExecutor sync(Function<ChainTask, Boolean> runnable) {
registerTask(runnable, true);
return this;
}
public ChainExecutor sync(Runnable runnable) {
return sync(ChainExecutor.toBooleanFunction(runnable));
}
public ChainExecutor async(Function<ChainTask, Boolean> runnable) {
registerTask(runnable, false);
return this;
}
public ChainExecutor async(Runnable runnable) {
return async(ChainExecutor.toBooleanFunction(runnable));
}
public void execute() {
this.first.execute();
}
public static class ChainTask {
private final Function<ChainTask, Boolean> task;
private ChainTask next;
private final boolean sync;
private ChainTask(Function<ChainTask, Boolean> task, boolean sync) {
this.task = task;
this.sync = sync;
}
public void addToTail(ChainTask task) {
if (this.next == null) {
this.next = task;
return;
}
this.next.addToTail(task);
}
public void sync(Function<ChainTask, Boolean> task) {
insertNext(task, true);
}
public void sync(Runnable task) {
insertNext(task, true);
}
public void async(Function<ChainTask, Boolean> task) {
insertNext(task, false);
}
public void async(Runnable task) {
insertNext(task, false);
}
public void insertNext(Function<ChainTask, Boolean> task, boolean sync) {
this.insertNext(new ChainTask(task, sync));
}
public void insertNext(Runnable task, boolean sync) {
this.insertNext(new ChainTask(ChainExecutor.toBooleanFunction(task), sync));
}
public void insertNext(ChainTask task) {
task.next = this.next;
this.next = task;
}
public void next() {
if (this.next != null)
this.next.execute();
}
public void execute() {
if (!this.sync && Bukkit.isPrimaryThread()) {
Bukkit.getScheduler().runTaskAsynchronously(YOUR-PLUGIN-INSTANCE, this::runTask);
} else if (this.sync && !Bukkit.isPrimaryThread()) {
Bukkit.getScheduler().runTask(YOUR-PLUGIN-INSTANCE, this::runTask);
} else {
this.runTask();
}
}
public void runTask() {
if (this.task.apply(this)) {
this.next();
}
}
}
}
@hamza-cskn
Copy link
Author

        new ChainExecutor()
                .sync(() -> System.out.println("1 - sync: " + Bukkit.isPrimaryThread()))
                .async(() -> System.out.println("2 - sync: " + Bukkit.isPrimaryThread()))
                .sync(chain -> {
                    System.out.println("3 - sync: " + Bukkit.isPrimaryThread());
                    chain.async(() -> System.out.println("4 - sync: " + Bukkit.isPrimaryThread()));
                    System.out.println("5 - sync: " + Bukkit.isPrimaryThread());
                    return true; //should chain continue
                })
                .async(chain -> {
                    System.out.println("6 - sync: " + Bukkit.isPrimaryThread());
                    return false; //should chain continue
                })
                .sync(() -> System.out.println("7 - sync: " + Bukkit.isPrimaryThread()))
                .execute();

OUTPUT:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment