using System; using System.Collections; using System.Collections.Generic; namespace UniFramework.Machine { public class StateMachine { private readonly Dictionary _nodes = new Dictionary(100); private IStateNode _curNode; private IStateNode _preNode; /// /// 状态机持有者 /// public System.Object Owner { private set; get; } /// /// 当前运行的节点名称 /// public string CurrentNode { get { return _curNode != null ? _curNode.GetType().FullName : string.Empty; } } /// /// 之前运行的节点名称 /// public string PreviousNode { get { return _preNode != null ? _preNode.GetType().FullName : string.Empty; } } private StateMachine() { } public StateMachine(System.Object owner) { Owner = owner; } /// /// 更新状态机 /// public void Update() { if (_curNode != null) _curNode.OnUpdate(); } /// /// 启动状态机 /// public void Run() where TNode : IStateNode { var nodeType = typeof(TNode); var nodeName = nodeType.FullName; Run(nodeName); } public void Run(Type entryNode) { var nodeName = entryNode.FullName; Run(nodeName); } public void Run(string entryNode) { _curNode = TryGetNode(entryNode); _preNode = _curNode; if (_curNode == null) throw new Exception($"Not found entry node: {entryNode }"); _curNode.OnEnter(); } /// /// 加入一个节点 /// public void AddNode() where TNode : IStateNode { var nodeType = typeof(TNode); var stateNode = Activator.CreateInstance(nodeType) as IStateNode; AddNode(stateNode); } public void AddNode(IStateNode stateNode) { if (stateNode == null) throw new ArgumentNullException(); var nodeType = stateNode.GetType(); var nodeName = nodeType.FullName; if (_nodes.ContainsKey(nodeName) == false) { stateNode.OnCreate(this); _nodes.Add(nodeName, stateNode); } else { UniLogger.Error($"State node already existed : {nodeName}"); } } /// /// 转换状态节点 /// public void ChangeState() where TNode : IStateNode { var nodeType = typeof(TNode); var nodeName = nodeType.FullName; ChangeState(nodeName); } public void ChangeState(Type nodeType) { var nodeName = nodeType.FullName; ChangeState(nodeName); } public void ChangeState(string nodeName) { if (string.IsNullOrEmpty(nodeName)) throw new ArgumentNullException(); IStateNode node = TryGetNode(nodeName); if (node == null) { UniLogger.Error($"Can not found state node : {nodeName}"); return; } UniLogger.Log($"{_curNode.GetType().FullName} --> {node.GetType().FullName}"); _preNode = _curNode; _curNode.OnExit(); _curNode = node; _curNode.OnEnter(); } private IStateNode TryGetNode(string nodeName) { _nodes.TryGetValue(nodeName, out IStateNode result); return result; } } }