using Convention.Experimental.PublicType;
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
namespace Convention.Experimental.Modules
{
public class GameObjectPoolManager : GameModule
{
///
/// 继承该接口的Component将在回收到对象池时调用
/// 中禁止调用
///
public interface IPoolPawn
{
void Release();
}
private readonly Dictionary> GameObjectPools = new();
private readonly Dictionary LeaveGameObjectPoolObjects = new();
private bool GameObjectPoolStatus = true;
///
/// 检查是否存在指定的游戏对象池
///
/// 用做键的预制体
///
public bool Contains(GameObject prefab)
{
return GameObjectPools.ContainsKey(prefab);
}
///
/// 确保不会嵌套调用
///
///
private void EnsureSafeStatus()
{
if (GameObjectPoolStatus == false)
{
throw new GameException("GameObjectPool is busy now.");
}
}
///
/// 生成游戏对象
///
///
///
public GameObject Spawn(GameObject prefab)
{
EnsureSafeStatus();
lock (GameObjectPools)
{
if (!GameObjectPools.ContainsKey(prefab))
{
GameObjectPools[prefab] = new();
}
var pool = GameObjectPools[prefab];
GameObject instance;
if (pool.Count > 0)
{
instance = pool.Pop();
instance.SetActive(true);
instance.transform.SetParent(null);
}
else
{
instance = GameObject.Instantiate(prefab);
}
lock (LeaveGameObjectPoolObjects)
{
LeaveGameObjectPoolObjects[instance] = prefab;
}
return instance;
}
}
///
/// 回收游戏对象
///
///
///
public void Unspawn(GameObject instance)
{
EnsureSafeStatus();
lock (LeaveGameObjectPoolObjects)
{
if (LeaveGameObjectPoolObjects.TryGetValue(instance, out var prefab))
{
var releaser = instance.GetComponents();
GameObjectPoolStatus = false;
foreach (var r in releaser)
{
r.Release();
}
GameObjectPoolStatus = true;
instance.SetActive(false);
instance.transform.SetParent(ConventionUtility.Singleton.transform);
lock (GameObjectPools)
{
GameObjectPools[prefab].Push(instance);
LeaveGameObjectPoolObjects.Remove(instance);
}
}
else
{
throw new PublicType.GameException("This object does not belong to any pool.");
}
}
}
public void Clear(GameObject prefab)
{
EnsureSafeStatus();
lock (GameObjectPools)
{
lock (LeaveGameObjectPoolObjects)
{
// 销毁池中对象
if (GameObjectPools.TryGetValue(prefab, out var pool))
{
while (pool.Count > 0)
{
var instance = pool.Pop();
GameObject.Destroy(instance);
}
}
else
{
throw new PublicType.GameException("This pool does not exist.");
}
// 销毁未回收对象
var unbackInstances = from item in LeaveGameObjectPoolObjects
where item.Value == prefab
select item.Key;
foreach (var instance in unbackInstances)
{
LeaveGameObjectPoolObjects.Remove(instance);
}
foreach (var instance in unbackInstances)
{
GameObject.Destroy(instance);
}
}
}
}
}
public class ObjectPoolManager
{
///
/// 继承该接口的Component将在回收到对象池时调用
/// 中禁止调用
///
public interface IPoolPawn
{
void Release();
}
private readonly Dictionary ObjectPools = new();
private readonly Dictionary