122 lines
3.4 KiB
C#
122 lines
3.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using UnityEngine.Scripting;
|
|
|
|
namespace AlicizaX.Fsm.Runtime
|
|
{
|
|
// 新增非泛型接口
|
|
|
|
public struct FsmDebugInfo
|
|
{
|
|
public string FsmName;
|
|
public string CurrentStateName;
|
|
public int RegisteredStates;
|
|
}
|
|
|
|
[Preserve]
|
|
public sealed class FsmModule : IFsmModule
|
|
{
|
|
private const int DefaultPoolSize = 64;
|
|
private const int MaxPoolSize = 2048;
|
|
|
|
// 按类型分组的对象池和活动实例
|
|
private readonly Dictionary<Type, Stack<IUltraFSM>> _fsmPools = new();
|
|
private readonly Dictionary<Type, List<IUltraFSM>> _activeFsms = new();
|
|
|
|
public UltraFSM<TState> Create<TState>(string name, int initialCapacity = 8) where TState : struct, Enum
|
|
{
|
|
var stateType = typeof(TState);
|
|
// 初始化存储结构
|
|
if (!_fsmPools.ContainsKey(stateType))
|
|
{
|
|
_fsmPools[stateType] = new Stack<IUltraFSM>(DefaultPoolSize);
|
|
_activeFsms[stateType] = new List<IUltraFSM>(DefaultPoolSize);
|
|
}
|
|
|
|
// 从池中获取或新建实例
|
|
var fsm = _fsmPools[stateType].Count > 0
|
|
? (UltraFSM<TState>)_fsmPools[stateType].Pop()
|
|
: new UltraFSM<TState>();
|
|
|
|
fsm.Initialize(name, initialCapacity);
|
|
_activeFsms[stateType].Add(fsm);
|
|
return fsm;
|
|
}
|
|
|
|
public void Destroy<TState>(UltraFSM<TState> fsm) where TState : Enum
|
|
{
|
|
if (fsm.IsDisposed) return;
|
|
|
|
var stateType = typeof(TState);
|
|
if (!_activeFsms.TryGetValue(stateType, out var activeList)) return;
|
|
|
|
fsm?.Dispose();
|
|
|
|
// 回收实例到池
|
|
if (_fsmPools[stateType].Count < MaxPoolSize)
|
|
{
|
|
_fsmPools[stateType].Push(fsm);
|
|
}
|
|
|
|
// 从活动列表移除
|
|
activeList.Remove(fsm);
|
|
}
|
|
|
|
public List<FsmDebugInfo> GetDebugInfo()
|
|
{
|
|
var list = new List<FsmDebugInfo>();
|
|
foreach (var kvp in _activeFsms)
|
|
{
|
|
foreach (var fsm in kvp.Value)
|
|
{
|
|
list.Add(new FsmDebugInfo
|
|
{
|
|
FsmName = fsm.Name,
|
|
CurrentStateName = fsm.StateName,
|
|
});
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
void IModuleUpdate.Update(float elapseSeconds, float realElapseSeconds)
|
|
{
|
|
foreach (var kvp in _activeFsms)
|
|
{
|
|
foreach (var fsm in kvp.Value)
|
|
{
|
|
if (!fsm.IsDisposed)
|
|
{
|
|
fsm.Update(elapseSeconds);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void IModule.Dispose()
|
|
{
|
|
foreach (var pool in _fsmPools.Values)
|
|
{
|
|
while (pool.Count > 0)
|
|
{
|
|
pool.Pop().Dispose();
|
|
}
|
|
}
|
|
|
|
foreach (var activeList in _activeFsms.Values)
|
|
{
|
|
foreach (var fsm in activeList)
|
|
{
|
|
fsm?.Dispose();
|
|
}
|
|
|
|
activeList.Clear();
|
|
}
|
|
}
|
|
|
|
public int Priority => 0;
|
|
}
|
|
}
|