Skip to content

The basics ‐ Tasks

ImIllusion edited this page Sep 20, 2023 · 1 revision

When dealing with minigame code, we might want to create tasks that are executed in the background (such as schedulers) that must be cleaned up in order to avoid weird side effects and memory leaks.

Let's start by making a simple GameTask class:

public abstract class GameTask {

    protected final GamePhase phase;

    protected GameTask(GamePhase phase) {
        this.game = game;
    }

    public abstract void start();
    protected abstract void dispose(); // Mandatory to override

    public final void stop() {
        dispose();
        game.removeTask(this);
    }

}

And a simple task

public class ScheduledDelayedTask extends GameTask implements Runnable {

    private final int delay;
    private final JavaPlugin plugin;
    private final Runnable runnable;

    private int taskId = -1;

    public ScheduledDelayedTask(GamePhase phase, Runnable runnable, /* JavaPlugin plugin, */ int delay) {
        super(phase);
        
        // this.plugin = plugin;
        this.plugin = phase.getPlugin(); // If you have this method, use it!
        this.delay = delay;
        this.runnable = runnable;
    }

    @Override
    public void start() {
        taskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, this, delay);
    }

    @Override
    public void run() {
        runnable.run();
        taskId = -1; // Prevent the stop method from causing unexpected behavior
        stop();
    }

    @Override
    protected void dispose() {
        if(taskId == -1) {
            return;
        }

        Bukkit.getScheduler().cancelTask(taskId);
        taskId = -1;
    }
}

We can then tie these tasks to a GamePhase, and clean them up along other things :)

Clone this wiki locally