mirror of
https://github.com/Bragin-Stepan/project-entity.git
synced 2026-03-02 14:29:23 +00:00
97 lines
2.6 KiB
C#
97 lines
2.6 KiB
C#
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<TState> : State, IDisposable, IUpdatableState where TState : class, IState
|
|
{
|
|
private List<StateNode<TState>> _states = new();
|
|
|
|
private StateNode<TState> _currentState;
|
|
|
|
private bool _isRunning;
|
|
|
|
private List<IDisposable> _disposables;
|
|
|
|
protected StateMachine(List<IDisposable> disposables)
|
|
{
|
|
_disposables = new List<IDisposable>(disposables);
|
|
}
|
|
|
|
protected TState CurrentState => _currentState.State;
|
|
|
|
public void AddState(TState state) => _states.Add(new StateNode<TState>(state));
|
|
|
|
public void AddTransition(TState fromState, TState toState, ICondition condition)
|
|
{
|
|
StateNode<TState> from = _states.First(stateNode => stateNode.State == fromState);
|
|
StateNode<TState> to = _states.First(stateNode => stateNode.State == toState);
|
|
|
|
from.AddTransition(new StateTransition<TState>(to, condition));
|
|
}
|
|
|
|
public void Update(float deltaTime)
|
|
{
|
|
if (_isRunning == false)
|
|
return;
|
|
|
|
foreach (StateTransition<TState> 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<TState> 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<TState> nextState)
|
|
{
|
|
_currentState?.State.Exit();
|
|
_currentState = nextState;
|
|
_currentState.State.Enter();
|
|
}
|
|
}
|
|
}
|