Renewable timer
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
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