001package fr.aumgn.bukkitutils.timer; 002 003import java.util.concurrent.TimeUnit; 004 005import org.bukkit.Bukkit; 006import org.bukkit.ChatColor; 007import org.bukkit.plugin.Plugin; 008 009import com.google.common.base.Stopwatch; 010 011/** 012 * A timer class which display time according 013 * to the delays specified in the {@link TimerConfig} 014 * using the abstract method {@link #sendTimeMessage(String)}. 015 */ 016public abstract class Timer implements Runnable { 017 018 private static final int TICKS_PER_SECONDS = 20; 019 020 private final Plugin plugin; 021 private final int majorDelay; 022 private final int minorDelay; 023 private final String format; 024 private final String endMessage; 025 private Runnable runnable; 026 027 private int remainingTime; 028 029 private int taskId; 030 private Stopwatch watch; 031 private int currentDelay; 032 private int pauseDelay; 033 034 private Timer(boolean dummy, Plugin plugin, TimerConfig config, int seconds) { 035 this.plugin = plugin; 036 this.majorDelay = config.getMajorDuration(); 037 this.minorDelay = config.getMinorDuration(); 038 this.format = config.getFormat(); 039 this.endMessage = config.getEndMessage(); 040 041 this.taskId = -1; 042 this.remainingTime = seconds; 043 044 this.currentDelay = 0; 045 } 046 047 public Timer(Plugin plugin, TimerConfig config, int seconds, Runnable runnable) { 048 this(true, plugin, config, seconds); 049 this.runnable = runnable; 050 } 051 052 public Timer(Plugin plugin, TimerConfig config, int seconds) { 053 this(false, plugin, config, seconds); 054 this.runnable = new Runnable() { 055 public void run() { 056 onFinish(); 057 } 058 }; 059 } 060 061 private void scheduleAndPrintTime(int delay) { 062 long minutes = TimeUnit.SECONDS.toMinutes(remainingTime); 063 String msg = String.format(format, minutes, remainingTime % 60); 064 sendTimeMessage(getCurrentColor() + msg); 065 schedule(delay); 066 } 067 068 private void schedule(int delay) { 069 currentDelay = delay; 070 watch = new Stopwatch(); 071 watch.start(); 072 taskId = Bukkit.getScheduler().scheduleSyncDelayedTask( 073 plugin, this, (long) delay * TICKS_PER_SECONDS); 074 } 075 076 private ChatColor getCurrentColor() { 077 if (remainingTime >= majorDelay) { 078 return ChatColor.YELLOW; 079 } else if (remainingTime >= minorDelay){ 080 return ChatColor.GOLD; 081 } else { 082 return ChatColor.RED; 083 } 084 } 085 086 public int getRemainingTime() { 087 return remainingTime; 088 } 089 090 public void start() { 091 remainingTime -= currentDelay; 092 if (remainingTime > majorDelay) { 093 schedule(majorDelay); 094 } else if (remainingTime > minorDelay) { 095 schedule(minorDelay); 096 } else if (remainingTime > 0) { 097 schedule(1); 098 } else { 099 runnable.run(); 100 } 101 } 102 103 @Override 104 public void run() { 105 remainingTime -= currentDelay; 106 if (remainingTime > majorDelay) { 107 scheduleAndPrintTime(majorDelay); 108 } else if (remainingTime > minorDelay) { 109 scheduleAndPrintTime(minorDelay); 110 } else if (remainingTime > 0) { 111 scheduleAndPrintTime(1); 112 } else { 113 runnable.run(); 114 } 115 } 116 117 public void cancel() { 118 if (taskId != -1) { 119 Bukkit.getScheduler().cancelTask(taskId); 120 taskId = -1; 121 } 122 } 123 124 public void pause() { 125 cancel(); 126 watch.stop(); 127 pauseDelay = (int) watch.elapsedTime(TimeUnit.SECONDS); 128 remainingTime -= pauseDelay; 129 } 130 131 public void resume() { 132 int delay = currentDelay - pauseDelay; 133 if (delay > 0) { 134 scheduleAndPrintTime(delay); 135 } else { 136 runnable.run(); 137 } 138 } 139 140 public void onFinish() { 141 sendTimeMessage(endMessage); 142 } 143 144 public abstract void sendTimeMessage(String string); 145}