SamsonGame/Assets/Scripts/Core/ObjectPool/ObjectPoolManager.cs

95 lines
2.7 KiB
C#

using System;
using System.Collections.Generic;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
namespace RND
{
public class ObjectPoolManager : LazySingleton<ObjectPoolManager>
{
private readonly Dictionary<GameObject, ObjectPool> _poolsDict = new Dictionary<GameObject, ObjectPool>();
private readonly List<ObjectPool> _poolsList = new List<ObjectPool>();
private readonly CompositeDisposable _poolsDestroySubs = new CompositeDisposable();
public ObjectPool CreatePool(GameObject template)
{
ObjectPool pool = CreateLocalPool(template);
pool.gameObject.OnDestroyAsObservable().Subscribe(x =>
{
UnregisterPool(pool);
}).AddTo(_poolsDestroySubs);
RegisterPool(pool);
return pool;
}
public ObjectPool CreateLocalPool(GameObject template)
{
var pool = new GameObject($"{template.name} Pool");
return pool.AddComponent<ObjectPool>().Init(template);
}
public ObjectPool EnsurePoolByTemplate(GameObject template)
{
return _poolsDict.ContainsKey(template) ? _poolsDict[template] : CreatePool(template);
}
public ObjectPool EnsurePoolByInstance(GameObject instance)
{
return EnsurePoolByTemplate(ExtractTemplate(instance));
}
private GameObject ExtractTemplate(GameObject instance)
{
if (instance.TryGetComponent(out TemplateReference reference) && reference.Template != null)
{
return reference.Template;
}
else
{
throw new Exception($"{instance.name} doesn't belong to any pool");
}
}
private void OnDestroy()
{
DestroyAllPools();
}
public void DestroyAllPools()
{
_poolsDestroySubs.Clear();
_poolsList.ForEach(x => x.Destroy());
_poolsDict.Clear();
_poolsList.Clear();
}
public void DestroyPoolByInstance(GameObject instance)
{
DestroyPoolByTemplate(ExtractTemplate(instance));
}
private void DestroyPoolByTemplate(GameObject template)
{
if (_poolsDict.TryGetValue(template, out ObjectPool pool))
{
pool.Destroy();
UnregisterPool(pool);
}
}
public void RegisterPool(ObjectPool pool)
{
_poolsDict.Add(pool.Template, pool);
_poolsList.Add(pool);
}
public void UnregisterPool(ObjectPool pool)
{
_poolsList.Remove(pool);
_poolsDict.Remove(pool.Template);
}
}
}