| 52 | * @en State machine implementation |
| 53 | */ |
| 54 | export class StateMachine<TState extends string = string, TContext = unknown> |
| 55 | implements IStateMachine<TState, TContext> |
| 56 | { |
| 57 | private _current: TState; |
| 58 | private _previous: TState | null = null; |
| 59 | private _context: TContext; |
| 60 | private _isTransitioning = false; |
| 61 | private _stateStartTime = 0; |
| 62 | |
| 63 | private states: Map<TState, StateConfig<TState, TContext>> = new Map(); |
| 64 | private transitions: Map<TState, TransitionConfig<TState, TContext>[]> = new Map(); |
| 65 | |
| 66 | private enterListeners: Map<TState, Set<(from: TState | null) => void>> = new Map(); |
| 67 | private exitListeners: Map<TState, Set<(to: TState) => void>> = new Map(); |
| 68 | private changeListeners: Set<StateChangeListener<TState>> = new Set(); |
| 69 | |
| 70 | private history: StateChangeEvent<TState>[] = []; |
| 71 | private maxHistorySize: number; |
| 72 | private enableHistory: boolean; |
| 73 | |
| 74 | constructor(initialState: TState, options: StateMachineOptions<TContext> = {}) { |
| 75 | this._current = initialState; |
| 76 | this._context = (options.context ?? {}) as TContext; |
| 77 | this.maxHistorySize = options.maxHistorySize ?? 100; |
| 78 | this.enableHistory = options.enableHistory ?? true; |
| 79 | this._stateStartTime = Date.now(); |
| 80 | |
| 81 | // Auto-define initial state if not defined |
| 82 | this.defineState(initialState); |
| 83 | } |
| 84 | |
| 85 | // ========================================================================= |
| 86 | // 属性 | Properties |
| 87 | // ========================================================================= |
| 88 | |
| 89 | get current(): TState { |
| 90 | return this._current; |
| 91 | } |
| 92 | |
| 93 | get previous(): TState | null { |
| 94 | return this._previous; |
| 95 | } |
| 96 | |
| 97 | get context(): TContext { |
| 98 | return this._context; |
| 99 | } |
| 100 | |
| 101 | get isTransitioning(): boolean { |
| 102 | return this._isTransitioning; |
| 103 | } |
| 104 | |
| 105 | get currentStateDuration(): number { |
| 106 | return Date.now() - this._stateStartTime; |
| 107 | } |
| 108 | |
| 109 | // ========================================================================= |
| 110 | // 状态定义 | State Definition |
| 111 | // ========================================================================= |
nothing calls this directly
no outgoing calls
no test coverage detected