Files
MojSadUnity/Assets/Code/Infrastructure/StateMachine/AbstractStateMachine.cs
T
2026-02-26 11:21:27 +03:00

62 lines
2.1 KiB
C#

using System;
using System.Collections.Generic;
using Code.Infrastructure.EventBus;
namespace Code.Infrastructure.StateMachine
{
public abstract class AbstractStateMachine<TStateEnum, TStateMachineContext>
where TStateMachineContext : new()
{
protected AbstractStateMachine(TStateMachineContext stateMachineContext )
{
StateMachineContext = stateMachineContext;
}
public TStateEnum CurrentState { get; protected set; }
public BaseState<TStateEnum, TStateMachineContext> CurrentBaseState { get; private set; }
private BaseState<TStateEnum, TStateMachineContext> _previousBaseState;
protected Dictionary<TStateEnum, BaseState<TStateEnum, TStateMachineContext>> States = new();
protected Dictionary<TStateEnum, Type> 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<TStateEnum, TStateMachineContext> 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<TState> : IGlobalSubscriber
{
void EnterState();
}
public interface IExitStateHandle<TState> : IGlobalSubscriber
{
void ExitState();
}
}