有限状态机
2020-09-21 本文已影响0人
洒一地阳光_217d
状态机,控制各个状态。
1、各个状态内部,返回要跳转的下一个状态,状态机会自动切换状态;
2、也可以外部调用状态机,手动切换状态;
各个状态接口:
/// <summary>
/// 状态
/// </summary>
public interface IState<TData>
{
/// <summary>
/// 当前状态是否已经开始
/// </summary>
bool Started { get; }
/// <summary>
/// 状态名字
/// </summary>
string StateName { get; }
/// <summary>
/// 初始化状态
/// </summary>
/// <param name="data"></param>
void Initialize(TData data);
/// <summary>
/// 检查
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
bool Check(TData data);
/// <summary>
/// 返回下一个状态
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
string Finish(TData data);
/// <summary>
/// 重置
/// </summary>
void Reset();
/// <summary>
/// 被中断
/// </summary>
void Abort();
}
状态机:
using System.Collections.Generic;
/// <summary>
/// 状态机对象
/// </summary>
public class StateMachine<TData>
{
/// <summary>
/// 当前状态
/// </summary>
public string CurStateName
{
get
{
if (curState != null)
{
return curState.StateName;
}
return null;
}
}
private bool running = false;
private IState<TData> curState; // 当前状态
private readonly TData data;
// 所有状态集合
private readonly Dictionary<string, IState<TData>> states = new Dictionary<string, IState<TData>>();
public StateMachine(TData data)
{
this.data = data;
}
/// <summary>
/// 添加状态
/// </summary>
/// <param name="state"></param>
public void AddState(IState<TData> state)
{
if (state == null)
{
return;
}
string stateName = state.StateName;
if (states.ContainsKey(stateName))
{
states[stateName] = state;
}
else
{
states.Add(stateName, state);
}
}
/// <summary>
/// 开始执行状态机逻辑
/// </summary>
/// <param name="firstState">第一个状态</param>
public void Start(string firstState)
{
running = true;
if (!string.IsNullOrEmpty(firstState))
{
curState = states[firstState];
}
}
/// <summary>
/// 刷新状态机逻辑,自动切换状态
/// </summary>
public void Update()
{
if (!running)
{
return;
}
if (curState == null)
{
return;
}
if (!curState.Started)
{
curState.Initialize(data);
}
if (curState.Check(data))
{
string nextStateName = curState.Finish(data);
curState = states[nextStateName];
}
}
/// <summary>
/// 停止状态机
/// </summary>
public void Stop()
{
running = false;
}
/// <summary>
/// 停止状态机并重置
/// </summary>
public void StopAndReset()
{
running = false;
curState = null;
foreach (var state in states.Values)
{
state.Reset();
}
}
/// <summary>
/// 切换状态
/// </summary>
/// <param name="stateName"></param>
public void SwitchTo(string stateName)
{
if (curState != null && curState.StateName != stateName)
{
curState.Abort();
}
curState = states[stateName];
}
}