From 958364080f889abb03729db844a2b0d0d1052e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com> Date: Tue, 18 Nov 2025 16:15:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0procedure=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/FSM/FsmDebuggerWindow.cs | 4 +- Runtime/FSM/FsmComponent.cs | 4 +- Runtime/FSM/FsmModule.cs | 2 +- Runtime/FSM/HighPerfFSM.cs | 2 +- Runtime/FSM/IFsmModule.cs | 2 +- Runtime/FSM/SimpleFSM.cs | 251 ------------------- Runtime/FSM/SimpleFSM.cs.meta | 3 - Runtime/Procedure.meta | 3 + Runtime/Procedure/IProcedureModule.cs | 13 + Runtime/Procedure/IProcedureModule.cs.meta | 3 + Runtime/Procedure/ProcedureBase.cs | 72 ++++++ Runtime/Procedure/ProcedureBase.cs.meta | 3 + Runtime/Procedure/ProcedureComponent.cs | 21 ++ Runtime/Procedure/ProcedureComponent.cs.meta | 3 + Runtime/Procedure/ProcedureModule.cs | 132 ++++++++++ Runtime/Procedure/ProcedureModule.cs.meta | 3 + 16 files changed, 259 insertions(+), 262 deletions(-) delete mode 100644 Runtime/FSM/SimpleFSM.cs delete mode 100644 Runtime/FSM/SimpleFSM.cs.meta create mode 100644 Runtime/Procedure.meta create mode 100644 Runtime/Procedure/IProcedureModule.cs create mode 100644 Runtime/Procedure/IProcedureModule.cs.meta create mode 100644 Runtime/Procedure/ProcedureBase.cs create mode 100644 Runtime/Procedure/ProcedureBase.cs.meta create mode 100644 Runtime/Procedure/ProcedureComponent.cs create mode 100644 Runtime/Procedure/ProcedureComponent.cs.meta create mode 100644 Runtime/Procedure/ProcedureModule.cs create mode 100644 Runtime/Procedure/ProcedureModule.cs.meta diff --git a/Editor/FSM/FsmDebuggerWindow.cs b/Editor/FSM/FsmDebuggerWindow.cs index c7da860..af7a4b0 100644 --- a/Editor/FSM/FsmDebuggerWindow.cs +++ b/Editor/FSM/FsmDebuggerWindow.cs @@ -1,6 +1,4 @@ -// ===================== FSMDebugger Window (unchanged API, auto-binding now) ===================== - -using AlicizaX.Fsm; +using AlicizaX; using UnityEditor; using UnityEngine; diff --git a/Runtime/FSM/FsmComponent.cs b/Runtime/FSM/FsmComponent.cs index 57a725c..206b3f3 100644 --- a/Runtime/FSM/FsmComponent.cs +++ b/Runtime/FSM/FsmComponent.cs @@ -1,10 +1,10 @@ using AlicizaX; -using AlicizaX.Fsm; + using System; using System.Collections.Generic; using UnityEngine; -namespace AlicizaX.Fsm.Runtime +namespace AlicizaX { /// /// 有限状态机组件。 diff --git a/Runtime/FSM/FsmModule.cs b/Runtime/FSM/FsmModule.cs index b408ee8..a80c774 100644 --- a/Runtime/FSM/FsmModule.cs +++ b/Runtime/FSM/FsmModule.cs @@ -5,7 +5,7 @@ using UnityEngine; using UnityEngine.Scripting; using Object = UnityEngine.Object; -namespace AlicizaX.Fsm.Runtime +namespace AlicizaX { [Preserve] internal sealed class FsmModule : IFsmModule diff --git a/Runtime/FSM/HighPerfFSM.cs b/Runtime/FSM/HighPerfFSM.cs index 5806ace..5e972b2 100644 --- a/Runtime/FSM/HighPerfFSM.cs +++ b/Runtime/FSM/HighPerfFSM.cs @@ -4,7 +4,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Threading; -namespace AlicizaX.Fsm +namespace AlicizaX { internal interface IFsmRunner : IDisposable, IMemory { diff --git a/Runtime/FSM/IFsmModule.cs b/Runtime/FSM/IFsmModule.cs index d5f3617..1c62a2b 100644 --- a/Runtime/FSM/IFsmModule.cs +++ b/Runtime/FSM/IFsmModule.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace AlicizaX.Fsm.Runtime +namespace AlicizaX { public interface IFsmModule : IModule, IModuleUpdate, IModuleAwake, IModuleLateUpdate { diff --git a/Runtime/FSM/SimpleFSM.cs b/Runtime/FSM/SimpleFSM.cs deleted file mode 100644 index 182ea45..0000000 --- a/Runtime/FSM/SimpleFSM.cs +++ /dev/null @@ -1,251 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using AlicizaX; - - -public interface IState -{ - IUltraFSM Fsm { get; set; } - bool IsRegistered { get; set; } - void Init(); - void Enter(); - void Exit(); - void Update(float deltaTime); - void Destroy(); -} - -public abstract class StateBase : IState where TState : Enum -{ - public IUltraFSM Fsm { get; set; } - public bool IsRegistered { get; set; } - - protected virtual void OnInit() - { - } - - protected virtual void OnEnter() - { - } - - protected virtual void OnExit() - { - } - - protected virtual void OnUpdate(float deltaTime) - { - } - - protected virtual void OnDestroy() - { - } - - void IState.Init() - { - OnInit(); - } - - void IState.Enter() - { - OnEnter(); - } - - void IState.Exit() - { - OnExit(); - } - - void IState.Update(float deltaTime) - { - OnUpdate(deltaTime); - } - - void IState.Destroy() - { - IsRegistered = false; - OnDestroy(); - } - - protected void SwitchState(TState newStateId) - { - (Fsm as SimpleFSM).SwitchState(newStateId); - } -} - - -public interface IUltraFSM -{ - string Name { get; } - string StateName { get; } - void Update(float deltaTime); - void Dispose(); -} - -public sealed class SimpleFSM : IUltraFSM where TState : Enum -{ - private IState[] _states; - private string _name; - private int _currentIndex = -1; - private int _registeredCount; - private TState _currentState; - - public string Name - { - get => _name; - } - - - public string StateName - { - get - { - if (_currentIndex == -1) - { - return "None"; - } - - return CurrentState.ToString(); - } - } - - - public TState CurrentState - { - get - { - if (_currentIndex == -1) - throw new InvalidOperationException("No current state."); - return _currentState; - } - } - - public SimpleFSM() - { - Initialize("None", 16); - } - - internal int Capacity => _states?.Length ?? 0; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int CalculateCapacity(int requested) - { - if (requested < 16) return 16; - requested--; - requested |= requested >> 1; - requested |= requested >> 2; - requested |= requested >> 4; - requested |= requested >> 8; - requested |= requested >> 16; - return requested + 1; - } - - internal void Initialize(string name, int minCapacity) - { - _name = name; - int newCapacity = CalculateCapacity(minCapacity); - _states ??= new IState[newCapacity]; - } - - private void Resize(int minCapacity) - { - int newCapacity = CalculateCapacity(minCapacity); - if (_states != null && _states.Length >= newCapacity) return; - Array.Resize(ref _states, newCapacity); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Register(TState stateId) where T : class, IState, new() - { - int stateIdValue = Convert.ToInt32(stateId); - if (stateIdValue < 0) - throw new ArgumentException("State ID must be non-negative."); - - if (stateIdValue >= _states.Length) - Resize(stateIdValue + 1); - - // 检查当前状态是否已注册,若存在则先释放 - var existingState = _states[stateIdValue]; - if (existingState != null && existingState.IsRegistered) - { - existingState.Destroy(); - _registeredCount--; - } - - IState state = default; - state = new T(); - - _states[stateIdValue] = state; - - if (!state.IsRegistered) - { - state.Fsm = this; - state.Init(); - state.IsRegistered = true; - _registeredCount++; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SwitchState(TState newStateId) - { - int newStateIdValue = Convert.ToInt32(newStateId); - if (newStateIdValue < 0 || newStateIdValue >= _states.Length) - throw new ArgumentOutOfRangeException(nameof(newStateId), "State ID is out of range."); - int prevIndex = _currentIndex; - int newIndex = newStateIdValue; - - if (prevIndex == newIndex) return; - - ExitState(prevIndex); - EnterState(newIndex); - _currentIndex = newIndex; - _currentState = newStateId; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Update(float deltaTime) - { - if ((uint)_currentIndex < (uint)_states.Length) - _states[_currentIndex]?.Update(deltaTime); - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ExitState(int index) - { - if ((uint)index < (uint)_states.Length) - _states[index]?.Exit(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void EnterState(int index) - { - if ((uint)index < (uint)_states.Length) - { - IState state = _states[index]; - if (state.IsRegistered) - state.Enter(); - } - } - - - public void Dispose() - { - if (_states == null) return; - - for (int i = 0; i < _states.Length; i++) - { - IState state = _states[i]; - if (state != null && state.IsRegistered) - { - state.Destroy(); - } - } - - // 清空数组引用,帮助 GC 回收内存 - Array.Clear(_states, 0, _states.Length); - _states = null; - - _currentIndex = -1; - _registeredCount = 0; - } -} diff --git a/Runtime/FSM/SimpleFSM.cs.meta b/Runtime/FSM/SimpleFSM.cs.meta deleted file mode 100644 index 5470ab1..0000000 --- a/Runtime/FSM/SimpleFSM.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 064e59389d6a4e61816e12e5de6848ed -timeCreated: 1756985353 \ No newline at end of file diff --git a/Runtime/Procedure.meta b/Runtime/Procedure.meta new file mode 100644 index 0000000..3aa3c2d --- /dev/null +++ b/Runtime/Procedure.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 131e0fd9dfe2470394ebf46fd2a9c781 +timeCreated: 1763450210 \ No newline at end of file diff --git a/Runtime/Procedure/IProcedureModule.cs b/Runtime/Procedure/IProcedureModule.cs new file mode 100644 index 0000000..f7be84e --- /dev/null +++ b/Runtime/Procedure/IProcedureModule.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace AlicizaX +{ + public interface IProcedureModule:IModule,IModuleUpdate + { + void InitializeProcedure(List availableProcedures, Type defaultProcedureType); + void ClearAllProcedures(); + bool SwitchProcedure() where T : IProcedure; + bool SwitchProcedure(Type procedureType); + } +} diff --git a/Runtime/Procedure/IProcedureModule.cs.meta b/Runtime/Procedure/IProcedureModule.cs.meta new file mode 100644 index 0000000..4585a5c --- /dev/null +++ b/Runtime/Procedure/IProcedureModule.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 18d5ca3d17384612b2d2023084b6a97b +timeCreated: 1763451617 \ No newline at end of file diff --git a/Runtime/Procedure/ProcedureBase.cs b/Runtime/Procedure/ProcedureBase.cs new file mode 100644 index 0000000..06bc46a --- /dev/null +++ b/Runtime/Procedure/ProcedureBase.cs @@ -0,0 +1,72 @@ +namespace AlicizaX +{ + public interface IProcedure + { + IProcedureModule ProcedureModule { get; set; } + void Init(); + void Enter(); + void Leave(); + void Update(); + void Destroy(); + } + + /// + /// 流程基类 - 使用模板方法模式定义流程生命周期 + /// + public abstract class ProcedureBase : IProcedure + { + public IProcedureModule ProcedureModule { get; set; } + + void IProcedure.Init() + { + OnInit(); + } + + void IProcedure.Enter() + { + OnEnter(); + } + + void IProcedure.Leave() + { + OnLeave(); + } + + void IProcedure.Update() + { + OnUpdate(); + } + + void IProcedure.Destroy() + { + OnDestroy(); + } + + + protected virtual void OnInit() + { + } + + protected virtual void OnEnter() + { + } + + protected virtual void OnLeave() + { + } + + protected virtual void OnUpdate() + { + } + + protected virtual void OnDestroy() + { + } + + + protected internal void SwitchProcedure() where T : ProcedureBase + { + ProcedureModule.SwitchProcedure(); + } + } +} diff --git a/Runtime/Procedure/ProcedureBase.cs.meta b/Runtime/Procedure/ProcedureBase.cs.meta new file mode 100644 index 0000000..dd173af --- /dev/null +++ b/Runtime/Procedure/ProcedureBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 367e3373495c49da9c1d85e9c5a68bf3 +timeCreated: 1763450223 \ No newline at end of file diff --git a/Runtime/Procedure/ProcedureComponent.cs b/Runtime/Procedure/ProcedureComponent.cs new file mode 100644 index 0000000..7df55d1 --- /dev/null +++ b/Runtime/Procedure/ProcedureComponent.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +namespace AlicizaX +{ + [DisallowMultipleComponent] + [AddComponentMenu("Game Framework/Procedure")] + public sealed class ProcedureComponent : MonoBehaviour + { + private IProcedureModule _mProcedureModule = null; + + private void Awake() + { + _mProcedureModule = ModuleSystem.RegisterModule(); + if (_mProcedureModule == null) + { + Log.Error("Procedure Module is invalid."); + return; + } + } + } +} diff --git a/Runtime/Procedure/ProcedureComponent.cs.meta b/Runtime/Procedure/ProcedureComponent.cs.meta new file mode 100644 index 0000000..dce34ef --- /dev/null +++ b/Runtime/Procedure/ProcedureComponent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c0a419f3af614cdda5267671f803dfdb +timeCreated: 1763451994 \ No newline at end of file diff --git a/Runtime/Procedure/ProcedureModule.cs b/Runtime/Procedure/ProcedureModule.cs new file mode 100644 index 0000000..695e698 --- /dev/null +++ b/Runtime/Procedure/ProcedureModule.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace AlicizaX +{ + internal class ProcedureModule : IProcedureModule + { + private readonly Dictionary _procedures = new Dictionary(); + private IProcedure _currentProcedure; + private IProcedure _defaultProcedure; + + + public void InitializeProcedure(List availableProcedures, Type defaultProcedureType) + { + _procedures.Clear(); + foreach (var procedure in availableProcedures) + { + var type = procedure.GetType(); + _procedures[type] = procedure; + procedure.ProcedureModule = this; + procedure.Init(); + } + + if (_procedures.ContainsKey(defaultProcedureType)) + { + _defaultProcedure = _procedures[defaultProcedureType]; + SwitchProcedure(defaultProcedureType); + } + else + { + Log.Info($"默认流程 {defaultProcedureType.Name} 未注册!"); + } + } + + + /// + /// + /// 清除所有流程 + /// + public void ClearAllProcedures() + { + if (_procedures != null) + { + foreach (var procedure in _procedures.Values) + { + procedure.Destroy(); + } + + _procedures.Clear(); + } + + _currentProcedure = null; + _defaultProcedure = null; + } + + public bool SwitchProcedure() where T : IProcedure + { + if (HasProcedure()) + { + return SwitchProcedure(typeof(T)); + } + + if (_defaultProcedure != null) + { + Debug.LogWarning($"流程 {typeof(T).Name} 不存在,切换到默认流程"); + return SwitchToDefault(); + } + + return false; + } + + + public bool SwitchProcedure(Type procedureType) + { + var nextProcedure = _procedures[procedureType]; + var lastProcedure = _currentProcedure; + + if (lastProcedure == nextProcedure) + return true; + + if (lastProcedure != null) + { + lastProcedure.Leave(); + } + + nextProcedure.Enter(); + _currentProcedure = nextProcedure; + + return true; + } + + + /// + /// 切换到默认流程 + /// + private bool SwitchToDefault() + { + if (_defaultProcedure != null) + { + return SwitchProcedure(_defaultProcedure.GetType()); + } + + return false; + } + + + /// + /// 检查是否存在指定类型的流程 + /// + private bool HasProcedure() where T : IProcedure + { + return _procedures.ContainsKey(typeof(T)); + } + + + void IModule.Dispose() + { + ClearAllProcedures(); + } + + public int Priority { get; } + + void IModuleUpdate.Update(float elapseSeconds, float realElapseSeconds) + { + if (_currentProcedure != null) + { + _currentProcedure.Update(); + } + } + } +} diff --git a/Runtime/Procedure/ProcedureModule.cs.meta b/Runtime/Procedure/ProcedureModule.cs.meta new file mode 100644 index 0000000..434e607 --- /dev/null +++ b/Runtime/Procedure/ProcedureModule.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4272c5c31b6b4a459f1da37a228cfd3f +timeCreated: 1763450372 \ No newline at end of file