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