143 lines
3.7 KiB
C#
143 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Unity.VisualScripting;
|
|
|
|
namespace NBC
|
|
{
|
|
public class Fsm<TOwnerClass>
|
|
{
|
|
private FsmBaseState<TOwnerClass> _currentState;
|
|
|
|
private Dictionary<uint, FsmBaseState<TOwnerClass>> _states = new Dictionary<uint, FsmBaseState<TOwnerClass>>();
|
|
|
|
private Dictionary<Type, uint> _stateType2Id = new Dictionary<Type, uint>();
|
|
|
|
private bool _doDebugOutput;
|
|
|
|
private TOwnerClass _owner;
|
|
|
|
private string _description;
|
|
|
|
|
|
public uint CurrentStateId => _currentState.StateId;
|
|
|
|
public FsmBaseState<TOwnerClass> CurrentState => _currentState;
|
|
|
|
public Fsm(string description, TOwnerClass owner, bool debugOutput = false)
|
|
{
|
|
_description = description;
|
|
_owner = owner;
|
|
_doDebugOutput = debugOutput;
|
|
}
|
|
|
|
public void RegisterState<T>() where T : FsmBaseState<TOwnerClass>, new()
|
|
{
|
|
var type = typeof(T);
|
|
if (_stateType2Id.ContainsKey(type))
|
|
{
|
|
LogError("State {0} already registered", type);
|
|
return;
|
|
}
|
|
|
|
T result = new T();
|
|
_stateType2Id[type] = result.StateId;
|
|
_states[result.StateId] = result;
|
|
result.Init(_owner, this);
|
|
}
|
|
|
|
public void Start<T>() where T : FsmBaseState<TOwnerClass>, new()
|
|
{
|
|
Log("start");
|
|
EnterState(typeof(T));
|
|
}
|
|
|
|
public void EnterState(Type type, FsmBaseState<TOwnerClass> sourceState = null)
|
|
{
|
|
if (_stateType2Id.TryGetValue(type, out var id))
|
|
{
|
|
EnterState(id, sourceState);
|
|
}
|
|
}
|
|
|
|
public void EnterState(uint stateId, FsmBaseState<TOwnerClass> sourceState = null)
|
|
{
|
|
uint prevState = 0;
|
|
FsmTransmit param = null;
|
|
if (_currentState != null)
|
|
{
|
|
prevState = _currentState.StateId;
|
|
param = _currentState.Params;
|
|
_currentState.Exit();
|
|
}
|
|
|
|
_currentState = _states[stateId];
|
|
_currentState.PrevState = prevState;
|
|
if (param != null)
|
|
{
|
|
_currentState.Params.AddRange(param);
|
|
param.Clear();
|
|
}
|
|
|
|
if (sourceState != null)
|
|
{
|
|
_currentState.Transition(sourceState);
|
|
}
|
|
else
|
|
{
|
|
_currentState.Enter();
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (_currentState != null)
|
|
{
|
|
_currentState.PreUpdate();
|
|
var type = _currentState.Update();
|
|
if (type != 0)
|
|
{
|
|
_currentState.NextState = type;
|
|
EnterState(type);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void FixedUpdate()
|
|
{
|
|
if (_currentState != null)
|
|
{
|
|
var type = _currentState.FixedUpdate();
|
|
if (type != 0)
|
|
{
|
|
_currentState.NextState = type;
|
|
EnterState(type);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void LateUpdate()
|
|
{
|
|
if (_currentState != null)
|
|
{
|
|
var type = _currentState.LateUpdate();
|
|
if (type != 0)
|
|
{
|
|
_currentState.NextState = type;
|
|
EnterState(type);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void LogError(string textPattern, params object[] args)
|
|
{
|
|
}
|
|
|
|
public void Log(string text)
|
|
{
|
|
if (!_doDebugOutput)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
} |