Fix state exit
- Fix case where linked pseudostates may cause substate not exited properly. - Tests coming in other commit. - Fixes #208
This commit is contained in:
@@ -754,10 +754,18 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
} else if (kind == PseudoStateKind.ENTRY) {
|
||||
StateContext<S, E> stateContext = buildStateContext(Stage.STATE_CHANGED, message, transition, stateMachine);
|
||||
State<S, E> toState = state.getPseudoState().entry(stateContext);
|
||||
while (toState != null && toState.getPseudoState() != null
|
||||
&& toState.getPseudoState().getKind() != PseudoStateKind.INITIAL) {
|
||||
toState = toState.getPseudoState().entry(stateContext);
|
||||
}
|
||||
setCurrentState(toState, message, transition, true, stateMachine);
|
||||
} else if (kind == PseudoStateKind.EXIT) {
|
||||
StateContext<S, E> stateContext = buildStateContext(Stage.STATE_CHANGED, message, transition, stateMachine);
|
||||
State<S, E> toState = state.getPseudoState().entry(stateContext);
|
||||
while (toState != null && toState.getPseudoState() != null
|
||||
&& toState.getPseudoState().getKind() != PseudoStateKind.INITIAL) {
|
||||
toState = toState.getPseudoState().entry(stateContext);
|
||||
}
|
||||
setCurrentState(toState, message, transition, true, stateMachine);
|
||||
} else if (kind == PseudoStateKind.FORK) {
|
||||
ForkPseudoState<S, E> fps = (ForkPseudoState<S, E>) state.getPseudoState();
|
||||
@@ -982,6 +990,7 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
} else if (isTargetSubOfOtherState) {
|
||||
} else if (!isSubOfSource && !isSubOfTarget && findDeep == null) {
|
||||
} else if (!isSubOfSource && !isSubOfTarget && (transition.getSource() == currentState && StateMachineUtils.isSubstate(currentState, transition.getTarget()))) {
|
||||
} else if (StateMachineUtils.isNormalPseudoState(transition.getTarget())) {
|
||||
} else if (!isSubOfSource && !isSubOfTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.statemachine.support;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.statemachine.state.PseudoState;
|
||||
import org.springframework.statemachine.state.PseudoStateKind;
|
||||
import org.springframework.statemachine.state.State;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -68,6 +70,31 @@ public abstract class StateMachineUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if state is a normal pseudo state, meaning it is a pseudostate
|
||||
* and its kind is not initial or end.
|
||||
*
|
||||
* @param <S> the type of state
|
||||
* @param <E> the type of event
|
||||
* @param state the state
|
||||
* @return true, if is normal pseudo state
|
||||
*/
|
||||
public static <S, E> boolean isNormalPseudoState(State<S, E> state) {
|
||||
if (state == null) {
|
||||
return false;
|
||||
}
|
||||
PseudoState<S, E> pseudoState = state.getPseudoState();
|
||||
if (pseudoState == null) {
|
||||
return false;
|
||||
}
|
||||
PseudoStateKind kind = pseudoState.getKind();
|
||||
if (kind == PseudoStateKind.INITIAL || kind == PseudoStateKind.END) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static <S> Collection<String> toStringCollection(Collection<S> collection) {
|
||||
Collection<String> c = new ArrayList<String>();
|
||||
for (S item : collection) {
|
||||
|
||||
Reference in New Issue
Block a user