Skip to content

Instantly share code, notes, and snippets.

@Minikloon
Created April 30, 2017 21:40
Show Gist options
  • Save Minikloon/741c24512d1500c87c76a2efb07bbae5 to your computer and use it in GitHub Desktop.
Save Minikloon/741c24512d1500c87c76a2efb07bbae5 to your computer and use it in GitHub Desktop.
StateInJava
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.time.Instant;
public abstract class StateInJava {
private static final Logger logger = LoggerFactory.getLogger(StateInJava.class);
private boolean started = false;
private boolean ended = false;
private Instant startInstant = null;
private final Object lock = new Object();
public void start() {
synchronized(lock) {
if(started || ended)
return;
started = true;
}
startInstant = Instant.now();
try {
onStart();
} catch(Throwable e) {
logger.error("Exception during " + getClass().getName() + " start", e);
}
}
protected abstract void onStart();
private boolean updating = false;
public void update() {
synchronized(lock) {
if(!started || ended || updating)
return;
updating = true;
}
if(isReadyToEnd() && !frozen) {
end();
return;
}
try {
onUpdate();
} catch(Throwable e) {
logger.error("Exception during " + getClass().getName() + " update", e);
}
updating = false;
}
protected abstract void onUpdate();
public boolean isReadyToEnd() {
return ended || getRemainingDuration() == Duration.ZERO;
}
public void end() {
synchronized(lock) {
if(!started || ended)
return;
ended = true;
}
try {
onEnd();
} catch(Throwable e) {
logger.error("Exception during " + getClass().getName () + " end", e);
}
}
protected abstract void onEnd();
public abstract Duration getDuration();
public Duration getRemainingDuration() {
if(startInstant == null)
return getDuration();
Duration sinceStart = Duration.between(startInstant, Instant.now());
Duration remaining = getDuration().minus(sinceStart);
if(remaining.isNegative())
return Duration.ZERO;
else
return remaining;
}
private boolean frozen = false;
public void setFrozen(boolean frozen) {
this.frozen = frozen;
}
public boolean isFrozen() {
return frozen;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment