# -*- coding: utf-8 -*- """ 装备模型生命周期状态机 ───────────────────────────────────────────────────────────────── LifecycleState 枚举:CREATED / READY / RUNNING / PAUSED / STOPPED / ERROR LifecycleFSM 有限状态机:管理合法状态转移,非法转移抛出异常 ───────────────────────────────────────────────────────────────── """ from __future__ import annotations from enum import Enum from typing import Dict, Set, Callable, Optional # ───────────────────────────────────────────────────────────────── # 生命周期状态枚举 # ───────────────────────────────────────────────────────────────── class LifecycleState(Enum): CREATED = "CREATED" # 刚创建,参数未就绪 READY = "READY" # 参数就绪,可启动 RUNNING = "RUNNING" # 仿真运行中 PAUSED = "PAUSED" # 暂停(可恢复) STOPPED = "STOPPED" # 已停止(不可恢复,需 reset) ERROR = "ERROR" # 发生错误 # ───────────────────────────────────────────────────────────────── # 合法状态转移表 # ───────────────────────────────────────────────────────────────── # { 当前状态 → 可转移到的目标状态集合 } _TRANSITIONS: Dict[LifecycleState, Set[LifecycleState]] = { LifecycleState.CREATED: { LifecycleState.READY, LifecycleState.ERROR, }, LifecycleState.READY: { LifecycleState.RUNNING, LifecycleState.ERROR, }, LifecycleState.RUNNING: { LifecycleState.PAUSED, LifecycleState.STOPPED, LifecycleState.ERROR, LifecycleState.READY, # reset 时 }, LifecycleState.PAUSED: { LifecycleState.RUNNING, LifecycleState.STOPPED, LifecycleState.ERROR, LifecycleState.READY, # reset 时 }, LifecycleState.STOPPED: { LifecycleState.READY, # reset 后可重新启动 LifecycleState.ERROR, }, LifecycleState.ERROR: { LifecycleState.READY, # 错误恢复后 reset }, } # ───────────────────────────────────────────────────────────────── # 生命周期有限状态机 # ───────────────────────────────────────────────────────────────── class LifecycleFSM: """ 装备模型生命周期有限状态机 职责: - 维护当前状态 - 校验状态转移合法性 - 触发转移回调(on_enter / on_exit) - 记录状态历史 """ def __init__( self, initial: LifecycleState = LifecycleState.CREATED, on_changed: Optional[Callable[[str, str], None]] = None, ): self._state: LifecycleState = initial self._history: list = [(initial, 0.0)] self._on_changed = on_changed # (old, new) 回调 # ── 属性 ────────────────────────────────────────────────────── @property def state(self) -> LifecycleState: return self._state @property def history(self) -> list: return list(self._history) # ── 状态查询 ────────────────────────────────────────────────── @property def is_running(self) -> bool: return self._state == LifecycleState.RUNNING @property def is_paused(self) -> bool: return self._state == LifecycleState.PAUSED @property def is_stopped(self) -> bool: return self._state == LifecycleState.STOPPED @property def is_ready(self) -> bool: return self._state == LifecycleState.READY @property def is_error(self) -> bool: return self._state == LifecycleState.ERROR @property def can_step(self) -> bool: """是否可以执行 step()""" return self._state == LifecycleState.RUNNING # ── 状态转移 ────────────────────────────────────────────────── def transition( self, target: LifecycleState, timestamp: float = 0.0, force: bool = False, ) -> bool: """ 执行状态转移 :param target: 目标状态 :param timestamp: 当前仿真时刻(用于历史记录) :param force: True=强制转移(跳过合法性检查,仅内部使用) :return: True=转移成功,False=已在目标状态 :raises ValueError: 非法状态转移 """ if self._state == target: return False if not force: allowed = _TRANSITIONS.get(self._state, set()) if target not in allowed: raise ValueError( f"非法状态转移: {self._state.value} → {target.value} " f"(允许: {[s.value for s in allowed]})" ) old_state = self._state self._state = target self._history.append((target, timestamp)) if self._on_changed: self._on_changed(old_state.value, target.value) return True # ── 快捷转移方法 ────────────────────────────────────────────── def to_ready(self, t: float = 0.0) -> bool: return self.transition(LifecycleState.READY, t) def to_running(self, t: float = 0.0) -> bool: return self.transition(LifecycleState.RUNNING, t) def to_paused(self, t: float = 0.0) -> bool: return self.transition(LifecycleState.PAUSED, t) def to_stopped(self, t: float = 0.0) -> bool: return self.transition(LifecycleState.STOPPED, t) def to_error(self, t: float = 0.0) -> bool: return self.transition(LifecycleState.ERROR, t, force=True) # ── 工具 ────────────────────────────────────────────────────── def reset(self, t: float = 0.0) -> bool: """强制重置到 READY(任意状态均可)""" return self.transition(LifecycleState.READY, t, force=True) def __repr__(self) -> str: return f"LifecycleFSM(state={self._state.value})"