55 lines
1.7 KiB
C#
55 lines
1.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
|
|
namespace Code.Infrastructure.StateMachine
|
|
{
|
|
public class AbstractStateMachine<TStateEnum, TStateMachineContext>
|
|
where TStateMachineContext : new()
|
|
{
|
|
protected AbstractStateMachine(TStateMachineContext stateMachineContext)
|
|
{
|
|
StateMachineContext = stateMachineContext;
|
|
}
|
|
|
|
public TStateEnum CurrentState { get; protected set; }
|
|
public TStateEnum NextState { 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();
|
|
protected TStateMachineContext StateMachineContext { get; }
|
|
|
|
private readonly SemaphoreSlim _stateLock = new (1, 1);
|
|
|
|
public async UniTask SwitchState(TStateEnum nextState)
|
|
{
|
|
await _stateLock.WaitAsync();
|
|
|
|
try
|
|
{
|
|
NextState = nextState;
|
|
|
|
if (CurrentBaseState != null) await CurrentBaseState.ExitState();
|
|
|
|
var newState = States[nextState];
|
|
await newState.EnterState();
|
|
|
|
Debug.Log($"Switched from {CurrentState} to {nextState}");
|
|
|
|
CurrentBaseState = newState;
|
|
CurrentState = nextState;
|
|
NextState = default;
|
|
|
|
// Logger
|
|
}
|
|
finally
|
|
{
|
|
_stateLock.Release();
|
|
}
|
|
}
|
|
}
|
|
} |