123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588 |
- //------------------------------------------------------------
- // Game Framework
- // Copyright © 2013-2021 loyalsoft. All rights reserved.
- // Homepage: http://www.game7000.com/
- // Feedback: http://www.game7000.com/
- //------------------------------------------------------------
- using System;
- using System.Collections.Generic;
- namespace GameFramework.Fsm
- {
- /// <summary>
- /// 有限状态机。
- /// </summary>
- /// <typeparam name="T">有限状态机持有者类型。</typeparam>
- internal sealed class Fsm<T> : FsmBase, IReference, IFsm<T> where T : class
- {
- private T m_Owner;
- private readonly Dictionary<Type, FsmState<T>> m_States;
- private Dictionary<string, Variable> m_Datas;
- private FsmState<T> m_CurrentState;
- private float m_CurrentStateTime;
- private bool m_IsDestroyed;
- /// <summary>
- /// 初始化有限状态机的新实例。
- /// </summary>
- public Fsm()
- {
- m_Owner = null;
- m_States = new Dictionary<Type, FsmState<T>>();
- m_Datas = null;
- m_CurrentState = null;
- m_CurrentStateTime = 0f;
- m_IsDestroyed = true;
- }
- /// <summary>
- /// 获取有限状态机持有者。
- /// </summary>
- public T Owner
- {
- get
- {
- return m_Owner;
- }
- }
- /// <summary>
- /// 获取有限状态机持有者类型。
- /// </summary>
- public override Type OwnerType
- {
- get
- {
- return typeof(T);
- }
- }
- /// <summary>
- /// 获取有限状态机中状态的数量。
- /// </summary>
- public override int FsmStateCount
- {
- get
- {
- return m_States.Count;
- }
- }
- /// <summary>
- /// 获取有限状态机是否正在运行。
- /// </summary>
- public override bool IsRunning
- {
- get
- {
- return m_CurrentState != null;
- }
- }
- /// <summary>
- /// 获取有限状态机是否被销毁。
- /// </summary>
- public override bool IsDestroyed
- {
- get
- {
- return m_IsDestroyed;
- }
- }
- /// <summary>
- /// 获取当前有限状态机状态。
- /// </summary>
- public FsmState<T> CurrentState
- {
- get
- {
- return m_CurrentState;
- }
- }
- /// <summary>
- /// 获取当前有限状态机状态名称。
- /// </summary>
- public override string CurrentStateName
- {
- get
- {
- return m_CurrentState != null ? m_CurrentState.GetType().FullName : null;
- }
- }
- /// <summary>
- /// 获取当前有限状态机状态持续时间。
- /// </summary>
- public override float CurrentStateTime
- {
- get
- {
- return m_CurrentStateTime;
- }
- }
- /// <summary>
- /// 创建有限状态机。
- /// </summary>
- /// <param name="name">有限状态机名称。</param>
- /// <param name="owner">有限状态机持有者。</param>
- /// <param name="states">有限状态机状态集合。</param>
- /// <returns>创建的有限状态机。</returns>
- public static Fsm<T> Create(string name, T owner, params FsmState<T>[] states)
- {
- if (owner == null)
- {
- throw new GameFrameworkException("FSM owner is invalid.");
- }
- if (states == null || states.Length < 1)
- {
- throw new GameFrameworkException("FSM states is invalid.");
- }
- Fsm<T> fsm = ReferencePool.Acquire<Fsm<T>>();
- fsm.Name = name;
- fsm.m_Owner = owner;
- fsm.m_IsDestroyed = false;
- foreach (FsmState<T> state in states)
- {
- if (state == null)
- {
- throw new GameFrameworkException("FSM states is invalid.");
- }
- Type stateType = state.GetType();
- if (fsm.m_States.ContainsKey(stateType))
- {
- throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' state '{1}' is already exist.", new TypeNamePair(typeof(T), name), stateType.FullName));
- }
- fsm.m_States.Add(stateType, state);
- state.OnInit(fsm);
- }
- return fsm;
- }
- /// <summary>
- /// 创建有限状态机。
- /// </summary>
- /// <param name="name">有限状态机名称。</param>
- /// <param name="owner">有限状态机持有者。</param>
- /// <param name="states">有限状态机状态集合。</param>
- /// <returns>创建的有限状态机。</returns>
- public static Fsm<T> Create(string name, T owner, List<FsmState<T>> states)
- {
- if (owner == null)
- {
- throw new GameFrameworkException("FSM owner is invalid.");
- }
- if (states == null || states.Count < 1)
- {
- throw new GameFrameworkException("FSM states is invalid.");
- }
- Fsm<T> fsm = ReferencePool.Acquire<Fsm<T>>();
- fsm.Name = name;
- fsm.m_Owner = owner;
- fsm.m_IsDestroyed = false;
- foreach (FsmState<T> state in states)
- {
- if (state == null)
- {
- throw new GameFrameworkException("FSM states is invalid.");
- }
- Type stateType = state.GetType();
- if (fsm.m_States.ContainsKey(stateType))
- {
- throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' state '{1}' is already exist.", new TypeNamePair(typeof(T), name), stateType.FullName));
- }
- fsm.m_States.Add(stateType, state);
- state.OnInit(fsm);
- }
- return fsm;
- }
- /// <summary>
- /// 清理有限状态机。
- /// </summary>
- public void Clear()
- {
- if (m_CurrentState != null)
- {
- m_CurrentState.OnLeave(this, true);
- }
- foreach (KeyValuePair<Type, FsmState<T>> state in m_States)
- {
- state.Value.OnDestroy(this);
- }
- Name = null;
- m_Owner = null;
- m_States.Clear();
- if (m_Datas != null)
- {
- foreach (KeyValuePair<string, Variable> data in m_Datas)
- {
- if (data.Value == null)
- {
- continue;
- }
- ReferencePool.Release(data.Value);
- }
- m_Datas.Clear();
- }
- m_CurrentState = null;
- m_CurrentStateTime = 0f;
- m_IsDestroyed = true;
- }
- /// <summary>
- /// 开始有限状态机。
- /// </summary>
- /// <typeparam name="TState">要开始的有限状态机状态类型。</typeparam>
- public void Start<TState>() where TState : FsmState<T>
- {
- if (IsRunning)
- {
- throw new GameFrameworkException("FSM is running, can not start again.");
- }
- FsmState<T> state = GetState<TState>();
- if (state == null)
- {
- throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not start state '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), typeof(TState).FullName));
- }
- m_CurrentStateTime = 0f;
- m_CurrentState = state;
- m_CurrentState.OnEnter(this);
- }
- /// <summary>
- /// 开始有限状态机。
- /// </summary>
- /// <param name="stateType">要开始的有限状态机状态类型。</param>
- public void Start(Type stateType)
- {
- if (IsRunning)
- {
- throw new GameFrameworkException("FSM is running, can not start again.");
- }
- if (stateType == null)
- {
- throw new GameFrameworkException("State type is invalid.");
- }
- if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
- {
- throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
- }
- FsmState<T> state = GetState(stateType);
- if (state == null)
- {
- throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not start state '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), stateType.FullName));
- }
- m_CurrentStateTime = 0f;
- m_CurrentState = state;
- m_CurrentState.OnEnter(this);
- }
- /// <summary>
- /// 是否存在有限状态机状态。
- /// </summary>
- /// <typeparam name="TState">要检查的有限状态机状态类型。</typeparam>
- /// <returns>是否存在有限状态机状态。</returns>
- public bool HasState<TState>() where TState : FsmState<T>
- {
- return m_States.ContainsKey(typeof(TState));
- }
- /// <summary>
- /// 是否存在有限状态机状态。
- /// </summary>
- /// <param name="stateType">要检查的有限状态机状态类型。</param>
- /// <returns>是否存在有限状态机状态。</returns>
- public bool HasState(Type stateType)
- {
- if (stateType == null)
- {
- throw new GameFrameworkException("State type is invalid.");
- }
- if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
- {
- throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
- }
- return m_States.ContainsKey(stateType);
- }
- /// <summary>
- /// 获取有限状态机状态。
- /// </summary>
- /// <typeparam name="TState">要获取的有限状态机状态类型。</typeparam>
- /// <returns>要获取的有限状态机状态。</returns>
- public TState GetState<TState>() where TState : FsmState<T>
- {
- FsmState<T> state = null;
- if (m_States.TryGetValue(typeof(TState), out state))
- {
- return (TState)state;
- }
- return null;
- }
- /// <summary>
- /// 获取有限状态机状态。
- /// </summary>
- /// <param name="stateType">要获取的有限状态机状态类型。</param>
- /// <returns>要获取的有限状态机状态。</returns>
- public FsmState<T> GetState(Type stateType)
- {
- if (stateType == null)
- {
- throw new GameFrameworkException("State type is invalid.");
- }
- if (!typeof(FsmState<T>).IsAssignableFrom(stateType))
- {
- throw new GameFrameworkException(Utility.Text.Format("State type '{0}' is invalid.", stateType.FullName));
- }
- FsmState<T> state = null;
- if (m_States.TryGetValue(stateType, out state))
- {
- return state;
- }
- return null;
- }
- /// <summary>
- /// 获取有限状态机的所有状态。
- /// </summary>
- /// <returns>有限状态机的所有状态。</returns>
- public FsmState<T>[] GetAllStates()
- {
- int index = 0;
- FsmState<T>[] results = new FsmState<T>[m_States.Count];
- foreach (KeyValuePair<Type, FsmState<T>> state in m_States)
- {
- results[index++] = state.Value;
- }
- return results;
- }
- /// <summary>
- /// 获取有限状态机的所有状态。
- /// </summary>
- /// <param name="results">有限状态机的所有状态。</param>
- public void GetAllStates(List<FsmState<T>> results)
- {
- if (results == null)
- {
- throw new GameFrameworkException("Results is invalid.");
- }
- results.Clear();
- foreach (KeyValuePair<Type, FsmState<T>> state in m_States)
- {
- results.Add(state.Value);
- }
- }
- /// <summary>
- /// 是否存在有限状态机数据。
- /// </summary>
- /// <param name="name">有限状态机数据名称。</param>
- /// <returns>有限状态机数据是否存在。</returns>
- public bool HasData(string name)
- {
- if (string.IsNullOrEmpty(name))
- {
- throw new GameFrameworkException("Data name is invalid.");
- }
- if (m_Datas == null)
- {
- return false;
- }
- return m_Datas.ContainsKey(name);
- }
- /// <summary>
- /// 获取有限状态机数据。
- /// </summary>
- /// <typeparam name="TData">要获取的有限状态机数据的类型。</typeparam>
- /// <param name="name">有限状态机数据名称。</param>
- /// <returns>要获取的有限状态机数据。</returns>
- public TData GetData<TData>(string name) where TData : Variable
- {
- return (TData)GetData(name);
- }
- /// <summary>
- /// 获取有限状态机数据。
- /// </summary>
- /// <param name="name">有限状态机数据名称。</param>
- /// <returns>要获取的有限状态机数据。</returns>
- public Variable GetData(string name)
- {
- if (string.IsNullOrEmpty(name))
- {
- throw new GameFrameworkException("Data name is invalid.");
- }
- if (m_Datas == null)
- {
- return null;
- }
- Variable data = null;
- if (m_Datas.TryGetValue(name, out data))
- {
- return data;
- }
- return null;
- }
- /// <summary>
- /// 设置有限状态机数据。
- /// </summary>
- /// <typeparam name="TData">要设置的有限状态机数据的类型。</typeparam>
- /// <param name="name">有限状态机数据名称。</param>
- /// <param name="data">要设置的有限状态机数据。</param>
- public void SetData<TData>(string name, TData data) where TData : Variable
- {
- SetData(name, (Variable)data);
- }
- /// <summary>
- /// 设置有限状态机数据。
- /// </summary>
- /// <param name="name">有限状态机数据名称。</param>
- /// <param name="data">要设置的有限状态机数据。</param>
- public void SetData(string name, Variable data)
- {
- if (string.IsNullOrEmpty(name))
- {
- throw new GameFrameworkException("Data name is invalid.");
- }
- if (m_Datas == null)
- {
- m_Datas = new Dictionary<string, Variable>(StringComparer.Ordinal);
- }
- Variable oldData = GetData(name);
- if (oldData != null)
- {
- ReferencePool.Release(oldData);
- }
- m_Datas[name] = data;
- }
- /// <summary>
- /// 移除有限状态机数据。
- /// </summary>
- /// <param name="name">有限状态机数据名称。</param>
- /// <returns>是否移除有限状态机数据成功。</returns>
- public bool RemoveData(string name)
- {
- if (string.IsNullOrEmpty(name))
- {
- throw new GameFrameworkException("Data name is invalid.");
- }
- if (m_Datas == null)
- {
- return false;
- }
- Variable oldData = GetData(name);
- if (oldData != null)
- {
- ReferencePool.Release(oldData);
- }
- return m_Datas.Remove(name);
- }
- /// <summary>
- /// 有限状态机轮询。
- /// </summary>
- /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
- /// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
- internal override void Update(float elapseSeconds, float realElapseSeconds)
- {
- if (m_CurrentState == null)
- {
- return;
- }
- m_CurrentStateTime += elapseSeconds;
- m_CurrentState.OnUpdate(this, elapseSeconds, realElapseSeconds);
- }
- /// <summary>
- /// 关闭并清理有限状态机。
- /// </summary>
- internal override void Shutdown()
- {
- ReferencePool.Release(this);
- }
- /// <summary>
- /// 切换当前有限状态机状态。
- /// </summary>
- /// <typeparam name="TState">要切换到的有限状态机状态类型。</typeparam>
- internal void ChangeState<TState>() where TState : FsmState<T>
- {
- ChangeState(typeof(TState));
- }
- /// <summary>
- /// 切换当前有限状态机状态。
- /// </summary>
- /// <param name="stateType">要切换到的有限状态机状态类型。</param>
- internal void ChangeState(Type stateType)
- {
- if (m_CurrentState == null)
- {
- throw new GameFrameworkException("Current state is invalid.");
- }
- FsmState<T> state = GetState(stateType);
- if (state == null)
- {
- throw new GameFrameworkException(Utility.Text.Format("FSM '{0}' can not change state to '{1}' which is not exist.", new TypeNamePair(typeof(T), Name), stateType.FullName));
- }
- m_CurrentState.OnLeave(this, false);
- m_CurrentStateTime = 0f;
- m_CurrentState = state;
- m_CurrentState.OnEnter(this);
- }
- }
- }
|