62 lines
2.1 KiB
C#
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();
|
|
}
|
|
} |