using System; using System.Collections.Generic; using System.Linq; using _Project.Develop.Runtime.Utilities.Conditions; namespace Assets._Project.Develop.Runtime.Utilities.StateMachineCore { public abstract class StateMachine : State, IDisposable, IUpdatableState where TState : class, IState { private List> _states = new(); private StateNode _currentState; private bool _isRunning; private List _disposables; protected StateMachine(List disposables) { _disposables = new List(disposables); } protected TState CurrentState => _currentState.State; public void AddState(TState state) => _states.Add(new StateNode(state)); public void AddTransition(TState fromState, TState toState, ICondition condition) { StateNode from = _states.First(stateNode => stateNode.State == fromState); StateNode to = _states.First(stateNode => stateNode.State == toState); from.AddTransition(new StateTransition(to, condition)); } public void Update(float deltaTime) { if (_isRunning == false) return; foreach (StateTransition transition in _currentState.Transitions) { if (transition.Condition.Evaluate()) { SwitchState(transition.ToState); break; } } UpdateLogic(deltaTime); } protected virtual void UpdateLogic(float deltaTime) { } public void Dispose() { _isRunning = false; foreach (StateNode stateNode in _states) if (stateNode.State is IDisposable disposableState) disposableState.Dispose(); _states.Clear(); foreach (IDisposable disposable in _disposables) disposable.Dispose(); _disposables.Clear(); } public override void Enter() { base.Enter(); if (_currentState == null) SwitchState(_states[0]); _isRunning = true; } public override void Exit() { base.Exit(); _currentState?.State.Exit(); _isRunning = false; } private void SwitchState(StateNode nextState) { _currentState?.State.Exit(); _currentState = nextState; _currentState.State.Enter(); } } }