using System; using System.Collections.Generic; using Code.Infrastructure.EventBus; namespace Code.Infrastructure.StateMachine { public abstract class AbstractStateMachine where TStateMachineContext : new() { protected AbstractStateMachine(TStateMachineContext stateMachineContext ) { StateMachineContext = stateMachineContext; } public TStateEnum CurrentState { get; protected set; } public BaseState CurrentBaseState { get; private set; } private BaseState _previousBaseState; protected Dictionary> States = new(); protected Dictionary StatesTypes = new(); public TStateEnum AllowedStates { get; set; } protected TStateMachineContext StateMachineContext { get; } // Костыли 2 шт. для флагового енама в шаблонах protected abstract bool CheckTransitionAllowed(TStateEnum nextState); protected abstract void ResetAllowedTransitions(); // TODO Если в EnterState вызывается ExitState, то будет гарантированная поломка public AbstractStateMachine SwitchState(TStateEnum nextState) { if (!CheckTransitionAllowed(nextState) && CurrentBaseState != null) { return null; } ResetAllowedTransitions(); _previousBaseState = CurrentBaseState; CurrentBaseState = States[nextState]; _previousBaseState?.ExitState(); CurrentBaseState.EnterState(); CurrentState = nextState; return this; } } public interface IEnterStateHandle : IGlobalSubscriber { void EnterState(); } public interface IExitStateHandle : IGlobalSubscriber { void ExitState(); } }