180 lines
5.7 KiB
C#
180 lines
5.7 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using System.Reflection;
|
|
using System.Collections.Generic;
|
|
|
|
namespace SK.Framework
|
|
{
|
|
public static class MonoObjectPool
|
|
{
|
|
/// <summary>
|
|
/// 从对象池中获取实例
|
|
/// </summary>
|
|
/// <typeparam name="T">对象类型</typeparam>
|
|
/// <returns>对象实例</returns>
|
|
public static T Allocate<T>() where T : MonoBehaviour, IPoolable
|
|
{
|
|
return MonoObjectPool<T>.Instance.Allocate();
|
|
}
|
|
/// <summary>
|
|
/// 回收对象
|
|
/// </summary>
|
|
/// <typeparam name="T">对象类型</typeparam>
|
|
/// <param name="t">回收对象实例</param>
|
|
/// <returns>回收成功返回true 否则返回false</returns>
|
|
public static bool Recycle<T>(T t) where T : MonoBehaviour, IPoolable
|
|
{
|
|
return MonoObjectPool<T>.Instance.Recycle(t);
|
|
}
|
|
/// <summary>
|
|
/// 释放对象池
|
|
/// </summary>
|
|
/// <typeparam name="T">对象类型</typeparam>
|
|
public static void Release<T>() where T : MonoBehaviour, IPoolable
|
|
{
|
|
MonoObjectPool<T>.Instance.Release();
|
|
}
|
|
/// <summary>
|
|
/// 设置对象池缓存数量上限
|
|
/// </summary>
|
|
/// <typeparam name="T">对象类型</typeparam>
|
|
/// <param name="maxCacheCount">缓存数量上限</param>
|
|
public static void SetMaxCacheCount<T>(int maxCacheCount) where T : MonoBehaviour, IPoolable
|
|
{
|
|
MonoObjectPool<T>.Instance.MaxCacheCount = maxCacheCount;
|
|
}
|
|
/// <summary>
|
|
/// 设置对象创建方法
|
|
/// </summary>
|
|
/// <typeparam name="T">对象类型</typeparam>
|
|
/// <param name="createMethod">创建方法</param>
|
|
public static void CreateBy<T>(Func<T> createMethod) where T : MonoBehaviour, IPoolable
|
|
{
|
|
MonoObjectPool<T>.Instance.CreateBy(createMethod);
|
|
}
|
|
|
|
}
|
|
public class MonoObjectPool<T> : IObjectPool<T> where T : MonoBehaviour, IPoolable
|
|
{
|
|
private static MonoObjectPool<T> instance;
|
|
//对象池缓存数量上限 默认9
|
|
private int maxCacheCount = 9;
|
|
//对象池
|
|
private readonly Stack<T> pool = new Stack<T>();
|
|
//创建方法
|
|
private Func<T> createMethod;
|
|
|
|
public static MonoObjectPool<T> Instance
|
|
{
|
|
get
|
|
{
|
|
if (null == instance)
|
|
{
|
|
var ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.Public);
|
|
var index = Array.FindIndex(ctors, m => m.GetParameters().Length == 0);
|
|
if (index == -1)
|
|
{
|
|
Debug.LogError($"{typeof(MonoObjectPool<T>)} 类型不具有公有无参构造函数.");
|
|
}
|
|
else
|
|
{
|
|
instance = Activator.CreateInstance<MonoObjectPool<T>>();
|
|
}
|
|
}
|
|
return instance;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 当前池中缓存的数量
|
|
/// </summary>
|
|
public int CurrentCacheCount
|
|
{
|
|
get
|
|
{
|
|
return pool.Count;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 缓存数量上限
|
|
/// </summary>
|
|
public int MaxCacheCount
|
|
{
|
|
get
|
|
{
|
|
return maxCacheCount;
|
|
}
|
|
set
|
|
{
|
|
if (maxCacheCount != value)
|
|
{
|
|
maxCacheCount = value;
|
|
if (maxCacheCount > 0 && maxCacheCount < pool.Count)
|
|
{
|
|
int removeCount = pool.Count - maxCacheCount;
|
|
while (removeCount > 0)
|
|
{
|
|
T t = pool.Pop();
|
|
UnityEngine.Object.Destroy(t.gameObject);
|
|
removeCount--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 获取实例
|
|
/// </summary>
|
|
/// <returns>对象实例</returns>
|
|
public T Allocate()
|
|
{
|
|
//若对象池中有缓存则从对象池中获取
|
|
T retT = pool.Count > 0
|
|
? pool.Pop()
|
|
: (createMethod != null ? createMethod.Invoke() : new GameObject().AddComponent<T>());
|
|
retT.hideFlags = HideFlags.HideInHierarchy;
|
|
retT.IsRecycled = false;
|
|
return retT;
|
|
}
|
|
/// <summary>
|
|
/// 回收对象
|
|
/// </summary>
|
|
/// <param name="t">回收对象实例</param>
|
|
/// <returns>回收成功返回true 否则返回false</returns>
|
|
public bool Recycle(T t)
|
|
{
|
|
if (null == t || t.IsRecycled) return false;
|
|
t.IsRecycled = true;
|
|
t.OnRecycled();
|
|
//若未达到缓存数量上限 放入池中
|
|
if (pool.Count < maxCacheCount)
|
|
{
|
|
pool.Push(t);
|
|
}
|
|
else
|
|
{
|
|
UnityEngine.Object.Destroy(t.gameObject);
|
|
}
|
|
return true;
|
|
}
|
|
/// <summary>
|
|
/// 释放对象池
|
|
/// </summary>
|
|
public void Release()
|
|
{
|
|
foreach (var o in pool)
|
|
{
|
|
UnityEngine.Object.Destroy(o.gameObject);
|
|
}
|
|
pool.Clear();
|
|
instance = null;
|
|
}
|
|
/// <summary>
|
|
/// 设置创建方法
|
|
/// </summary>
|
|
/// <param name="createMethod">创建方法</param>
|
|
public void CreateBy(Func<T> createMethod)
|
|
{
|
|
this.createMethod = createMethod;
|
|
}
|
|
}
|
|
} |