简单轻量状态机

KeyState 状态类

namespace FSM
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Threading.Tasks;

    /// <summary>
    /// 关键字状态机
    /// </summary>
    public class KeyState : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        /// <summary>
        /// 属性改变时触发
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 触发属性改变通知方法
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        /// <summary>
        /// 子状态名称拼接符
        /// </summary>
        public const Char ChildSplitChar = '\\';

        /// <summary>
        /// 状态名
        /// </summary>
        private string _Name;
        /// <summary>
        /// 状态名称
        /// </summary>
        protected string Name
        {
            get => _Name; set
            {
                if (value.Contains(ChildSplitChar))
                {
                    throw new Exception($"StateName不能包含‘{ChildSplitChar}’符号");
                }
                if (_Name != value)
                {
                    _Name = value;
                }
            }
        }
        /// <summary>
        /// 状态方法
        /// </summary>
        protected Action<Object> ChangeStateAction { get; private set; }
        /// <summary>
        /// 子状态
        /// </summary>
        protected Dictionary<string, KeyState> ChildStates { get; private set; } = new Dictionary<string, KeyState>();
        /// <summary>
        /// 获取子状态索引
        /// </summary>
        /// <param name="StateNamePath"></param>
        /// <returns></returns>
        protected KeyState this[string StateNamePath]
        {
            get
            {
                KeyState state = null;
                if (StateNamePath == Name) state = this;
                else if (ChildStates.ContainsKey(StateNamePath)) state = ChildStates[StateNamePath];
                else if (StateNamePath.Contains(ChildSplitChar))
                {
                    var stateNames = StateNamePath.Split(ChildSplitChar);
                    var childNames = stateNames.Skip(1).ToArray();
                    KeyState _state = this;
                    string _stateName = null;
                    for (int i = 0; i < childNames.Length; i++)
                    {
                        _stateName = childNames[i];
                        if (_state.ChildStates.ContainsKey(_stateName))
                        {
                            var temp = _state[_stateName];
                            _state = temp;
                        }
                        else
                        {
                            _state = null;
                            break;
                        }
                    }
                    state = _state;
                }
                if (state == null)
                    throw new Exception($"$找不到{StateNamePath}指定的状态");
                return state;
            }
        }
        /// <summary>
        /// 状态数据上下文
        /// </summary>
        public object CurrentContext { get; set; }

        protected KeyState() { }
        /// <summary>
        /// 创建状态机
        /// </summary>
        /// <param name="StateName"></param>
        /// <param name="ChangeStateAction"></param>
        public KeyState(string StateName, Action<object> ChangeStateAction)
        {
            this.Name = StateName;
            this.ChangeStateAction = ChangeStateAction;
        }
        /// <summary>
        /// 创建带多个子状态的状态机
        /// </summary>
        /// <param name="StateName"></param>
        /// <param name="ChildStates"></param>
        public KeyState(string StateName, params KeyState[] ChildStates)
        {
            this.Name = StateName;
            foreach (var state in ChildStates)
            {
                AddState(state);
            }
        }
        /// <summary>
        /// 添加多个子状态机
        /// </summary>
        /// <param name="MultiStates"></param>
        public virtual void AddState(params KeyState[] MultiStates)
        {
            foreach (var state in MultiStates)
            {
                this.AddState(state);
            }
        }
        /// <summary>
        /// 添加一个子状态机
        /// </summary>
        /// <param name="State"></param>
        public virtual void AddState(KeyState State)
        {
            if (ChildStates.ContainsKey(State.Name))
                throw new Exception($"已经添加了{State.Name}状态");
            ChildStates.Add(State.Name, State);
        }
        /// <summary>
        /// 添加一个子状态机
        /// </summary>
        /// <param name="StateName"></param>
        /// <param name="ChangeStateAction"></param>
        public virtual void AddState(string StateName, Action<Object> ChangeStateAction) => AddState(new KeyState(StateName, ChangeStateAction));
        /// <summary>
        /// 执行状态机改变方法
        /// </summary>
        /// <param name="Context"></param>
        public virtual void OnChangeState(object Context)
        {
            if (this.CurrentContext != Context)
                this.CurrentContext = Context;
            this.ChangeStateAction?.Invoke(this.CurrentContext);
        }
    }
}

KeyFSM 状态管理类

namespace FSM
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    /// <summary>
    /// 基于Key模式的有限状态机 FiniteStateMachine
    /// </summary>
    public class KeyFSM : KeyState
    {
        /// <summary>
        /// 创建有序状态机  基于Key模式的有限状态机 FiniteStateMachine
        /// </summary>
        public KeyFSM()
        {

        }
        /// <summary>
        /// 上一个状态机完整名称
        /// </summary>
        public string LastState { get; set; }
        /// <summary>
        /// 当前状态机完整名称
        /// </summary>
        private new string Name;
        /// <summary>
        /// 当前状态机完整名称
        /// </summary>
        public string CurrentState
        {
            get => this.Name; protected set
            {
                if (this.Name != value)
                {
                    this.LastState = this.Name;
                    this.Name = value;

                    this.NotifyPropertyChanged(nameof(LastState));
                    this.NotifyPropertyChanged(nameof(CurrentState));
                }
            }
        }
        /// <summary>
        /// 初始化状态机
        /// </summary>
        /// <param name="StateName"></param>
        /// <param name="Context"></param>
        public void InitState(string StateName, Object Context = null)
        {
            if (this.CurrentState != null)
                throw new Exception($"已经初始化了状态,不能重复初始化,当前状态:{CurrentState}");
            else
            {
                var state = this[StateName];
                state.OnChangeState(Context);
                this.CurrentState = StateName;
            }
        }
        /// <summary>
        /// 更改状态
        /// </summary>
        /// <param name="StateName"></param>
        /// <param name="Context"></param>
        public void ChangeState(string StateName, Object Context = null)
        {
            var state = this[StateName];
            this.CurrentState = StateName;
            state.OnChangeState(Context);
        }
        /// <summary>
        /// 更改状态,更改失败时回退状态
        /// </summary>
        /// <param name="BackStateName">回退状态</param>
        /// <param name="NewStateName">更改状态</param>
        /// <param name="Context">数据上下文</param>
        /// <returns>null执行成功,执行失败,返回异常内容</returns>
        public Exception ChangeState(string BackStateName, string NewStateName, Object Context = null)
        {
            Exception error = null;
            try
            {
                var state = this[NewStateName];
                state.OnChangeState(Context);
                this.CurrentState = NewStateName;
            }
            catch (Exception exc)
            {
                var state = this[BackStateName];
                state.OnChangeState(state.CurrentContext);
                error = exc;
            }
            return error;
        }
        /// <summary>
        /// 更改失败时回退状态
        /// </summary>
        /// <param name="BackStateName">回退状态</param>
        /// <param name="NewStateName">更改状态</param>
        /// <param name="exception">执行失败,返回异常内容</param>
        /// <param name="Context">数据上下文</param>
        /// <returns>true执行成功,false执行失败</returns>
        public Boolean ChangeState(string BackStateName, string NewStateName, out Exception exception, Object Context = null)
        {
            exception = ChangeState(BackStateName, NewStateName, Context);
            return exception == null;
        }
        /// <summary>
        /// 调用该方法,无效
        /// </summary>
        /// <param name="Context"></param>
        [Obsolete("调用该方法,无效", true)]
        public override void OnChangeState(object Context) { }
    }
}

发布了13 篇原创文章 · 获赞 3 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览