export class StateMachine { private _states: Map = new Map(); private currentState: State; constructor(states: State[]) { this.currentState = states[0]; } update(dt: number) { this.currentState.update(dt); } get current() { return this.currentState; } get states() { return this._states; } addState(state: State) { this.states.set(state.name, state); } transitionTo(state: State) { if (this.current.canTransitionTo(state)) { this.current.stop(); this.currentState = state; this.current.start(); } } } export abstract class State { private stateMachine: StateMachine; protected abstract validTransitions: Set; abstract readonly name: T; constructor( stateMachine: StateMachine, ) { this.stateMachine = stateMachine; } abstract update(dt: number): void; abstract start(): void; abstract stop(): void; canTransitionTo(state: T) { return this.validTransitions.has(state); } }