From 337f21c9aed4fafa99045da3531b6ae6ef07605a Mon Sep 17 00:00:00 2001 From: ALEXTANG <574809918@qq.com> Date: Tue, 9 Aug 2022 15:42:07 +0800 Subject: [PATCH] Fsm Fsm --- Assets/TEngine/Runtime/Fsm.meta | 8 + Assets/TEngine/Runtime/Fsm/Fsm.cs | 575 ++++++++++++++++++ Assets/TEngine/Runtime/Fsm/Fsm.cs.meta | 11 + Assets/TEngine/Runtime/Fsm/FsmBase.cs | 106 ++++ Assets/TEngine/Runtime/Fsm/FsmBase.cs.meta | 11 + Assets/TEngine/Runtime/Fsm/FsmManager.cs | 404 ++++++++++++ Assets/TEngine/Runtime/Fsm/FsmManager.cs.meta | 11 + Assets/TEngine/Runtime/Fsm/FsmState.cs | 103 ++++ Assets/TEngine/Runtime/Fsm/FsmState.cs.meta | 11 + Assets/TEngine/Runtime/Fsm/IFsm.cs | 178 ++++++ Assets/TEngine/Runtime/Fsm/IFsm.cs.meta | 11 + Assets/TEngine/Runtime/Fsm/IFsmManager.cs | 174 ++++++ .../TEngine/Runtime/Fsm/IFsmManager.cs.meta | 11 + Assets/TEngine/Runtime/Fsm/TypeNamePair.cs | 128 ++++ .../TEngine/Runtime/Fsm/TypeNamePair.cs.meta | 11 + 15 files changed, 1753 insertions(+) create mode 100644 Assets/TEngine/Runtime/Fsm.meta create mode 100644 Assets/TEngine/Runtime/Fsm/Fsm.cs create mode 100644 Assets/TEngine/Runtime/Fsm/Fsm.cs.meta create mode 100644 Assets/TEngine/Runtime/Fsm/FsmBase.cs create mode 100644 Assets/TEngine/Runtime/Fsm/FsmBase.cs.meta create mode 100644 Assets/TEngine/Runtime/Fsm/FsmManager.cs create mode 100644 Assets/TEngine/Runtime/Fsm/FsmManager.cs.meta create mode 100644 Assets/TEngine/Runtime/Fsm/FsmState.cs create mode 100644 Assets/TEngine/Runtime/Fsm/FsmState.cs.meta create mode 100644 Assets/TEngine/Runtime/Fsm/IFsm.cs create mode 100644 Assets/TEngine/Runtime/Fsm/IFsm.cs.meta create mode 100644 Assets/TEngine/Runtime/Fsm/IFsmManager.cs create mode 100644 Assets/TEngine/Runtime/Fsm/IFsmManager.cs.meta create mode 100644 Assets/TEngine/Runtime/Fsm/TypeNamePair.cs create mode 100644 Assets/TEngine/Runtime/Fsm/TypeNamePair.cs.meta diff --git a/Assets/TEngine/Runtime/Fsm.meta b/Assets/TEngine/Runtime/Fsm.meta new file mode 100644 index 00000000..08195c8b --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ff94fb3406b8dc744adcde21595f769c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Fsm/Fsm.cs b/Assets/TEngine/Runtime/Fsm/Fsm.cs new file mode 100644 index 00000000..0df63c7f --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/Fsm.cs @@ -0,0 +1,575 @@ +using System; +using System.Collections.Generic; + +namespace TEngine.Fsm +{ + /// + /// 有限状态机。 + /// + /// 有限状态机持有者类型。 + internal sealed class Fsm : FsmBase,IMemPoolObject, IFsm where T : class + { + private T m_Owner; + private readonly Dictionary> m_States; + private Dictionary m_Datas; + private FsmState m_CurrentState; + private float m_CurrentStateTime; + private bool m_IsDestroyed; + + /// + /// 初始化有限状态机的新实例。 + /// + public Fsm() + { + m_Owner = null; + m_States = new Dictionary>(); + m_Datas = null; + m_CurrentState = null; + m_CurrentStateTime = 0f; + m_IsDestroyed = true; + } + + /// + /// 获取有限状态机持有者。 + /// + public T Owner + { + get + { + return m_Owner; + } + } + + /// + /// 获取有限状态机持有者类型。 + /// + public override Type OwnerType + { + get + { + return typeof(T); + } + } + + /// + /// 获取有限状态机中状态的数量。 + /// + public override int FsmStateCount + { + get + { + return m_States.Count; + } + } + + /// + /// 获取有限状态机是否正在运行。 + /// + public override bool IsRunning + { + get + { + return m_CurrentState != null; + } + } + + /// + /// 获取有限状态机是否被销毁。 + /// + public override bool IsDestroyed + { + get + { + return m_IsDestroyed; + } + } + + /// + /// 获取当前有限状态机状态。 + /// + public FsmState CurrentState + { + get + { + return m_CurrentState; + } + } + + /// + /// 获取当前有限状态机状态名称。 + /// + public override string CurrentStateName + { + get + { + return m_CurrentState != null ? m_CurrentState.GetType().FullName : null; + } + } + + /// + /// 获取当前有限状态机状态持续时间。 + /// + public override float CurrentStateTime + { + get + { + return m_CurrentStateTime; + } + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 创建的有限状态机。 + public static Fsm Create(string name, T owner, params FsmState[] states) + { + if (owner == null) + { + throw new Exception("FSM owner is invalid."); + } + + if (states == null || states.Length < 1) + { + throw new Exception("FSM states is invalid."); + } + + Fsm fsm = GameMemPool>.Alloc(); + fsm.Name = name; + fsm.m_Owner = owner; + fsm.m_IsDestroyed = false; + foreach (FsmState state in states) + { + if (state == null) + { + throw new Exception("FSM states is invalid."); + } + + Type stateType = state.GetType(); + if (fsm.m_States.ContainsKey(stateType)) + { + throw new Exception(string.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; + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 创建的有限状态机。 + public static Fsm Create(string name, T owner, List> states) + { + if (owner == null) + { + throw new Exception("FSM owner is invalid."); + } + + if (states == null || states.Count < 1) + { + throw new Exception("FSM states is invalid."); + } + + Fsm fsm = GameMemPool>.Alloc(); + fsm.Name = name; + fsm.m_Owner = owner; + fsm.m_IsDestroyed = false; + foreach (FsmState state in states) + { + if (state == null) + { + throw new Exception("FSM states is invalid."); + } + + Type stateType = state.GetType(); + if (fsm.m_States.ContainsKey(stateType)) + { + throw new Exception(string.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; + } + + /// + /// 清理有限状态机。 + /// + public void Clear() + { + if (m_CurrentState != null) + { + m_CurrentState.OnLeave(this, true); + } + + foreach (KeyValuePair> state in m_States) + { + state.Value.OnDestroy(this); + } + + Name = null; + m_Owner = null; + m_States.Clear(); + + if (m_Datas != null) + { + m_Datas.Clear(); + } + + m_CurrentState = null; + m_CurrentStateTime = 0f; + m_IsDestroyed = true; + } + + /// + /// 开始有限状态机。 + /// + /// 要开始的有限状态机状态类型。 + public void Start() where TState : FsmState + { + if (IsRunning) + { + throw new Exception("FSM is running, can not start again."); + } + + FsmState state = GetState(); + if (state == null) + { + throw new Exception(string.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); + } + + /// + /// 开始有限状态机。 + /// + /// 要开始的有限状态机状态类型。 + public void Start(Type stateType) + { + if (IsRunning) + { + throw new Exception("FSM is running, can not start again."); + } + + if (stateType == null) + { + throw new Exception("State type is invalid."); + } + + if (!typeof(FsmState).IsAssignableFrom(stateType)) + { + throw new Exception(string.Format("State type '{0}' is invalid.", stateType.FullName)); + } + + FsmState state = GetState(stateType); + if (state == null) + { + throw new Exception(string.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); + } + + /// + /// 是否存在有限状态机状态。 + /// + /// 要检查的有限状态机状态类型。 + /// 是否存在有限状态机状态。 + public bool HasState() where TState : FsmState + { + return m_States.ContainsKey(typeof(TState)); + } + + /// + /// 是否存在有限状态机状态。 + /// + /// 要检查的有限状态机状态类型。 + /// 是否存在有限状态机状态。 + public bool HasState(Type stateType) + { + if (stateType == null) + { + throw new Exception("State type is invalid."); + } + + if (!typeof(FsmState).IsAssignableFrom(stateType)) + { + throw new Exception(string.Format("State type '{0}' is invalid.", stateType.FullName)); + } + + return m_States.ContainsKey(stateType); + } + + /// + /// 获取有限状态机状态。 + /// + /// 要获取的有限状态机状态类型。 + /// 要获取的有限状态机状态。 + public TState GetState() where TState : FsmState + { + FsmState state = null; + if (m_States.TryGetValue(typeof(TState), out state)) + { + return (TState)state; + } + + return null; + } + + /// + /// 获取有限状态机状态。 + /// + /// 要获取的有限状态机状态类型。 + /// 要获取的有限状态机状态。 + public FsmState GetState(Type stateType) + { + if (stateType == null) + { + throw new Exception("State type is invalid."); + } + + if (!typeof(FsmState).IsAssignableFrom(stateType)) + { + throw new Exception(string.Format("State type '{0}' is invalid.", stateType.FullName)); + } + + FsmState state = null; + if (m_States.TryGetValue(stateType, out state)) + { + return state; + } + + return null; + } + + /// + /// 获取有限状态机的所有状态。 + /// + /// 有限状态机的所有状态。 + public FsmState[] GetAllStates() + { + int index = 0; + FsmState[] results = new FsmState[m_States.Count]; + foreach (KeyValuePair> state in m_States) + { + results[index++] = state.Value; + } + + return results; + } + + /// + /// 获取有限状态机的所有状态。 + /// + /// 有限状态机的所有状态。 + public void GetAllStates(List> results) + { + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair> state in m_States) + { + results.Add(state.Value); + } + } + + /// + /// 是否存在有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 有限状态机数据是否存在。 + public bool HasData(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new Exception("Data name is invalid."); + } + + if (m_Datas == null) + { + return false; + } + + return m_Datas.ContainsKey(name); + } + + /// + /// 获取有限状态机数据。 + /// + /// 要获取的有限状态机数据的类型。 + /// 有限状态机数据名称。 + /// 要获取的有限状态机数据。 + public TData GetData(string name) + { + return (TData)GetData(name); + } + + /// + /// 获取有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 要获取的有限状态机数据。 + public object GetData(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new Exception("Data name is invalid."); + } + + if (m_Datas == null) + { + return null; + } + + object data = null; + if (m_Datas.TryGetValue(name, out data)) + { + return data; + } + + return null; + } + + /// + /// 设置有限状态机数据。 + /// + /// 要设置的有限状态机数据的类型。 + /// 有限状态机数据名称。 + /// 要设置的有限状态机数据。 + public void SetData(string name, TData data) + { + SetData(name,data); + } + + /// + /// 设置有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 要设置的有限状态机数据。 + public void SetData(string name, object data) + { + if (string.IsNullOrEmpty(name)) + { + throw new Exception("Data name is invalid."); + } + + if (m_Datas == null) + { + m_Datas = new Dictionary(StringComparer.Ordinal); + } + + object oldData = GetData(name); + oldData = null; + + m_Datas[name] = data; + } + + /// + /// 移除有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 是否移除有限状态机数据成功。 + public bool RemoveData(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new Exception("Data name is invalid."); + } + + if (m_Datas == null) + { + return false; + } + + object oldData = GetData(name); + oldData = null; + + return m_Datas.Remove(name); + } + + /// + /// 有限状态机轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + internal override void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_CurrentState == null) + { + return; + } + + m_CurrentStateTime += elapseSeconds; + m_CurrentState.OnUpdate(this, elapseSeconds, realElapseSeconds); + } + + /// + /// 关闭并清理有限状态机。 + /// + internal override void Shutdown() + { + GameMemPool>.Free(this); + } + + /// + /// 切换当前有限状态机状态。 + /// + /// 要切换到的有限状态机状态类型。 + public void ChangeState() where TState : FsmState + { + ChangeState(typeof(TState)); + } + + /// + /// 切换当前有限状态机状态。 + /// + /// 要切换到的有限状态机状态类型。 + internal void ChangeState(Type stateType) + { + if (m_CurrentState == null) + { + throw new Exception("Current state is invalid."); + } + + FsmState state = GetState(stateType); + if (state == null) + { + throw new Exception(string.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); + } + + public void Init() + { + + } + + public void Destroy() + { + + } + } +} diff --git a/Assets/TEngine/Runtime/Fsm/Fsm.cs.meta b/Assets/TEngine/Runtime/Fsm/Fsm.cs.meta new file mode 100644 index 00000000..9f335fa0 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/Fsm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88364685b9103df45b9d246548c35246 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Fsm/FsmBase.cs b/Assets/TEngine/Runtime/Fsm/FsmBase.cs new file mode 100644 index 00000000..ec0100a5 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/FsmBase.cs @@ -0,0 +1,106 @@ +using System; + +namespace TEngine.Fsm +{ + /// + /// 有限状态机基类。 + /// + public abstract class FsmBase + { + private string m_Name; + + /// + /// 初始化有限状态机基类的新实例。 + /// + public FsmBase() + { + m_Name = string.Empty; + } + + /// + /// 获取有限状态机名称。 + /// + public string Name + { + get + { + return m_Name; + } + protected set + { + m_Name = value ?? string.Empty; + } + } + + /// + /// 获取有限状态机完整名称。 + /// + public string FullName + { + get + { + return new TypeNamePair(OwnerType, m_Name).ToString(); + } + } + + /// + /// 获取有限状态机持有者类型。 + /// + public abstract Type OwnerType + { + get; + } + + /// + /// 获取有限状态机中状态的数量。 + /// + public abstract int FsmStateCount + { + get; + } + + /// + /// 获取有限状态机是否正在运行。 + /// + public abstract bool IsRunning + { + get; + } + + /// + /// 获取有限状态机是否被销毁。 + /// + public abstract bool IsDestroyed + { + get; + } + + /// + /// 获取当前有限状态机状态名称。 + /// + public abstract string CurrentStateName + { + get; + } + + /// + /// 获取当前有限状态机状态持续时间。 + /// + public abstract float CurrentStateTime + { + get; + } + + /// + /// 有限状态机轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 当前已流逝时间,以秒为单位。 + internal abstract void Update(float elapseSeconds, float realElapseSeconds); + + /// + /// 关闭并清理有限状态机。 + /// + internal abstract void Shutdown(); + } +} diff --git a/Assets/TEngine/Runtime/Fsm/FsmBase.cs.meta b/Assets/TEngine/Runtime/Fsm/FsmBase.cs.meta new file mode 100644 index 00000000..b9b30bfe --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/FsmBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a23e58e7b2ef2e469d1e6e295516fc5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Fsm/FsmManager.cs b/Assets/TEngine/Runtime/Fsm/FsmManager.cs new file mode 100644 index 00000000..a9f724d5 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/FsmManager.cs @@ -0,0 +1,404 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Fsm +{ + /// + /// 有限状态机管理器。 + /// + public class FsmManager : UnitySingleton, IFsmManager + { + private readonly Dictionary m_Fsms; + private readonly List m_TempFsms; + + /// + /// 初始化有限状态机管理器的新实例。 + /// + public FsmManager() + { + m_Fsms = new Dictionary(); + m_TempFsms = new List(); + } + + /// + /// 获取游戏框架模块优先级。 + /// + /// 优先级较高的模块会优先轮询,并且关闭操作会后进行。 + internal int Priority + { + get + { + return 1; + } + } + + /// + /// 获取有限状态机数量。 + /// + public int Count + { + get + { + return m_Fsms.Count; + } + } + /// + /// 有限状态机管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update() + { + m_TempFsms.Clear(); + if (m_Fsms.Count <= 0) + { + return; + } + + foreach (KeyValuePair fsm in m_Fsms) + { + m_TempFsms.Add(fsm.Value); + } + + foreach (FsmBase fsm in m_TempFsms) + { + if (fsm.IsDestroyed) + { + continue; + } + + fsm.Update(Time.deltaTime, Time.unscaledDeltaTime); + } + } + + /// + /// 关闭并清理有限状态机管理器。 + /// + protected override void OnDestroy() + { + foreach (KeyValuePair fsm in m_Fsms) + { + fsm.Value.Shutdown(); + } + + m_Fsms.Clear(); + m_TempFsms.Clear(); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + public bool HasFsm() where T : class + { + return InternalHasFsm(new TypeNamePair(typeof(T))); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + public bool HasFsm(Type ownerType) + { + if (ownerType == null) + { + throw new Exception("Owner type is invalid."); + } + + return InternalHasFsm(new TypeNamePair(ownerType)); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + public bool HasFsm(string name) where T : class + { + return InternalHasFsm(new TypeNamePair(typeof(T), name)); + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + public bool HasFsm(Type ownerType, string name) + { + if (ownerType == null) + { + throw new Exception("Owner type is invalid."); + } + + return InternalHasFsm(new TypeNamePair(ownerType, name)); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + public IFsm GetFsm() where T : class + { + return (IFsm)InternalGetFsm(new TypeNamePair(typeof(T))); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + public FsmBase GetFsm(Type ownerType) + { + if (ownerType == null) + { + throw new Exception("Owner type is invalid."); + } + + return InternalGetFsm(new TypeNamePair(ownerType)); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + public IFsm GetFsm(string name) where T : class + { + return (IFsm)InternalGetFsm(new TypeNamePair(typeof(T), name)); + } + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + public FsmBase GetFsm(Type ownerType, string name) + { + if (ownerType == null) + { + throw new Exception("Owner type is invalid."); + } + + return InternalGetFsm(new TypeNamePair(ownerType, name)); + } + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + public FsmBase[] GetAllFsms() + { + int index = 0; + FsmBase[] results = new FsmBase[m_Fsms.Count]; + foreach (KeyValuePair fsm in m_Fsms) + { + results[index++] = fsm.Value; + } + + return results; + } + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + public void GetAllFsms(List results) + { + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair fsm in m_Fsms) + { + results.Add(fsm.Value); + } + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(T owner, params FsmState[] states) where T : class + { + return CreateFsm(string.Empty, owner, states); + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(string name, T owner, params FsmState[] states) where T : class + { + TypeNamePair typeNamePair = new TypeNamePair(typeof(T), name); + if (HasFsm(name)) + { + throw new Exception(string.Format("Already exist FSM '{0}'.", typeNamePair)); + } + + Fsm fsm = Fsm.Create(name, owner, states); + m_Fsms.Add(typeNamePair, fsm); + return fsm; + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(T owner, List> states) where T : class + { + return CreateFsm(string.Empty, owner, states); + } + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + public IFsm CreateFsm(string name, T owner, List> states) where T : class + { + TypeNamePair typeNamePair = new TypeNamePair(typeof(T), name); + if (HasFsm(name)) + { + throw new Exception(string.Format("Already exist FSM '{0}'.", typeNamePair)); + } + + Fsm fsm = Fsm.Create(name, owner, states); + m_Fsms.Add(typeNamePair, fsm); + return fsm; + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm() where T : class + { + return InternalDestroyFsm(new TypeNamePair(typeof(T))); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(Type ownerType) + { + if (ownerType == null) + { + throw new Exception("Owner type is invalid."); + } + + return InternalDestroyFsm(new TypeNamePair(ownerType)); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(string name) where T : class + { + return InternalDestroyFsm(new TypeNamePair(typeof(T), name)); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(Type ownerType, string name) + { + if (ownerType == null) + { + throw new Exception("Owner type is invalid."); + } + + return InternalDestroyFsm(new TypeNamePair(ownerType, name)); + } + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(IFsm fsm) where T : class + { + if (fsm == null) + { + throw new Exception("FSM is invalid."); + } + + return InternalDestroyFsm(new TypeNamePair(typeof(T), fsm.Name)); + } + + /// + /// 销毁有限状态机。 + /// + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + public bool DestroyFsm(FsmBase fsm) + { + if (fsm == null) + { + throw new Exception("FSM is invalid."); + } + + return InternalDestroyFsm(new TypeNamePair(fsm.OwnerType, fsm.Name)); + } + + private bool InternalHasFsm(TypeNamePair typeNamePair) + { + return m_Fsms.ContainsKey(typeNamePair); + } + + private FsmBase InternalGetFsm(TypeNamePair typeNamePair) + { + FsmBase fsm = null; + if (m_Fsms.TryGetValue(typeNamePair, out fsm)) + { + return fsm; + } + + return null; + } + + private bool InternalDestroyFsm(TypeNamePair typeNamePair) + { + FsmBase fsm = null; + if (m_Fsms.TryGetValue(typeNamePair, out fsm)) + { + fsm.Shutdown(); + return m_Fsms.Remove(typeNamePair); + } + + return false; + } + } +} diff --git a/Assets/TEngine/Runtime/Fsm/FsmManager.cs.meta b/Assets/TEngine/Runtime/Fsm/FsmManager.cs.meta new file mode 100644 index 00000000..95ce0adb --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/FsmManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 313492502b69d854e94ccd7ca4eb436d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Fsm/FsmState.cs b/Assets/TEngine/Runtime/Fsm/FsmState.cs new file mode 100644 index 00000000..97015443 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/FsmState.cs @@ -0,0 +1,103 @@ +using System; + +namespace TEngine.Fsm +{ + /// + /// 有限状态机状态基类。 + /// + /// 有限状态机持有者类型。 + public abstract class FsmState where T : class + { + /// + /// 初始化有限状态机状态基类的新实例。 + /// + public FsmState() + { + } + + /// + /// 有限状态机状态初始化时调用。 + /// + /// 有限状态机引用。 + protected internal virtual void OnInit(IFsm fsm) + { + } + + /// + /// 有限状态机状态进入时调用。 + /// + /// 有限状态机引用。 + protected internal virtual void OnEnter(IFsm fsm) + { + } + + /// + /// 有限状态机状态轮询时调用。 + /// + /// 有限状态机引用。 + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + protected internal virtual void OnUpdate(IFsm fsm, float elapseSeconds, float realElapseSeconds) + { + } + + /// + /// 有限状态机状态离开时调用。 + /// + /// 有限状态机引用。 + /// 是否是关闭有限状态机时触发。 + protected internal virtual void OnLeave(IFsm fsm, bool isShutdown) + { + } + + /// + /// 有限状态机状态销毁时调用。 + /// + /// 有限状态机引用。 + protected internal virtual void OnDestroy(IFsm fsm) + { + } + + /// + /// 切换当前有限状态机状态。 + /// + /// 要切换到的有限状态机状态类型。 + /// 有限状态机引用。 + protected void ChangeState(IFsm fsm) where TState : FsmState + { + Fsm fsmImplement = (Fsm)fsm; + if (fsmImplement == null) + { + throw new Exception("FSM is invalid."); + } + + fsmImplement.ChangeState(); + } + + /// + /// 切换当前有限状态机状态。 + /// + /// 有限状态机引用。 + /// 要切换到的有限状态机状态类型。 + protected void ChangeState(IFsm fsm, Type stateType) + { + Fsm fsmImplement = (Fsm)fsm; + if (fsmImplement == null) + { + throw new Exception("FSM is invalid."); + } + + if (stateType == null) + { + throw new Exception("State type is invalid."); + } + + if (!typeof(FsmState).IsAssignableFrom(stateType)) + { + throw new Exception(string.Format("State type '{0}' is invalid.", stateType.FullName)); + } + + fsmImplement.ChangeState(stateType); + } + } +} diff --git a/Assets/TEngine/Runtime/Fsm/FsmState.cs.meta b/Assets/TEngine/Runtime/Fsm/FsmState.cs.meta new file mode 100644 index 00000000..b2d83a92 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/FsmState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f37f11a7e625a445a24eeb4c9286423 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Fsm/IFsm.cs b/Assets/TEngine/Runtime/Fsm/IFsm.cs new file mode 100644 index 00000000..9e4de686 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/IFsm.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; + +namespace TEngine.Fsm +{ + /// + /// 有限状态机接口。 + /// + /// 有限状态机持有者类型。 + public interface IFsm where T : class + { + /// + /// 获取有限状态机名称。 + /// + string Name + { + get; + } + + /// + /// 获取有限状态机完整名称。 + /// + string FullName + { + get; + } + + /// + /// 获取有限状态机持有者。 + /// + T Owner + { + get; + } + + /// + /// 获取有限状态机中状态的数量。 + /// + int FsmStateCount + { + get; + } + + /// + /// 获取有限状态机是否正在运行。 + /// + bool IsRunning + { + get; + } + + /// + /// 获取有限状态机是否被销毁。 + /// + bool IsDestroyed + { + get; + } + + /// + /// 获取当前有限状态机状态。 + /// + FsmState CurrentState + { + get; + } + + /// + /// 获取当前有限状态机状态持续时间。 + /// + float CurrentStateTime + { + get; + } + + /// + /// 开始有限状态机。 + /// + /// 要开始的有限状态机状态类型。 + void Start() where TState : FsmState; + + /// + /// 开始有限状态机。 + /// + /// 要开始的有限状态机状态类型。 + void Start(Type stateType); + + /// + /// 是否存在有限状态机状态。 + /// + /// 要检查的有限状态机状态类型。 + /// 是否存在有限状态机状态。 + bool HasState() where TState : FsmState; + + /// + /// 是否存在有限状态机状态。 + /// + /// 要检查的有限状态机状态类型。 + /// 是否存在有限状态机状态。 + bool HasState(Type stateType); + + /// + /// 获取有限状态机状态。 + /// + /// 要获取的有限状态机状态类型。 + /// 要获取的有限状态机状态。 + TState GetState() where TState : FsmState; + + /// + /// 获取有限状态机状态。 + /// + /// 要获取的有限状态机状态类型。 + /// 要获取的有限状态机状态。 + FsmState GetState(Type stateType); + + /// + /// 获取有限状态机的所有状态。 + /// + /// 有限状态机的所有状态。 + FsmState[] GetAllStates(); + + /// + /// 获取有限状态机的所有状态。 + /// + /// 有限状态机的所有状态。 + void GetAllStates(List> results); + + /// + /// 是否存在有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 有限状态机数据是否存在。 + bool HasData(string name); + + /// + /// 获取有限状态机数据。 + /// + /// 要获取的有限状态机数据的类型。 + /// 有限状态机数据名称。 + /// 要获取的有限状态机数据。 + TData GetData(string name); + + /// + /// 获取有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 要获取的有限状态机数据。 + object GetData(string name); + + /// + /// 设置有限状态机数据。 + /// + /// 要设置的有限状态机数据的类型。 + /// 有限状态机数据名称。 + /// 要设置的有限状态机数据。 + void SetData(string name, TData data); + + /// + /// 设置有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 要设置的有限状态机数据。 + void SetData(string name, object data); + + /// + /// 移除有限状态机数据。 + /// + /// 有限状态机数据名称。 + /// 是否移除有限状态机数据成功。 + bool RemoveData(string name); + + /// + /// 切换状态机 + /// + /// + void ChangeState() where TState : FsmState; + } +} diff --git a/Assets/TEngine/Runtime/Fsm/IFsm.cs.meta b/Assets/TEngine/Runtime/Fsm/IFsm.cs.meta new file mode 100644 index 00000000..f070a8b6 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/IFsm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65550ee2887b2fc4097289b3d9103891 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Fsm/IFsmManager.cs b/Assets/TEngine/Runtime/Fsm/IFsmManager.cs new file mode 100644 index 00000000..2c2ad8d6 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/IFsmManager.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; + +namespace TEngine.Fsm +{ + /// + /// 有限状态机管理器。 + /// + public interface IFsmManager + { + /// + /// 获取有限状态机数量。 + /// + int Count + { + get; + } + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + bool HasFsm() where T : class; + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否存在有限状态机。 + bool HasFsm(Type ownerType); + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + bool HasFsm(string name) where T : class; + + /// + /// 检查是否存在有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 是否存在有限状态机。 + bool HasFsm(Type ownerType, string name); + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + IFsm GetFsm() where T : class; + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要获取的有限状态机。 + FsmBase GetFsm(Type ownerType); + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + IFsm GetFsm(string name) where T : class; + + /// + /// 获取有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 要获取的有限状态机。 + FsmBase GetFsm(Type ownerType, string name); + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + FsmBase[] GetAllFsms(); + + /// + /// 获取所有有限状态机。 + /// + /// 所有有限状态机。 + void GetAllFsms(List results); + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + IFsm CreateFsm(T owner, params FsmState[] states) where T : class; + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + IFsm CreateFsm(string name, T owner, params FsmState[] states) where T : class; + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + IFsm CreateFsm(T owner, List> states) where T : class; + + /// + /// 创建有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 有限状态机名称。 + /// 有限状态机持有者。 + /// 有限状态机状态集合。 + /// 要创建的有限状态机。 + IFsm CreateFsm(string name, T owner, List> states) where T : class; + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm() where T : class; + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(Type ownerType); + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(string name) where T : class; + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机名称。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(Type ownerType, string name); + + /// + /// 销毁有限状态机。 + /// + /// 有限状态机持有者类型。 + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(IFsm fsm) where T : class; + + /// + /// 销毁有限状态机。 + /// + /// 要销毁的有限状态机。 + /// 是否销毁有限状态机成功。 + bool DestroyFsm(FsmBase fsm); + } +} diff --git a/Assets/TEngine/Runtime/Fsm/IFsmManager.cs.meta b/Assets/TEngine/Runtime/Fsm/IFsmManager.cs.meta new file mode 100644 index 00000000..1339eab8 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/IFsmManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d57006ef47615e34e915854cdbd234bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/Fsm/TypeNamePair.cs b/Assets/TEngine/Runtime/Fsm/TypeNamePair.cs new file mode 100644 index 00000000..281c8463 --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/TypeNamePair.cs @@ -0,0 +1,128 @@ +using System; +using System.Runtime.InteropServices; + +namespace TEngine +{ + /// + /// ͺƵֵ + /// + [StructLayout(LayoutKind.Auto)] + internal struct TypeNamePair : IEquatable + { + private readonly Type m_Type; + private readonly string m_Name; + + /// + /// ʼͺƵֵʵ + /// + /// ͡ + public TypeNamePair(Type type) + : this(type, string.Empty) + { + } + + /// + /// ʼͺƵֵʵ + /// + /// ͡ + /// ơ + public TypeNamePair(Type type, string name) + { + if (type == null) + { + throw new Exception("Type is invalid."); + } + + m_Type = type; + m_Name = name ?? string.Empty; + } + + /// + /// ȡ͡ + /// + public Type Type + { + get + { + return m_Type; + } + } + + /// + /// ȡơ + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// ȡͺƵֵַ + /// + /// ͺƵֵַ + public override string ToString() + { + if (m_Type == null) + { + throw new Exception("Type is invalid."); + } + + string typeName = m_Type.FullName; + return string.IsNullOrEmpty(m_Name) ? typeName : string.Format("{0}.{1}", typeName, m_Name); + } + + /// + /// ȡĹϣֵ + /// + /// Ĺϣֵ + public override int GetHashCode() + { + return m_Type.GetHashCode() ^ m_Name.GetHashCode(); + } + + /// + /// Ƚ϶Ƿȡ + /// + /// ҪȽϵĶ + /// ȽϵĶǷȡ + public override bool Equals(object obj) + { + return obj is TypeNamePair && Equals((TypeNamePair)obj); + } + + /// + /// Ƚ϶Ƿȡ + /// + /// ҪȽϵĶ + /// ȽϵĶǷȡ + public bool Equals(TypeNamePair value) + { + return m_Type == value.m_Type && m_Name == value.m_Name; + } + + /// + /// жǷȡ + /// + /// ֵ a + /// ֵ b + /// Ƿȡ + public static bool operator ==(TypeNamePair a, TypeNamePair b) + { + return a.Equals(b); + } + + /// + /// жǷȡ + /// + /// ֵ a + /// ֵ b + /// Ƿȡ + public static bool operator !=(TypeNamePair a, TypeNamePair b) + { + return !(a == b); + } + } +} diff --git a/Assets/TEngine/Runtime/Fsm/TypeNamePair.cs.meta b/Assets/TEngine/Runtime/Fsm/TypeNamePair.cs.meta new file mode 100644 index 00000000..6e3c067f --- /dev/null +++ b/Assets/TEngine/Runtime/Fsm/TypeNamePair.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3185e3f5b6cd2f04ebff57b9c5a80b07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: