BKCommonLib/Task
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.