using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using AYellowpaper.SerializedCollections; using UnityEngine; namespace BITKit { public class PoolService : MonoBehaviour { private static readonly ConcurrentDictionary _Prefabs = new(); private static readonly ConcurrentDictionary> _Pools = new(); public static Transform Get(Transform prefab) { _Prefabs.TryAdd(prefab.name, prefab); var pool = _Pools.GetOrAdd(prefab.name, CreatePool); return pool.Get(); } public static bool TryGet(Transform prefab, out Transform instance) { _Prefabs.TryAdd(prefab.name, prefab); var pool = _Pools.GetOrAdd(prefab.name, CreatePool); instance = null; if (pool.InstanceCount>=pool.DefaultCapacity) return false; instance = pool.Get(); return true; } public static void Release(string name,Transform instance) { var pool = _Pools.GetOrAdd(name, CreatePool); pool.Return(instance); } private static UnityPool CreatePool(string name) { var pool = new UnityPool { Prefab = _Prefabs[name], OnReturn = null, }; return pool; } [SerializeField] private SerializedDictionary initialCapacity; private void Start() { foreach (var (key, value) in initialCapacity) { var pool = new UnityPool { Prefab = key, DefaultCapacity = value, Root = transform, OnReturn = null, }; _Prefabs.TryAdd(key.name, key); _Pools.TryAdd(key.name, pool); var list = new List(); for (var i = 0; i < pool.DefaultCapacity; i++) { list.Add(pool.Get()); } foreach (var x in list) { x.gameObject.SetActive(false); pool.Return(x); } } } private void OnDestroy() { _Prefabs.Clear(); _Pools.Clear(); } } }