145 lines
5.4 KiB
Java
145 lines
5.4 KiB
Java
package com.tuoheng.status.machine.config;
|
||
|
||
import com.tuoheng.status.machine.events.DrcEvent;
|
||
import com.tuoheng.status.machine.platform.factory.PlatformStrategyFactory;
|
||
import com.tuoheng.status.machine.platform.strategy.DrcPlatformStrategy;
|
||
import com.tuoheng.status.machine.status.DrcState;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.context.annotation.Bean;
|
||
import org.springframework.context.annotation.Configuration;
|
||
import org.springframework.statemachine.StateMachine;
|
||
import org.springframework.statemachine.config.StateMachineBuilder;
|
||
import org.springframework.statemachine.config.StateMachineFactory;
|
||
|
||
import java.util.EnumSet;
|
||
import java.util.UUID;
|
||
|
||
/**
|
||
* DRC(飞行控制模式)状态机配置(多平台支持版本)
|
||
* 通过PlatformStrategyFactory动态获取平台特定的Guard、Action和Listener
|
||
*/
|
||
@Configuration
|
||
public class DrcMachineConfig {
|
||
|
||
@Autowired
|
||
private PlatformStrategyFactory platformStrategyFactory;
|
||
|
||
@Bean(name = "drcStateMachineFactory")
|
||
public StateMachineFactory<DrcState, DrcEvent> drcStateMachineFactory() throws Exception {
|
||
return new StateMachineFactory<DrcState, DrcEvent>() {
|
||
@Override
|
||
public StateMachine<DrcState, DrcEvent> getStateMachine() {
|
||
return null;
|
||
}
|
||
|
||
@Override
|
||
public StateMachine<DrcState, DrcEvent> getStateMachine(String machineId) {
|
||
try {
|
||
// 根据机巢SN获取平台策略
|
||
DrcPlatformStrategy strategy = platformStrategyFactory.getDrcStrategy(machineId);
|
||
|
||
StateMachineBuilder.Builder<DrcState, DrcEvent> builder = StateMachineBuilder.builder();
|
||
configureDrcStateMachine(builder, strategy);
|
||
configureDrcStates(builder);
|
||
configureDrcTransitions(builder, strategy);
|
||
|
||
StateMachine<DrcState, DrcEvent> stateMachine = builder.build();
|
||
stateMachine.getExtendedState().getVariables().put("machineId", machineId);
|
||
return stateMachine;
|
||
} catch (Exception e) {
|
||
throw new RuntimeException("Failed to create DRC state machine for: " + machineId, e);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public StateMachine<DrcState, DrcEvent> getStateMachine(UUID uuid) {
|
||
return null;
|
||
}
|
||
};
|
||
}
|
||
|
||
private void configureDrcStateMachine(
|
||
StateMachineBuilder.Builder<DrcState, DrcEvent> builder,
|
||
DrcPlatformStrategy strategy) throws Exception {
|
||
builder.configureConfiguration()
|
||
.withConfiguration()
|
||
.autoStartup(true)
|
||
.listener(strategy.getListener());
|
||
}
|
||
|
||
private void configureDrcStates(StateMachineBuilder.Builder<DrcState, DrcEvent> builder) throws Exception {
|
||
builder.configureStates()
|
||
.withStates()
|
||
.initial(DrcState.UNKNOWN)
|
||
.states(EnumSet.allOf(DrcState.class));
|
||
}
|
||
|
||
private void configureDrcTransitions(
|
||
StateMachineBuilder.Builder<DrcState, DrcEvent> builder,
|
||
DrcPlatformStrategy strategy) throws Exception {
|
||
builder.configureTransitions()
|
||
// ========== 从 UNKNOWN 到所有状态的转换(服务器重启后状态同步) ==========
|
||
// UNKNOWN -> EXITED
|
||
.withExternal()
|
||
.source(DrcState.UNKNOWN)
|
||
.target(DrcState.EXITED)
|
||
.event(DrcEvent.EXITED)
|
||
.and()
|
||
|
||
// UNKNOWN -> ENTERING
|
||
.withExternal()
|
||
.source(DrcState.UNKNOWN)
|
||
.target(DrcState.ENTERING)
|
||
.event(DrcEvent.ENTER)
|
||
.and()
|
||
|
||
// UNKNOWN -> ENTERED
|
||
.withExternal()
|
||
.source(DrcState.UNKNOWN)
|
||
.target(DrcState.ENTERED)
|
||
.event(DrcEvent.ENTERED)
|
||
.and()
|
||
|
||
// UNKNOWN -> EXITING
|
||
.withExternal()
|
||
.source(DrcState.UNKNOWN)
|
||
.target(DrcState.EXITING)
|
||
.event(DrcEvent.EXIT)
|
||
.and()
|
||
|
||
// ========== 正常状态转换(带 Guard 和 Action) ==========
|
||
// EXITED -> ENTERING
|
||
.withExternal()
|
||
.source(DrcState.EXITED)
|
||
.target(DrcState.ENTERING)
|
||
.event(DrcEvent.ENTER)
|
||
.action(strategy.getEnterAction())
|
||
.guard(strategy.getCanEnterGuard())
|
||
.and()
|
||
|
||
// ENTERING -> ENTERED
|
||
.withExternal()
|
||
.source(DrcState.ENTERING)
|
||
.target(DrcState.ENTERED)
|
||
.event(DrcEvent.ENTERED)
|
||
.action(strategy.getEnteredAction())
|
||
.and()
|
||
|
||
// ENTERED -> EXITING
|
||
.withExternal()
|
||
.source(DrcState.ENTERED)
|
||
.target(DrcState.EXITING)
|
||
.event(DrcEvent.EXIT)
|
||
.action(strategy.getExitAction())
|
||
.guard(strategy.getCanExitGuard())
|
||
.and()
|
||
|
||
// EXITING -> EXITED
|
||
.withExternal()
|
||
.source(DrcState.EXITING)
|
||
.target(DrcState.EXITED)
|
||
.event(DrcEvent.EXITED)
|
||
.action(strategy.getExitedAction());
|
||
}
|
||
}
|