ScheduledCallback
From EsWiki
ScheduledCallback is used by Java extensions to schedule execution after a wait of a given number of milliseconds, possibly repeating the execution periodically. Flash classes have access to the Timer class, which can be used in similar fashion.
Contents |
Simple Scheduled Execution
Usually a ScheduledCallback is implemented as an anonymous inner class. For example, to schedule a callback you could use:
int id = getApi().scheduleExecution(durationInMilliseconds,
numberOfTimesToRepeat,
new ScheduledCallback() {
public void scheduledCallback() {
... lines to be executed ...
}
});
If the id is a global variable, then the scheduled callback can be canceled by:
getApi().cancelScheduledExecution(id);
For an infinite number of repeats, set numberOfTimesToRepeat to -1. When doing this, use a global variable for the id, so that you can cancel execution later.
Due to the nature of the anonymous inner class, non-static parameters cannot be passed. There are various ways to get around this, usually involving global variables. Here are two specific examples of uses of a ScheduledCallback.
Cancellable Scheduled Execution
Often in games, all players need to do a task within a certain amount of time, but it does not make sense to force them to wait after everybody has finished, nor to tell them to start the next task twice.
Global variable
private int scheduledCallbackId;
Scheduling the Callback
scheduledCallbackId = getApi().scheduleExecution(seconds * 1000,
1,
new ScheduledCallback() {
public void scheduledCallback() {
...do the next thing...
}
});
}
Cancelling the Callback
if (...everybody finished doing XXX...) {
getApi().cancelScheduledExecution(scheduledCallbackId);
...do the next thing...
}
Multiple Delayed Executions at Various Times
When a player joins a game, it is often useful for the plugin to send a message or several. However, the player's client will not hear plugin messages from the game until after the client realizes that it has joined the game. Here is a way to handle multiple delayed "just joined the game" messages while a game is still filling (so multiple players might be joining at the same time).
Global variable
private ConcurrentLinkedQueue<DelayedMessage> delayMessageQueue = new ConcurrentLinkedQueue<DelayedMessage>();
DelayedMessage is a class that holds the information needed to send a message later, such as username and type of message to be sent.
Scheduling the Callback
protected final synchronized boolean onPlayerEnter(String playerName) {
if (..player is allowed to join the game..) {
...record that the player joined, locking the room if it is full now...
sendDelayedNotificationMessage(playerName, message1, 20);
sendDelayedNotificationMessage(playerName, message2, 30);
}
return true;
} else {
return false;
}
}
private synchronized void sendDelayedNotificationMessage(String playerName, message, int durationMS) {
DelayedMessage obj = new DelayedMessage(playerName, message);
if (delayMessageQueue.add(obj)) {
int id = getApi().scheduleExecution(durationMS,
1,
new ScheduledCallback() {
public void scheduledCallback() {
tickQueue();
}
});
}
}
private synchronized void tickQueue() {
if (delayMessageQueue.isEmpty()) {
return;
}
try {
DelayedMessage msg = delayMessageQueue.poll();
if (msg != null) {
..use the msg object to build a plugin message to be sent to the player..
}
} catch (Exception exception) {
// do nothing
}
}
