sclass RestartableCountdown implements AutoCloseable { java.util.Timer timer; long targetTime; // in sys time ifndef RestartableCountdown_noStats long /*firings,*/ totalSleepTime; // stats endifndef synchronized void setTargetTime(long targetTime, Runnable action) { if (targetTime <= 0) stop(); else if (targetTime != this.targetTime) { start(targetTime-sysNow(), action); this.targetTime = targetTime; } } // stops the countdown and restarts it synchronized void start(long delayMS, O action) { stop(); if (delayMS <= 0) thread { callF(action); } else { totalSleepTime + delayMS; timer = doLater_daemon(delayMS, action); targetTime = sysNow()+delayMS; } } void start(double delaySeconds, O action) { start(toMS(delaySeconds), action); } synchronized void stop() { cancelTimer(timer); timer = null; targetTime = 0; } public void close() { stop(); } }