Created
July 25, 2012 04:18
-
-
Save dumptruckman/3174361 to your computer and use it in GitHub Desktop.
A class for a Bukkit countdown task complete with warnings and "events" for doing stuff when started/finished
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class CountdownTask implements Runnable { | |
private boolean started = false; | |
private boolean dead = false; | |
private int countdown; | |
private long lastTime = 0L; | |
private final Set<Integer> warnings = new HashSet<Integer>(); | |
private final Plugin plugin; | |
public CountdownTask(final Plugin plugin, final int countdown) { | |
this.plugin = plugin; | |
this.countdown = countdown; | |
warnings = new HashSet<Integer>(); | |
} | |
protected final void setCountdown(int countdown) { | |
this.countdown = countdown; | |
} | |
/** | |
* Adds warning times to the countdown. | |
* The collection should contain the seconds at which a warning should occur. | |
* When a warning time is reached countdownWarning() is called. | |
*/ | |
public final void setWarnings(Collection<Integer> warnings) { | |
this.warnings.addAll(warnings); | |
} | |
/** | |
* Starts the countdown | |
*/ | |
public final void start() { | |
if (!started && !dead) { | |
lastTime = System.currentTimeMillis(); | |
started = true; | |
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), this, 5L); | |
} | |
} | |
/** | |
* Call to abruptly end the countdown and do nothing further. | |
*/ | |
public final void kill() { | |
dead = true; | |
} | |
@Override | |
public final void run() { | |
if (started) { | |
final long timeDiff = System.currentTimeMillis() - lastTime; | |
if (timeDiff < 1000) { | |
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), this, 5L); | |
return; | |
} else { | |
// Play catch-up if needed | |
final long missed = timeDiff / 1000; | |
for (int i = 1; i < missed; i++) { | |
if (dead) { | |
break; | |
} | |
processCountdown(); | |
} | |
lastTime += missed * 1000L; | |
} | |
if (!dead && countdown > 0 && !shouldEnd()) { | |
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), this, 5L); | |
} | |
processCountdown(); | |
} | |
} | |
private void processCountdown() { | |
if (shouldCountdown() && !dead) { | |
countdown--; | |
if (countdown <= 0) { | |
dead = true; | |
countdownFinished(); | |
} else if (warnings.contains(countdown)) { | |
countdownWarning(countdown); | |
} | |
} | |
} | |
/** | |
* Implement to do something at the start of the countdown. | |
*/ | |
public abstract void onStart(); | |
/** | |
* Implement for a way to end the countdown early. | |
* | |
* @return true to end countdown, false for countdown to continue | |
*/ | |
public abstract boolean shouldEnd(); | |
/** | |
* Implement for a way to effectively pause the countdown. | |
* When this returns false the countdown will halt. | |
* MUST return true to countdown at all. | |
* | |
* @return true to countdown, false to NOT countdown | |
*/ | |
public abstract boolean shouldCountdown(); | |
/** | |
* Implement if you are using countdown warnings as defined via the setWarnings() method. | |
* This is called when the countdown reaches the warning times. | |
* | |
* @param warning The warning time the countdown has reached. | |
*/ | |
public abstract void countdownWarning(int warning); | |
/** | |
* Implement to do something when the countdown has completed (reached 0). | |
*/ | |
public abstract void countdownFinished(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment