有限状态机

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];
    }
}

上一篇 下一篇

猜你喜欢

热点阅读