using System;
using System.Collections.Generic;
using UnityEngine;
public class GameObjectPoolEntity
{
public Queue<GameObject> QueueList;
public string Name;
public GameObject Pool0bj;
}
public class QGGameObjectPool : IDisposable
{
private Dictionary<int, GameObjectPoolEntity> m_PoolDic;
private Dictionary<int, List<int>> m_InstanceIdDic;
public QGGameObjectPool()
{
m_PoolDic = new Dictionary<int, GameObjectPoolEntity>();
m_InstanceIdDic = new Dictionary<int, List<int>>();
}
//取池
public GameObject Spawn(GameObject prefabObj, Action<GameObject> onComplete = null)
{
lock (m_PoolDic)
{
int instanceId = prefabObj.GetInstanceID();
m_PoolDic.TryGetValue(instanceId, out var poolEntity);
if (poolEntity == null)
{
poolEntity = new()
{
Pool0bj = new GameObject(prefabObj.name + "Pool"),
Name = prefabObj.name,
QueueList = new Queue<GameObject>()
};
m_PoolDic[instanceId] = poolEntity;
}
else
{
if (poolEntity.QueueList.Count > 0)
{
GameObject obj = poolEntity.QueueList.Dequeue();
obj.SetActive(true);
onComplete?.Invoke(obj);
return obj;
}
}
GameObject newObj = GameObject.Instantiate(prefabObj);
newObj.transform.parent = poolEntity.Pool0bj.transform;
m_InstanceIdDic.TryGetValue(instanceId, out var lst);
lst??= new List<int>();
lst.Add(newObj.GetInstanceID());
m_InstanceIdDic[instanceId] = lst;
newObj.SetActive(true);
onComplete?.Invoke(newObj);
return newObj;
}
}
//回池
public void Despawn(GameObject gameObject)
{
lock (m_PoolDic)
{
int instanceId = GetInstanceId(gameObject.GetInstanceID());
m_PoolDic.TryGetValue(instanceId, out var poolEntity);
if (poolEntity != null)
{
gameObject.SetActive(false);
poolEntity.QueueList.Enqueue(gameObject);
}
}
}
private int GetInstanceId(int instanceID)
{
foreach (var item in m_InstanceIdDic)
{
foreach (var obj in item.Value)
{
if (obj == instanceID)
{
return item.Key;
}
}
}
return 0;
}
public void Dispose()
{
m_PoolDic.Clear();
m_InstanceIdDic.Clear();
}
}