diff --git a/GFramework.Core.Abstractions/pool/IObjectPoolSystem.cs b/GFramework.Core.Abstractions/pool/IObjectPoolSystem.cs new file mode 100644 index 0000000..074eba2 --- /dev/null +++ b/GFramework.Core.Abstractions/pool/IObjectPoolSystem.cs @@ -0,0 +1,30 @@ +namespace GFramework.Core.Abstractions.pool; + +/// +/// 对象池系统接口,定义了对象池的基本操作 +/// +/// 池键的类型 +/// 池中对象的类型,必须实现IPoolableObject接口 +public interface IObjectPoolSystem + where TObject : IPoolableObject + where TKey : notnull +{ + /// + /// 从对象池中获取一个对象实例 + /// + /// 对象池的键 + /// 池中的对象实例,如果池中没有可用对象则创建新实例 + TObject Acquire(TKey key); + + /// + /// 将对象释放回对象池 + /// + /// 对象池的键 + /// 要释放的对象 + void Release(TKey key, TObject obj); + + /// + /// 清空所有对象池 + /// + void Clear(); +} \ No newline at end of file diff --git a/GFramework.Core.Abstractions/pool/IPoolableObject.cs b/GFramework.Core.Abstractions/pool/IPoolableObject.cs new file mode 100644 index 0000000..fbe0404 --- /dev/null +++ b/GFramework.Core.Abstractions/pool/IPoolableObject.cs @@ -0,0 +1,22 @@ +namespace GFramework.Core.Abstractions.pool; + +/// +/// 定义可池化对象的接口,提供对象在池中的生命周期管理方法 +/// +public interface IPoolableObject +{ + /// + /// 当对象从池中被获取时调用,用于初始化或重置对象状态 + /// + void OnAcquire(); + + /// + /// 当对象被释放回池中时调用,用于清理或重置对象状态以便下次使用 + /// + void OnRelease(); + + /// + /// 当对象池被销毁时调用,用于执行最终的清理工作 + /// + void OnPoolDestroy(); +} \ No newline at end of file diff --git a/GFramework.Core/pool/AbstractObjectPoolSystem.cs b/GFramework.Core/pool/AbstractObjectPoolSystem.cs new file mode 100644 index 0000000..9e84622 --- /dev/null +++ b/GFramework.Core/pool/AbstractObjectPoolSystem.cs @@ -0,0 +1,86 @@ +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(); + } +} \ No newline at end of file diff --git a/GFramework.Godot/pool/AbstractNodePoolSystem.cs b/GFramework.Godot/pool/AbstractNodePoolSystem.cs new file mode 100644 index 0000000..1941993 --- /dev/null +++ b/GFramework.Godot/pool/AbstractNodePoolSystem.cs @@ -0,0 +1,32 @@ +using GFramework.Core.pool; +using Godot; + +namespace GFramework.Godot.pool; + +/// +/// 抽象节点对象池系统,用于管理Godot节点类型的对象池 +/// +/// 用作键的类型,必须不为null +/// 节点类型,必须继承自Node并实现IPoolableNode接口 +public abstract class AbstractNodePoolSystem + : AbstractObjectPoolSystem + where TKey : notnull + where TNode : Node, IPoolableNode +{ + /// + /// 加载场景的抽象方法 + /// + /// 用于标识场景的键 + /// 加载的PackedScene对象 + protected abstract PackedScene LoadScene(TKey key); + + /// + /// 创建新节点实例的重写方法 + /// + /// 用于创建节点的键 + /// 创建的新节点实例 + protected override TNode Create(TKey key) + { + return LoadScene(key).Instantiate(); + } +} \ No newline at end of file diff --git a/GFramework.Godot/pool/IPoolableNode.cs b/GFramework.Godot/pool/IPoolableNode.cs new file mode 100644 index 0000000..e4a1282 --- /dev/null +++ b/GFramework.Godot/pool/IPoolableNode.cs @@ -0,0 +1,17 @@ +using GFramework.Core.Abstractions.pool; +using Godot; + +namespace GFramework.Godot.pool; + +/// +/// 可池化节点接口,继承自IPoolableObject接口 +/// 用于定义可以被对象池管理的Godot节点类型 +/// +public interface IPoolableNode : IPoolableObject +{ + /// + /// 将当前对象转换为Node类型 + /// + /// 返回当前对象对应的Node实例 + Node AsNode(); +} \ No newline at end of file