using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Reflection; /// /// 状态接口 /// public interface IState { /// /// 状态进入状态栈 /// void OnStateEnter(); /// /// 状态退出状态栈 /// void OnStateLeave(); /// /// 状态由栈顶变成非栈顶 /// void OnStateOverride(); /// /// 状态由非栈顶变成栈顶 /// void OnStateResume(); string name { get; } } public abstract class BaseState : IState { public virtual void OnStateEnter() { } public virtual void OnStateLeave() { } public virtual void OnStateOverride() { } public virtual void OnStateResume() { } public virtual string name { get { return GetType().Name; } } } /// /// 状态机 /// public class StateMachine { // 状态名-已注册的状态 private Dictionary _registedState = new Dictionary(); // 状态堆栈 private Stack _stateStack = new Stack(); public IState tarState { get; private set; } public void RegisterState(string name, IState state) { if (name == null || state == null) { return; } if (_registedState.ContainsKey(name)) { return; } _registedState.Add(name, state); } public ClassEnumerator RegisterStateByAttributes(Assembly InAssembly, params object[] args) where TAttributeType : AutoRegisterAttribute { var Classes = new ClassEnumerator( typeof(TAttributeType), typeof(IState), InAssembly); var Iter = Classes.results.GetEnumerator(); while( Iter.MoveNext() ) { var StateType = Iter.Current; IState StateObj = (IState)System.Activator.CreateInstance(StateType, args); RegisterState(StateObj, StateObj.name); } return Classes; } public ClassEnumerator RegisterStateByAttributes(Assembly InAssembly) where TAttributeType : AutoRegisterAttribute { var Classes = new ClassEnumerator( typeof(TAttributeType), typeof(IState), InAssembly); var Iter = Classes.results.GetEnumerator(); while (Iter.MoveNext()) { var StateType = Iter.Current; IState StateObj = (IState)System.Activator.CreateInstance(StateType); RegisterState(StateObj, StateObj.name); } return Classes; } public void RegisterState(TStateImplType State, string name) where TStateImplType : IState { RegisterState(name, State); } /// /// 注销状态 /// /// 状态名 /// 被注销的状态 public IState UnregisterState(string name) { if (name == null) { return default(IState); } IState state; if (!_registedState.TryGetValue(name, out state)) { return default(IState); } _registedState.Remove(name); return state; } /// /// 获取状态 /// /// 状态名 /// 状态 public IState GetState(string name) { if (null == name) { return default(IState); } IState state; return _registedState.TryGetValue(name, out state) ? state : default(IState); } public string GetStateName(IState state) { if (null == state) { return null; } var etr = _registedState.GetEnumerator(); KeyValuePair pair; while (etr.MoveNext()) { pair = etr.Current; if (pair.Value == state) { return pair.Key; } } return null; } /// /// 压入状态 /// /// 状态 public void Push(IState state) { if (state == null) { return; } if (_stateStack.Count > 0) { _stateStack.Peek().OnStateOverride(); } _stateStack.Push(state); state.OnStateEnter(); } /// /// 压入状态 /// /// 状态名 public void Push(string name) { if (name == null) { return; } IState state; if (!_registedState.TryGetValue(name, out state)) { return; } Push(state); } /// /// 弹出状态 /// /// 被弹出的状态 public IState PopState() { if (_stateStack.Count <= 0) { return default(IState); } IState state = _stateStack.Pop(); state.OnStateLeave(); if (_stateStack.Count > 0) { _stateStack.Peek().OnStateResume(); } return state; } /// /// 修改栈顶状态 /// /// 新栈顶状态 /// 原栈顶状态 public IState ChangeState(IState state) { if (state == null) { return default(IState); } tarState = state; IState oldState = default(IState); if (_stateStack.Count > 0) { oldState = _stateStack.Pop(); oldState.OnStateLeave(); } _stateStack.Push(state); state.OnStateEnter(); return oldState; } /// /// 修改栈顶状态 /// /// 新栈顶状态名 /// 原栈顶状态 public IState ChangeState(string name) { if (name == null) { DebugHelper.LogWarning("没有状态机类型,使用默认类型:"); return default(IState); } IState state; if (!_registedState.TryGetValue(name, out state)) { DebugHelper.LogError("找不到状态机类:" + name); return default(IState); } return ChangeState(state); } /// /// 获取栈顶状态 /// /// 栈顶状态 public IState TopState() { if (_stateStack.Count <= 0) { return default(IState); } return _stateStack.Peek(); } public string TopStateName() { if (_stateStack.Count <= 0) { return null; } IState state = _stateStack.Peek(); return GetStateName(state); } /// /// 清空堆栈 /// public void Clear() { while (_stateStack.Count > 0) { _stateStack.Pop().OnStateLeave(); } } public int Count { get { return _stateStack.Count; } } }