简介
在尝试写代码之前,我们要对将要学习的东西有一个大概的了解.比如这部分是用来做什么的.它可以做到什么.以及有什么好处之类的.
对象池的设计是用来避免物体频繁创建,销毁.使一个物体复用,从而节省资源.
源码
回收对象
首先我们要定义一个物体必须拥有两个方法,一个是回收时执行的方法,一个是再次使用时执行的方法,这部分我们用一个接口来实现
public interface IPoolObject {
void OnSpawn(BaseData baseData);//被生成时的回调
void OnUnSpawn();//被回收时的回调
}
对象池
一个简单的对象池至少要包含几个参数和方法.拥有了这些,一个简单的对象池就完成了.
储存所有被回收的实体,当创建实体时,优先从储存的实体中取出一个,不存在的话就创建新的实体
回收实体的时候,把物体隐藏起来,数据清空,储存在池子里等待使用.
然后记得在生成和回收方法里调用我们之前定义的接口,让我们在每个实体里就定义好回收相关的方法.
public class ObjectPool {
private List<BaseEntity> objects;//池内储存的全部对象
private readonly string assetPath;//资源路径
private readonly string group;//对象池名字
/// <summary>
/// 生成实体
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public T SpawnEntity<T>(BaseData data) where T:BaseEntity{
}
/// <summary>
/// 回收实体
/// </summary>
/// <param name="baseEntity"></param>
public void UnSpawnEntity(BaseEntity baseEntity) {
}
/// <summary>
/// 创建实体
/// </summary>
/// <returns></returns>
private T CreateEntity<T>() where T : BaseEntity{
}
}
管理器
实际上我们有很多种实体都需要对象池,所以我们还需要一个管理池子的对象池管理器.它包含以下重要方法
我们用一个字典pools储存全部的对象池,通过实体的group名字来查找
因为管理器对于池子来说是更高级的模块,所以我们的管理器执行的回收,创建实体的方法,实际都是调用对应的池子来实现的,我们已经写好了池子怎么处理回收那些实体,而管理器负责创建,销毁池子,并调用池子完成实体的生成与创建
public sealed class PoolManager : BaseSingleTon<PoolManager> ,IModule{
Dictionary<string, ObjectPool> pools = new Dictionary<string, ObjectPool>();//全部对象池 根据entityGroup得到对应的pool
/// <summary>
/// 生成实体
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public T SpawnEntity<T>(BaseData data) where T : BaseEntity
{
}
/// <summary>
/// 回收实体
/// </summary>
/// <param name="baseEntity"></param>
public void UnSpawnEntity(BaseEntity baseEntity) {
}
/// <summary>
/// 创建对象池
/// </summary>
/// <param name="capacity">最大容量</param>
/// <param name="expireTime">最大储存时间</param>
/// <param name="name">对象池名字=实体group名字</param>
/// <param name="assetPath">资源路径</param>
/// <returns></returns>
public ObjectPool CreateObjectPool(int capacity, int expireTime, string name, string assetPath){
}
/// <summary>
/// 获取某个池
/// </summary>
/// <param name="group"></param>
/// <returns></returns>
private ObjectPool GetObjectPool(string group) {
}
/// <summary>
/// 对象池被销毁时的回调 从管理器的列表中撤销掉
/// </summary>
/// <param name="group"></param>
private void OnPoolDestroy(string group) {
}
}
扩展
如果我们为每一个类型的实体写一种池子,工作量会很大.所以我们用泛型的方式一劳永逸.
池子的回收与创建有时候不太容易管理,我们更希望它会自动清理一些长时间不用的实体,所以我们可以加入过期时间的判定,以及储存容量上的判定.来清除一些不频繁使用的实体.达到自动回收的目的.