using System; using System.Runtime.CompilerServices; using AlicizaX; public interface IState : IMemory { 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 void Clear() { IsRegistered = false; Fsm = null; } public bool fromPool { get; set; } 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, IMemory, 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(); MemoryPool.Release(existingState); _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; } }