就Unity游戏开发来说,对象池是一个非常重要的资源管理手段。提供对象缓存池的功能,避免频繁地创建和销毁各种游戏对象,提高游戏性能。除了 Game Framework 自身使用了对象池,用户还可以很方便地创建和管理自己的对象池。
E神
伪代码结构参照https://blog.csdn.net/yupu56/article/details/110206648?spm=1001.2014.3001.5501
伪代码
ObjectPoolManager
ObjectPoolManager 是管理不同对象池的总类 对象池的具体对象管理逻辑会在ObjectPool里面
public class ObjectPoolManager
{
private const int DefaultCapacity = int.MaxValue;//默认容量
private const float DefaultExpireTime = float.MaxValue;//默认释放时间
private const int DefaultPriority = 0;//默认优先级
private readonly Dictionary<TypeNamePair, ObjectPoolBase> m_ObjectPools;
private readonly List<ObjectPoolBase> m_CachedAllObjectPools;
private readonly Comparison<ObjectPoolBase> m_ObjectPoolComparer;
/// <summary>
/// 初始化对象池管理器的新实例。
/// </summary>
public ObjectPoolManager()
{
m_ObjectPools = new Dictionary<TypeNamePair, ObjectPoolBase>();
m_CachedAllObjectPools = new List<ObjectPoolBase>();
m_ObjectPoolComparer = ObjectPoolComparer;
}
public int Priority;/// 获取游戏框架模块优先级。优先级较高的模块会优先轮询,并且关闭操作会后进行
public int Count;/// 获取对象池数量。
/// <summary>
/// 对象池管理器轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
internal override void Update(float elapseSeconds, float realElapseSeconds)
{
foreach (KeyValuePair<TypeNamePair, ObjectPoolBase> objectPool in m_ObjectPools)
{
objectPool.Value.Update(elapseSeconds, realElapseSeconds);
}
}
/// <summary>
/// 获取对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <returns>要获取的对象池。</returns>
public IObjectPool<T> GetObjectPool<T>() where T : ObjectBase
{
return (IObjectPool<T>)InternalGetObjectPool(new TypeNamePair(typeof(T)));
}
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <returns>要创建的允许单次获取的对象池。</returns>
public IObjectPool<T> CreateSingleSpawnObjectPool<T>() where T : ObjectBase
{
return InternalCreateObjectPool<T>(string.Empty, false, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority);
}
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <returns>要创建的允许多次获取的对象池。</returns>
public ObjectPoolBase CreateMultiSpawnObjectPool<T>()
{
return InternalCreateObjectPool<T>(string.Empty, true, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority);
}
}
ObjectPool
可以看到 ObjectPool 对泛型Object<T>类型进行管理
提供了对象获取,回收与释放方法
提供了对象定时自动释放功能
/// <summary>
/// 泛型T的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
private sealed class ObjectPool<T> : ObjectPoolBase, IObjectPool<T> where T : ObjectBase
{
private readonly GameFrameworkMultiDictionary<string, Object<T>> m_Objects;
private readonly Dictionary<object, Object<T>> m_ObjectMap;
private readonly List<T> m_CachedCanReleaseObjects;
private readonly List<T> m_CachedToReleaseObjects;
public override Type ObjectType/// 获取对象池对象类型。
public override int Count/// 获取对象池中对象的数量。
public override int CanReleaseCount/// 获取对象池中能被释放的对象的数量。
public override bool AllowMultiSpawn/// 获取是否允许对象被多次获取。
public override float AutoReleaseInterval/// 获取或设置对象池自动释放可释放对象的间隔秒数。
public override int Capacity/// 获取或设置对象池的容量。
public override float ExpireTime/// 获取或设置对象池对象过期秒数。
public override int Priority/// 获取或设置对象池的优先级。
/// <summary>
/// 创建对象。
/// </summary>
/// <param name="obj">对象。</param>
/// <param name="spawned">对象是否已被获取。</param>
public void Register(T obj, bool spawned)
{
if (obj == null)
{
throw new GameFrameworkException("Object is invalid.");
}
Object<T> internalObject = Object<T>.Create(obj, spawned);
m_Objects.Add(obj.Name, internalObject);
m_ObjectMap.Add(obj.Target, internalObject);
if (Count > m_Capacity)
{
Release();
}
}
/// <summary>
/// 获取对象。
/// </summary>
/// <returns>要获取的对象。</returns>
public T Spawn()
{
return Spawn(string.Empty);
}
/// <summary>
/// 回收对象。
/// </summary>
/// <param name="obj">要回收的对象。</param>
public void Unspawn(T obj)
{
if (obj == null)
{
throw new GameFrameworkException("Object is invalid.");
}
Unspawn(obj.Target);
}
//对象池的自动释放机制
internal override void Update(float elapseSeconds, float realElapseSeconds)
{
m_AutoReleaseTime += realElapseSeconds;
if (m_AutoReleaseTime < m_AutoReleaseInterval)
{
return;
}
Release();
}
/// <summary>
/// 释放对象池中的可释放对象。
/// </summary>
public override void Release()
{
Release(Count - m_Capacity, m_DefaultReleaseObjectFilterCallback);
}
}
Object<T>
Object<T>相当于给T类型规定了共同的行为
/// <summary>
/// 内部对象。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
private sealed class Object<T> : IReference where T : ObjectBase
{
private T m_Object;
private int m_SpawnCount;
/// <summary>
/// 创建内部对象。
/// </summary>
/// <param name="obj">对象。</param>
/// <param name="spawned">对象是否已被获取。</param>
/// <returns>创建的内部对象。</returns>
public static Object<T> Create(T obj, bool spawned)
{
Object<T> internalObject = ReferencePool.Acquire<Object<T>>();
internalObject.m_Object = obj;
internalObject.m_SpawnCount = spawned ? 1 : 0;
if (spawned)
{
obj.OnSpawn();
}
return internalObject;
}
/// <summary>
/// 获取对象。
/// </summary>
/// <returns>对象。</returns>
public T Spawn()
{
m_SpawnCount++;
m_Object.LastUseTime = DateTime.Now;
m_Object.OnSpawn();
return m_Object;
}
/// <summary>
/// 回收对象。
/// </summary>
public void Unspawn()
{
m_Object.OnUnspawn();
m_Object.LastUseTime = DateTime.Now;
m_SpawnCount--;
if (m_SpawnCount < 0)
{
throw new GameFrameworkException(Utility.Text.Format("Object '{0}' spawn count is less than 0.", Name));
}
}
/// <summary>
/// 释放对象。
/// </summary>
/// <param name="isShutdown">是否是关闭对象池时触发。</param>
public void Release(bool isShutdown)
{
m_Object.Release(isShutdown);
ReferencePool.Release(m_Object);
}
}
小结
GF对象池实现了对象池的基本功能
多个对象池的统一管理
对象的获取回收与释放,对象的复用
对象的自动释放机制
Comments | NOTHING