Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@a613
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a613/8800099b72d728016440 to your computer and use it in GitHub Desktop.
Save a613/8800099b72d728016440 to your computer and use it in GitHub Desktop.
Renewable timer
import java.util.Timer;
import java.util.TimerTask;
/**
* This is a renewable timer. Begin by calling {@link #arm()}, renew it by
* calling {@link #rearm()}, and cancel it by calling {@link #disarm()}.
*
* @param <T>
* type of object stored and passed to listener.
*/
public class AutoDestruct<T> {
private T contents;
private long destructInMs;
private AutoDestructListener<T> onDestruct;
private Timer timer;
private Destruct task;
/**
* Class constructor with no listener.
*
* @param destructInMs
* duration
*/
public AutoDestruct(long destructInMs) {
this(null, destructInMs, null);
}
/**
* Class constructor.
*
* @param contents
* timer content that will be passed to the listener
* @param destructInMs
* duration
* @param onDestruct
* listener to call when the delay has elapsed with no call to
* {@link #rearm()}. Note that the listener has the ability to
* rearm this instance if it chooses.
*/
public AutoDestruct(T contents, long destructInMs, AutoDestructListener<T> onDestruct) {
this.contents = contents;
this.destructInMs = destructInMs;
this.onDestruct = onDestruct;
timer = new Timer();
}
/**
* Cause the timer to begin counting.
*/
public void arm() {
disarm();
task = new Destruct();
timer.schedule(task, destructInMs);
}
/**
* Reset the timer.
*/
public void rearm() {
arm();
}
/**
* Cancel the timer.
*/
public void disarm() {
if (task != null) {
task.cancel();
}
}
/**
* Stop the timer early and call the listener. If the listener is
* {@code null}, this only has the former effect.
*
* @param force
* true to ignore the return value of the listener and always
* detonate, false to leave control to the listener
*/
public void detonate(boolean force) {
disarm();
if (onDestruct == null) {
return;
}
boolean preventDestruct = onDestruct.onAutoDestruct(contents);
if (preventDestruct && !force) {
arm();
}
}
private class Destruct extends TimerTask {
@Override
public void run() {
if (onDestruct == null) {
return;
}
boolean preventDestruct = onDestruct.onAutoDestruct(contents);
if (preventDestruct) {
arm();
}
}
}
/**
* Listener that is called by an {@link AutoDestruct}.
*
* @param <T>
* type of object that is stored in an AutoDestruct instance and
* passed here
*/
public interface AutoDestructListener<T> {
/**
* Use the contents of an {@link AutoDestruct}, and decide whether to
* rearm it.
*
* @param contents
* contents stored by an AutoDestruct
* @return true to rearm the AutoDestruct, false to allow it to detonate
*/
boolean onAutoDestruct(T contents);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment