This commit is contained in:
Vyacheslav Boyko 2022-07-07 23:06:38 +03:00
parent d2fccb9426
commit e5b3015115
3 changed files with 50 additions and 42 deletions

View File

@ -113,6 +113,26 @@ public class Fsm<T extends Fsm, E> {
currentState.beforeEvent();
}
/**
* Main method to handle every event
*
* @param event event
* @throws FsmException
*/
@SuppressWarnings("unchecked")
public void process(E event) throws FsmException {
if (done) {
return;
}
currentState.process(event);
currentState.afterEvent();
if (currentState.isFinish()) {
done = true;
return;
}
switchToNextState(event);
}
/**
* Returns current state
*
@ -131,44 +151,6 @@ public class Fsm<T extends Fsm, E> {
return previousState;
}
/**
* Main method to handle every event
*
* @param event event
* @throws FsmException
*/
@SuppressWarnings("unchecked")
public void process(E event) throws FsmException {
if (done) {
return;
}
currentState.afterEvent();
if (currentState.isFinish()) {
done = true;
return;
}
if (!transitions.containsKey(currentState.getName())) {
throw new TransitionMissedException(currentState.getName());
}
Map<String, Condition<T,E>> conditions = transitions.get(currentState.getName());
List<String> nextStates = new ArrayList<>();
for (String key : conditions.keySet()) {
if (conditions.get(key) == null) {
nextStates.add(key);
} else if(conditions.get(key).check((T) this, event)) {
nextStates.add(key);
}
}
if (nextStates.size() > 1) {
throw new AmbiguousTransitionException(currentState.getName(), nextStates);
}
if (nextStates.size() == 0) {
throw new BrokenTransitionException(currentState.getName());
}
State<E> nextState = states.get(nextStates.get(0));
nextState(nextState, event);
}
/**
* To specify initial state
*
@ -241,11 +223,33 @@ public class Fsm<T extends Fsm, E> {
addTransition(fromState, toState.getName(), condition);
}
private void switchToNextState(E event) {
if (!transitions.containsKey(currentState.getName())) {
throw new TransitionMissedException(currentState.getName());
}
Map<String, Condition<T,E>> conditions = transitions.get(currentState.getName());
List<String> nextStates = new ArrayList<>();
for (String key : conditions.keySet()) {
if (conditions.get(key) == null) {
nextStates.add(key);
} else if(conditions.get(key).check((T) this, event)) {
nextStates.add(key);
}
}
if (nextStates.size() > 1) {
throw new AmbiguousTransitionException(currentState.getName(), nextStates);
}
if (nextStates.size() == 0) {
throw new BrokenTransitionException(currentState.getName());
}
State<E> nextState = states.get(nextStates.get(0));
nextState(nextState, event);
}
private void nextState(State<E> state, E event) {
state.beforeEvent();
previousState = currentState;
currentState = state;
currentState.process(event);
}
private void checkStateExist(String name) throws StateAlreadyExistsException {

View File

@ -32,4 +32,8 @@ public class State<E> implements StateBehaviour<E> {
return finish;
}
public String toString() {
return name;
}
}

View File

@ -108,13 +108,13 @@ public class FsmTest {
simpleFsm.process("");
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
//Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
Assert.assertTrue(initBefore.get());
Assert.assertTrue(initProcess.get());
Assert.assertTrue(initAfter.get());
Assert.assertFalse(initProcess.get());
Assert.assertTrue(finishBefore.get());
Assert.assertFalse(finishProcess.get());
Assert.assertFalse(finishAfter.get());
Assert.assertTrue(finishProcess.get());
}