export default class FiniteStateMachine { private currentState: S | null = null; /** 状态 -> 处于该状态的总时长 */ private stateToTime = new Map(); /** 前一次结算总时长的时间戳 */ private lastTimeStamp = 0; /** 初始化状态 */ init(states: S[], initState?: S) { states.forEach((state) => { this.stateToTime.set(state, 0); }); if (initState !== undefined) { this.lastTimeStamp = Date.now(); this.currentState = initState; } } getCurrent() { return this.currentState; } /** 切换状态 */ switchTo(state: S) { if (!this.stateToTime.has(state)) { console.error(`the state: ${state} has not been registered!`); return; } if (this.currentState === state) { return; } const time = Date.now(); const period = time - this.lastTimeStamp; if (this.currentState !== null) { const passTime = this.stateToTime.get(this.currentState) || 0; this.stateToTime.set(this.currentState, period + passTime); } this.currentState = state; this.lastTimeStamp = time; } /** 立刻结算某个状态的时长 */ updateTime(state: S) { if (!this.stateToTime.has(state)) { console.error(`the state: ${state} has not been registered!`); return; } if (this.currentState !== state) { return; } const time = Date.now(); const period = time - this.lastTimeStamp; const passTime = this.stateToTime.get(this.currentState) || 0; this.stateToTime.set(this.currentState, period + passTime); this.lastTimeStamp = time; } /** 将某个状态的时长清零 */ resetTime(state: S) { if (!this.stateToTime.has(state)) { console.error(`the state: ${state} has not been registered!`); return; } this.stateToTime.set(state, 0); } /** 获取处于某状态的总时长 * @param immediate 是否立即结算 */ getTime(state: S, immediate = false) { if (immediate) this.updateTime(state); return this.stateToTime.get(state) ?? 0; } }