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 pool))
{
pool = new Stack();
Pools[key] = pool;
}
var obj = pool.Count > 0
? pool.Pop()
: Create(key);
obj.OnAcquire();
return obj;
}
///
/// 将对象释放回对象池中
///
/// 对象池的键值
/// 需要释放的对象
public void Release(TKey key, TObject obj)
{
obj.OnRelease();
if (!Pools.TryGetValue(key, out var pool))
{
pool = new Stack();
Pools[key] = pool;
}
pool.Push(obj);
}
///
/// 清空所有对象池,销毁所有池中的对象并清理池容器
///
public void Clear()
{
// 遍历所有对象池,调用每个对象的销毁方法
foreach (var obj in Pools.Values.SelectMany(pool => pool))
{
obj.OnPoolDestroy();
}
Pools.Clear();
}
///
/// 创建一个新的对象实例(由子类决定怎么创建)
///
/// 用于创建对象的键值
/// 新创建的对象实例
protected abstract TObject Create(TKey key);
///
/// 系统销毁时的清理操作,清空所有对象池
///
protected override void OnDestroy()
{
Clear();
}
}