Fix substate transition

- Should now correctly do corrent actions when
  transition is between different submachines and
  their substates.
- Fixes #32
This commit is contained in:
Janne Valkealahti
2015-04-04 15:51:45 +01:00
parent a4fcb9da97
commit 8282daf5d8
2 changed files with 30 additions and 3 deletions

View File

@@ -345,9 +345,7 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
return null;
}
void setCurrentState(State<S, E> statex, Message<E> event, Transition<S, E> transition, boolean exit) {
State<S, E> state = statex;
void setCurrentState(State<S, E> state, Message<E> event, Transition<S, E> transition, boolean exit) {
State<S, E> findDeep = findDeepParent(state);
boolean isTargetSubOf = false;
if (transition != null) {
@@ -418,11 +416,15 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
new HashMap<String, Object>());
StateContext<S, E> stateContext = new DefaultStateContext<S, E>(messageHeaders, extendedState, transition, this);
State<S, E> findDeep = findDeepParent(transition.getTarget());
boolean isTargetSubOfOtherState = findDeep != null && findDeep != currentState;
boolean isSubOfSource = isSubstate(transition.getSource(), currentState);
boolean isSubOfTarget = isSubstate(transition.getTarget(), currentState);
if (currentState == transition.getSource() && currentState == transition.getTarget()) {
} else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getSource()) {
} else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
} else if (isTargetSubOfOtherState) {
} else if (!isSubOfSource && !isSubOfTarget) {
return;
}
@@ -445,10 +447,15 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
StateContext<S, E> stateContext = new DefaultStateContext<S, E>(messageHeaders, extendedState, transition, this);
if (transition != null) {
State<S, E> findDeep1 = findDeepParent(transition.getTarget());
State<S, E> findDeep2 = findDeepParent(transition.getSource());
boolean isComingFromOtherSubmachine = findDeep1 != null && findDeep2 != null && findDeep2 != currentState;
boolean isSubOfSource = isSubstate(transition.getSource(), currentState);
boolean isSubOfTarget = isSubstate(transition.getTarget(), currentState);
if (currentState == transition.getSource() && currentState == transition.getTarget()) {
} else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
} else if (isComingFromOtherSubmachine) {
} else if (isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
return;
} else if (!isSubOfSource && !isSubOfTarget) {

View File

@@ -177,6 +177,26 @@ public class ShowcaseTests {
assertThat(listener.statesEntered.size(), is(3));
}
@Test
public void testF() throws Exception {
listener.reset(1, 4, 2, 0);
machine.sendEvent(Events.F);
listener.stateChangedLatch.await(1, TimeUnit.SECONDS);
assertThat(machine.getState().getIds(), contains(States.S0, States.S2, States.S21, States.S211));
assertThat(listener.statesExited.size(), is(2));
assertThat(listener.statesEntered.size(), is(4));
}
@Test
public void testG() throws Exception {
listener.reset(1, 4, 2, 0);
machine.sendEvent(Events.G);
listener.stateChangedLatch.await(1, TimeUnit.SECONDS);
assertThat(machine.getState().getIds(), contains(States.S0, States.S2, States.S21, States.S211));
assertThat(listener.statesExited.size(), is(2));
assertThat(listener.statesEntered.size(), is(4));
}
static class Config {
@Autowired