using System; using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using UnityEngine; namespace Code.Infrastructure.StateMachine { public class AbstractStateMachine where TStateMachineContext : new() { protected AbstractStateMachine(TStateMachineContext stateMachineContext) { StateMachineContext = stateMachineContext; } public TStateEnum CurrentState { get; protected set; } public TStateEnum NextState { get; protected set; } public BaseState CurrentBaseState { get; private set; } private BaseState _previousBaseState; protected Dictionary> States = new(); protected Dictionary 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(); } } } }