
org.squirrelframework.foundation.fsm.impl.TimedStateImpl Maven / Gradle / Ivy
package org.squirrelframework.foundation.fsm.impl;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.squirrelframework.foundation.component.SquirrelConfiguration;
import org.squirrelframework.foundation.fsm.Action;
import org.squirrelframework.foundation.fsm.AnonymousAction;
import org.squirrelframework.foundation.fsm.ImmutableTimedState;
import org.squirrelframework.foundation.fsm.MutableTimedState;
import org.squirrelframework.foundation.fsm.StateMachine;
import com.google.common.collect.Maps;
public class TimedStateImpl, S, E, C> extends StateImpl
implements ImmutableTimedState, MutableTimedState {
private long timeInterval;
private long initialDelay;
private E autoFireEvent;
private C autoFireContext;
private final ScheduledExecutorService scheduler = SquirrelConfiguration.getScheduler();
// TODO-hhe: not a good way to store runtime data in state definition
private transient final Map> futures = Maps.newConcurrentMap();
private Action lastEntryAction = new AnonymousAction() {
@Override
public void execute(S from, S to, E event, C context, final T stateMachine) {
final Runnable scheduledTask = new Runnable() {
@Override
public void run() {
stateMachine.fire(autoFireEvent, autoFireContext);
}
};
final Future> future = (timeInterval<=0) ?
scheduler.schedule(scheduledTask, initialDelay, TimeUnit.MILLISECONDS) :
scheduler.scheduleAtFixedRate(scheduledTask,
initialDelay, timeInterval, TimeUnit.MILLISECONDS);
futures.put(getKey(stateMachine), future);
}
@Override
public int weight() {
return Action.MIN_WEIGHT;
}
@Override
public String name() {
return "__TIMED_STATE_ENTRY_ACTION";
}
};
private Action firstExitAction = new AnonymousAction() {
@Override
public void execute(S from, S to, E event, C context, T stateMachine) {
Future> future = futures.remove(getKey(stateMachine));
if(future!=null) {
future.cancel(false);
}
}
@Override
public int weight() {
return Action.MAX_WEIGHT;
}
@Override
public String name() {
return "__TIMED_STATE_EXIT_ACTION";
}
};
TimedStateImpl(S stateId) {
super(stateId);
entryActions.add(lastEntryAction);
exitActions.add(firstExitAction);
}
@Override
public long getTimeInterval() {
return timeInterval;
}
@Override
public E getAutoFireEvent() {
return autoFireEvent;
}
@Override
public void setTimeInterval(long timeInterval) {
this.timeInterval = timeInterval;
}
@Override
public void setAutoFireEvent(E event) {
this.autoFireEvent = event;
}
@Override
public void setInitialDelay(long initialDelay) {
this.initialDelay = initialDelay;
}
@Override
public long getInitialDelay() {
return initialDelay;
}
@Override
public void setAutoFireContext(C context) {
this.autoFireContext = context;
}
@Override
public C getAutoFireContext() {
return autoFireContext;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy