Files
JJBB/Assets/Project/Script/GameLogic/GameManager/GameObjectPool.cs

264 lines
8.3 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
/********************************************************************************
* GameObjectPool.cs
* \Script\GameManager\GameObjectPool.cs
*
* 2014-04-15
*
*
*
*
* Create和Remove接口
* GC行为发生
* Destroyclass赋空的情况GC行为使
* list中的GameObject状态置true和falsePool
*
* LiJia 2014-09-17 POOL_MAX_CAPACITY定义的数量
*********************************************************************************/
using System.Collections.Generic;
using Games.GlobeDefine;
using UnityEngine;
using Module.Log;
public class GameObjectPool
{
public delegate void CreatePoolObjDelegate(GameObject newObj, object param1, object param2);
private class LoadBundleParam
{
public LoadBundleParam(CreatePoolObjDelegate delFun, object param1, object param2, UIPathData uiData, string objName)
{
m_delFun = delFun;
m_userParam1 = param1;
m_userParam2 = param2;
m_uiData = uiData;
m_objName = objName;
}
public CreatePoolObjDelegate m_delFun;
public object m_userParam1;
public object m_userParam2;
public UIPathData m_uiData;
public string m_objName;
}
private GameObjectPool()
{
}
public GameObjectPool(string szPoolName, int nMaxSize = GlobeVar.INVALID_ID)
{
m_szPoolName = szPoolName;
m_ActivePool = new Dictionary<string, List<GameObject>>();
m_InActivePool = new Dictionary<string, List<GameObject>>();
m_nMaxSize = nMaxSize;
}
private string m_szPoolName; //池子名称
public string PoolName
{
get { return m_szPoolName; }
}
private Dictionary<string, List<GameObject>> m_ActivePool; //活动对象队列
private Dictionary<string, List<GameObject>> m_InActivePool; //非活动对象队列
private int m_nMaxGameObjectType = 64; //池子中索引的数量
private int m_nMaxSize = 128; //池子中每种类型的GameObject可容纳的子队列大小
// 从Bundle加载一个可复用的ITEM
public void CreateUIFromBundle(UIPathData uiData, string objName, CreatePoolObjDelegate delFun, object param1, object param2)
{
GameObject obj = ReUseElement(objName);
if (null == obj)
{
if (m_nMaxGameObjectType > 0 && m_ActivePool.Count == m_nMaxGameObjectType)
{
if(null != delFun) delFun(null, param1, param2);
return;
}
}
else
{
if(null != delFun) delFun(obj, param1, param2);
}
}
private void OnLoadBundleItem(GameObject resObj, object param)
{
LoadBundleParam curParam = param as LoadBundleParam;
if (null == curParam)
return;
GameObject newElement = GameObject.Instantiate(resObj) as GameObject;
if (null != newElement)
{
newElement.name = curParam.m_objName;
if (false == InsertElement(m_ActivePool, newElement))
{
//这里必须将newElement强制释放雕否则会导致Pool管理失效newElement无限增加
//后面所有用到newElement的地方原理相同
GameObject.Destroy(newElement);
}
if (null != curParam.m_delFun)
curParam.m_delFun(newElement, curParam.m_userParam1, curParam.m_userParam2);
}
}
public void Remove(GameObject element)
{
if (null == element)
return;
if (RemoveElement(m_ActivePool, element))
{
//插入都未使用队列
if (InsertElement(m_InActivePool, element))
{
element.transform.position = GlobeVar.INFINITY_FAR;
}
else
{
//插入失败需要把element释放掉否则会变成不受管理的GameObject
GameObject.Destroy(element);
}
}
}
//复用一个已经无效的对象
private GameObject ReUseElement(string strGameObjectName)
{
GameObject reuseElem = null;
if (m_InActivePool.ContainsKey(strGameObjectName))
{
List<GameObject> list = m_InActivePool[strGameObjectName];
if (null == list || list.Count <= 0)
return null;
reuseElem = list[0];
if (reuseElem == null)
{
list.RemoveAt(0);
return null;
}
list.Remove(reuseElem);
if (InsertElement(m_ActivePool, reuseElem))
{
return reuseElem;
}
else
{
//插入失败,释放掉
GameObject.Destroy(reuseElem);
}
}
return null;
}
//内部接口
//向池子中插入一个新的GameObject
private bool InsertElement(Dictionary<string, List<GameObject>> pool, GameObject newElement)
{
if (null == newElement || null == pool)
{
return false;
}
//先判断池子中是否有这个Key,如果没有则先添加
List<GameObject> list = null;
if (false == pool.ContainsKey(newElement.name))
{
list = new List<GameObject>();
pool.Add(newElement.name, list);
}
else
{
list = pool[newElement.name];
}
if (null != list)
{
//池子已达到最大
if (m_nMaxSize > 0 && list.Count >= m_nMaxSize)
{
if (list.Count < GlobeVar.POOL_MAX_CAPACITY)
{
m_nMaxSize++;
}
else
{
LogModule.ErrorLog("Pool has reached capacity size, Element name:" + newElement.name);
return false;
}
}
list.Add(newElement);
return true;
}
return false;
}
//从池子中移除一个GameObject
private bool RemoveElement(Dictionary<string, List<GameObject>> pool, GameObject element)
{
if (null == element || null == pool)
{
return false;
}
if (pool.ContainsKey(element.name))
{
List<GameObject> list = pool[element.name];
if (null != list && list.Contains(element))
{
list.Remove(element);
return true;
}
}
return false;
}
//清理所有的GameObjectPool
public void ClearAllPool()
{
if (null != m_ActivePool)
{
foreach(KeyValuePair<string, List<GameObject>> activeList in m_ActivePool)
{
if (null != activeList.Value)
{
for(int i=0; i<activeList.Value.Count; ++i)
{
activeList.Value[i] = null;
}
activeList.Value.Clear();
}
}
m_ActivePool.Clear();
}
if (null != m_InActivePool)
{
foreach (KeyValuePair<string, List<GameObject>> inactiveList in m_InActivePool)
{
if (null != inactiveList.Value)
{
for (int i = 0; i < inactiveList.Value.Count; ++i)
{
inactiveList.Value[i] = null;
}
inactiveList.Value.Clear();
}
}
m_InActivePool.Clear();
}
}
}