Я пытаюсь реализовать конечный автомат с вложенными состояниями (как показано ниже) с помощью Spring Statemachine (версия 2.1.3).
Направленный конечный автомат
В приведенном ниже коде я предполагаю, что stateMachineDepth3
соответствует этой машине
package de.iotiq.test.statemachine;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.StateMachineBuilder;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.State;
public class Main {
public static void main(String[] args) throws Exception {
StateMachine<States, String> stateMachineDepth2;
StateMachine<States, String> stateMachineDepth3;
StateMachineBuilder.Builder<States, String> builder2 = StateMachineBuilder.builder();
StateMachineBuilder.Builder<States, String> builder3 = StateMachineBuilder.builder();
configureL2(builder2.configureStates(), null);
configureL2(builder2.configureTransitions());
configureL1(builder3.configureStates());
configureL1(builder3.configureTransitions());
stateMachineDepth2 = builder2.build();
stateMachineDepth3 = builder3.build();
stateMachineDepth2.addStateListener(new StateMachineListenerAdapter<States, String>() {
@Override
public void stateEntered(State<States, String> state) {
System.out.println("State (D2) -> " + state.getId());
}
@Override
public void stateExited(State<States, String> state) {
System.out.println("State (D2) <- " + state.getId());
}
});
stateMachineDepth3.addStateListener(new StateMachineListenerAdapter<States, String>() {
@Override
public void stateEntered(State<States, String> state) {
System.out.println("State (D3) -> " + state.getId());
}
@Override
public void stateExited(State<States, String> state) {
System.out.println("State (D3) <- " + state.getId());
}
});
stateMachineDepth2.start();
stateMachineDepth3.start();
}
private static void configureL1(StateMachineStateConfigurer<States, String> states) throws Exception {
states
.withStates()
.initial(States.S1)
.state(States.S1)
.state(States.S2)
;
configureL2(states, States.S2);
}
private static void configureL2(StateMachineStateConfigurer<States, String> states, States parent) throws Exception {
states
.withStates()
.parent(parent)
.initial(States.S2a)
.state(States.S2a)
.state(States.S2b)
;
configureL3(states);
}
private static void configureL3(StateMachineStateConfigurer<States, String> states) throws Exception {
states
.withStates()
.parent(States.S2b)
.initial(States.S2b1)
.state(States.S2b1)
.choice(States.S2b2)
.state(States.S2b2)
.state(States.S2b3)
.state(States.S2b4)
.state(States.S2b5)
;
}
private static void configureL1(StateMachineTransitionConfigurer<States, String> transitions) throws Exception {
transitions
.withExternal()
.source(States.S1)
.target(States.S2)
;
configureL2(transitions);
}
private static void configureL2(StateMachineTransitionConfigurer<States, String> transitions) throws Exception {
transitions
.withExternal()
.source(States.S2a)
.target(States.S2b)
;
configureL3(transitions);
}
private static void configureL3(StateMachineTransitionConfigurer<States, String> transitions) throws Exception {
transitions
.withExternal()
.source(States.S2b1)
.target(States.S2b2)
.and()
.withChoice()
.source(States.S2b2)
.first(States.S2b3, decide())
.last(States.S2b4)
.and()
.withExternal()
.source(States.S2b3)
.target(States.S2b5)
.and()
.withExternal()
.source(States.S2b4)
.target(States.S2b5)
;
}
private static Guard<States, String> decide() {
return new Guard<States, String>() {
public boolean evaluate(StateContext<States, String> context) {
System.out.println("eveluating...");
return false;
}
};
}
}
, когда я запускаю ее с stateMachineDepth3.start();
Я получаю следующий вывод
State (D3) -> S1
State (D3) <- S1
State (D3) -> S2
State (D3) -> S2a
State (D3) <- S2a
State (D3) -> S2b
State (D3) -> S2b1
eveluating...
State (D3) <- S2b1
State (D3) <- S2b
State (D3) -> S2b4
State (D3) <- S2b4
State (D3) -> S2b5
Как виднос выхода при переходе от S2b1
к S2b4
он выходит из S2b
, что не должно быть.
Для конечного автомата с глубиной 2, как в stateMachineDepth2
,который состоит из S2
внутренних элементов, похоже, что переходы такие же, как и ожидалось.Вывод будет таким, как показано ниже:
State (D2) -> S2a
State (D2) <- S2a
State (D2) -> S2b
State (D2) -> S2b1
eveluating...
State (D2) <- S2b1
State (D2) -> S2b4
State (D2) <- S2b4
State (D2) -> S2b5
Можете ли вы увидеть что-то неправильное в моей реализации statemachine?