BKCommonLib/Task

From BergerHealer Wiki
Jump to navigation Jump to search

« Go back

Introduction

The Task class is a wrapper class for starting Bukkit scheduler tasks (synchronized only). They can be used to execute a task with a certain tick delay, or with a certain tick interval. They can easily be started and stopped.

Usage

Tasks are abstract implementations - you need to make a new Class that extends the Task class and implement the run() method. In there you can execute your logic. In almost all cases, you will want to do something like this:

Task myTask = new Task(MyPlugin.plugin) {
    @Override
    public void run() {
        Bukkit.broadcastMessage("Test after 10 ticks!");
    }
}.start(10);

As you can see, all start() and stop() methods return the 'this' Task instance, allowing calls to be chained and the Task to be stored in a single line. In case of a task in your own plugin, this is a general way of doing it:

public class MyPlugin extends JavaPlugin {
    private Task myTask;

    @Override
    public void onEnable() {
        myTask = new Task(this) {
            @Override
            public void run() {
                Bukkit.broadcastMessage("This message is displayed about every second");
            }
        }.start(20, 20);
    }

    @Override
    public void onDisable() {
        Task.stop(myTask);
        myTask = null;
    }
}

It is possible to use myTask.stop() instead, but in the event that myTask is not initialized (and is null) Task.stop is more secure, as it includes a null check. Who knows, perhaps there was an error while enabling or for some other reason your task ended up nulled sooner.

Start types

You can start in multiple ways:

  • Task.start() - runs the task a single time at the end of the current tick
  • Task.start(10) - runs the task a single time in 10 ticks
  • Task.start(10, 20) - runs the task every 20 ticks, with a delay of 10 ticks before starting to repeat

Next-tick tasks

Since you have to start these tasks so often, there is an alternative to using the Task class for executing next-tick tasks: CommonUtil.nextTick. It allows you to schedule a Runnable to execute at the end of the current tick, similar to how Task.start() works. Example:

CommonUtil.nextTick(new Runnable() {
    @Override
    public void run() {
        Bukkit.broadcastMessage("Next tick message!");
    }
});

You do not have to pass in a Plugin instance, and it is also impossible to cancel the task once scheduled. When BKCommonLib disables all remaining tasks are discarded - only use this to schedule tasks while the server is enabling or running, not when disabling.

Tips for passing in parameters

It is possible that you want to use data obtained in an event or function to pass into the scheduled task - so how to easily use it? Making your own Task wrapper class with all these variables stored is possible, but also very inefficient. Java has a nice trick for that: final variables:

@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
    final Player player = event.getPlayer();
    new Task(plugin) {
        @Override
        public void run() {
            player.sendMessage("Welcome to our server!");
        }
    }.start(40);
}

Be very careful with this, as it IS prone to memory leaks. As a rule of thumb, don't use final variables to pass them into repeating tasks, as these variables then never get garbage collected. Even better would be to use primitive types only - a player name instead of a Player.