NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/Fsm/NStateMachine.cs

142 lines
3.4 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace LTGame
{
public class NStateMachine<T> where T : NBaseState
{
private Dictionary<int, T> _state;
public NStateMachine()
{
_state = new Dictionary<int, T>();
}
public T currentState { get; private set; }
public T lastState { get; private set; }
private int _forceChangeStateId = 0;
private object _forceChangeParam = null;
public bool Add(T state)
{
if (_state.ContainsKey(state.id))
{
return false;
}
_state.Add(state.id, state);
return true;
}
public bool Remove(int id)
{
return _state.Remove(id);
}
public T Find(int id)
{
if (_state.TryGetValue(id, out T find))
{
return find;
}
return null;
}
public bool ChangeState(int id,
object param = null)
{
var state = Find(id);
if (state == null)
{
DebugUtil.LogError("NStateMachine.ChangeState: {0} not found", id);
return false;
}
var canChange = true;
if (null != currentState)
{
if (currentState.id == state.id && !state.canReEnter)
{
canChange = false;
}
}
if (!canChange)
{
return false;
}
if (null != currentState)
{
currentState.Exit(state, param);
}
lastState = currentState;
currentState = state;
state.Enter(lastState, param);
return true;
}
public void SetForceChangeState(int id,
object param = null)
{
_forceChangeStateId = id;
_forceChangeParam = param;
}
public void LogicUpdate(float dt)
{
if (currentState == null)
{
if (_forceChangeStateId != 0)
{
ChangeState(_forceChangeStateId, _forceChangeParam);
_forceChangeStateId = 0;
_forceChangeParam = null;
OnRunning(dt);
}
return;
}
if (_forceChangeStateId != 0)
{
if (_forceChangeStateId == currentState.id)
{
if (currentState.canReEnter)
{
ChangeState(_forceChangeStateId, _forceChangeParam);
}
}
else
{
ChangeState(_forceChangeStateId, _forceChangeParam);
}
_forceChangeStateId = 0;
_forceChangeParam = null;
OnRunning(dt);
return;
}
var nextState = currentState.GetNextState();
if (nextState != 0)
{
ChangeState(nextState);
}
OnRunning(dt);
}
public void OnRunning(float dt)
{
if (null == currentState)
{
return;
}
currentState.Run(dt);
}
}
}