using System.Diagnostics; using GFramework.Core.Abstractions.pool; using GFramework.Core.system; namespace GFramework.Core.pool; /// /// 抽象对象池系统,提供基于键值的对象池管理功能 /// /// 对象池的键类型,必须不为null /// 池化对象类型,必须实现IPoolableObject接口 public abstract class AbstractObjectPoolSystem : AbstractSystem, IObjectPoolSystem where TObject : IPoolableObject where TKey : notnull { /// /// 存储对象池的字典,键为池标识,值为池信息 /// protected readonly Dictionary Pools = new(); /// /// 获取对象池中的对象,如果池中没有可用对象则创建新的对象 /// /// 对象池的键值 /// 获取到的对象实例 public TObject Acquire(TKey key) { if (!Pools.TryGetValue(key, out var poolInfo)) { poolInfo = new PoolInfo(); Pools[key] = poolInfo; } TObject obj; if (poolInfo.Stack.Count > 0) { obj = poolInfo.Stack.Pop(); } else { obj = Create(key); poolInfo.TotalCreated++; } poolInfo.TotalAcquired++; poolInfo.ActiveCount++; obj.OnAcquire(); return obj; } /// /// 将对象释放回对象池中 /// /// 对象池的键值 /// 需要释放的对象 public void Release(TKey key, TObject obj) { obj.OnRelease(); if (!Pools.TryGetValue(key, out var poolInfo)) { poolInfo = new PoolInfo(); Pools[key] = poolInfo; } poolInfo.TotalReleased++; // 防止 ActiveCount 变为负数 if (poolInfo.ActiveCount > 0) { poolInfo.ActiveCount--; } else { // 记录警告:检测到可能的双重释放或错误释放 Debug.WriteLine( $"[ObjectPool] Warning: Attempting to release object for key '{key}' " + $"but ActiveCount is already 0. Possible double-release or incorrect key."); } // 检查容量限制 if (poolInfo.MaxCapacity > 0 && poolInfo.Stack.Count >= poolInfo.MaxCapacity) { // 超过容量限制,销毁对象 obj.OnPoolDestroy(); poolInfo.TotalDestroyed++; } else { poolInfo.Stack.Push(obj); } } /// /// 清空所有对象池,销毁所有池中的对象并清理池容器 /// public void Clear() { // 遍历所有对象池,调用每个对象的销毁方法 foreach (var poolInfo in Pools.Values) { foreach (var obj in poolInfo.Stack) { obj.OnPoolDestroy(); } } Pools.Clear(); } /// /// 获取指定池的当前大小 /// /// 对象池的键 /// 池中可用对象的数量 public int GetPoolSize(TKey key) { return Pools.TryGetValue(key, out var poolInfo) ? poolInfo.Stack.Count : 0; } /// /// 获取指定池的活跃对象数量 /// /// 对象池的键 /// 已被获取但未释放的对象数量 public int GetActiveCount(TKey key) { return Pools.TryGetValue(key, out var poolInfo) ? poolInfo.ActiveCount : 0; } /// /// 设置指定池的最大容量 /// /// 对象池的键 /// 池中保留的最大对象数量。超过此数量时,释放的对象将被销毁而不是放回池中。设置为 0 表示无限制。 public void SetMaxCapacity(TKey key, int maxCapacity) { if (!Pools.TryGetValue(key, out var poolInfo)) { poolInfo = new PoolInfo(); Pools[key] = poolInfo; } poolInfo.MaxCapacity = maxCapacity; } /// /// 预热对象池,提前创建指定数量的对象 /// /// 对象池的键 /// 要预创建的对象数量 public void Prewarm(TKey key, int count) { if (!Pools.TryGetValue(key, out var poolInfo)) { poolInfo = new PoolInfo(); Pools[key] = poolInfo; } for (var i = 0; i < count; i++) { var obj = Create(key); poolInfo.TotalCreated++; obj.OnRelease(); poolInfo.Stack.Push(obj); } } /// /// 获取指定池的统计信息 /// /// 对象池的键 /// 池的统计信息 public PoolStatistics GetStatistics(TKey key) { if (!Pools.TryGetValue(key, out var poolInfo)) { return new PoolStatistics { AvailableCount = 0, ActiveCount = 0, MaxCapacity = 0, TotalCreated = 0, TotalAcquired = 0, TotalReleased = 0, TotalDestroyed = 0 }; } return new PoolStatistics { AvailableCount = poolInfo.Stack.Count, ActiveCount = poolInfo.ActiveCount, MaxCapacity = poolInfo.MaxCapacity, TotalCreated = poolInfo.TotalCreated, TotalAcquired = poolInfo.TotalAcquired, TotalReleased = poolInfo.TotalReleased, TotalDestroyed = poolInfo.TotalDestroyed }; } /// /// 创建一个新的对象实例(由子类决定怎么创建) /// /// 用于创建对象的键值 /// 新创建的对象实例 protected abstract TObject Create(TKey key); /// /// 系统销毁时的清理操作,清空所有对象池 /// protected override void OnDestroy() { Clear(); } /// /// 池信息类,用于管理对象池的核心数据结构和统计信息。 /// 包含对象栈、容量限制以及各类操作的统计计数。 /// protected class PoolInfo { /// /// 对象栈,用于存储可复用的对象实例。 /// public Stack Stack { get; } = new(); /// /// 池中保留的最大对象数量。当释放对象时,如果池中对象数已达到此限制, /// 对象将被销毁而不是放回池中。设置为 0 表示无限制。 /// public int MaxCapacity { get; set; } /// /// 总共创建的对象数量统计。 /// public int TotalCreated { get; set; } /// /// 总共从池中获取的对象数量统计。 /// public int TotalAcquired { get; set; } /// /// 总共归还到池中的对象数量统计。 /// public int TotalReleased { get; set; } /// /// 总共销毁的对象数量统计。 /// public int TotalDestroyed { get; set; } /// /// 当前活跃(正在使用)的对象数量统计。 /// public int ActiveCount { get; set; } } }