BITKit/Src/Unity/Scripts/Utility/Pool.cs

106 lines
3.0 KiB
C#
Raw Normal View History

2023-06-05 19:57:17 +08:00
using System;
using System.Collections;
2023-08-11 23:57:37 +08:00
using System.Collections.Concurrent;
2023-06-05 19:57:17 +08:00
using System.Collections.Generic;
2023-08-11 23:57:37 +08:00
using System.Xml.Linq;
2023-06-05 19:57:17 +08:00
using UnityEngine;
using UnityEngine.Pool;
2023-08-11 23:57:37 +08:00
using Object = UnityEngine.Object;
2023-06-05 19:57:17 +08:00
namespace BITKit
{
[System.Serializable]
public class UnityPool<T> where T : Component
{
2023-11-06 01:17:23 +08:00
[Header(Constant.Header.Settings)]
[SerializeField] private int defaultCapacity = 16;
2023-06-05 19:57:17 +08:00
[Header(Constant.Header.Prefabs)]
2023-11-06 01:17:23 +08:00
[SerializeField] private T prefab;
2023-06-05 19:57:17 +08:00
[Header(Constant.Header.Gameobjects)]
2023-11-06 01:17:23 +08:00
[SerializeField] private Transform root;
2024-04-06 16:33:32 +08:00
public Action<T> OnGet { get; set; } = x=>x.gameObject.SetActive(true);
public Action<T> OnReturn { get; set; } = x=>x.gameObject.SetActive(false);
public Action<T> OnDestroy { get; set; } = x=>Object.Destroy(x.gameObject);
2024-05-31 01:23:15 +08:00
public Action<T> OnSpawn { get; set; }
2024-04-06 16:33:32 +08:00
private ObjectPool<T> pool=> _pool ??=
new ObjectPool<T>
(Spawn, OnGet, OnReturn, OnDestroy,defaultCapacity:DefaultCapacity, maxSize:DefaultCapacity);
private ObjectPool<T> _pool;
2023-11-06 01:17:23 +08:00
private readonly List<T> _list=new();
2024-04-06 16:33:32 +08:00
public T Prefab
{
get => prefab;
set => prefab = value;
}
public Transform Root
{
get => root;
set => root = value;
}
2023-11-15 23:55:06 +08:00
public int DefaultCapacity
{
get => defaultCapacity;
set => defaultCapacity = value;
}
2024-04-06 16:33:32 +08:00
public int InstanceCount => _list.Count;
2023-08-11 23:57:37 +08:00
public T Get(T element = null, Transform _root = null)
2023-06-05 19:57:17 +08:00
{
2023-11-06 01:17:23 +08:00
if (_list.Count == defaultCapacity)
{
var next = _list[0];
next.gameObject.SetActive(false);
_list.RemoveAt(0);
_list.Add(next);
next.gameObject.SetActive(true);
return next;
}
2023-06-05 19:57:17 +08:00
if (element is not null)
prefab = element;
2023-08-11 23:57:37 +08:00
if (_root is not null)
root = _root;
2023-11-06 01:17:23 +08:00
var instance = pool.Get();
_list.Add(instance);
return instance;
}
public void Return(T element)
{
2024-05-31 01:23:15 +08:00
try
{
pool.Release(element);
}
catch (InvalidOperationException){}
_list.TryRemove(element);
2023-06-05 19:57:17 +08:00
}
2024-05-31 01:23:15 +08:00
private T Spawn()
{
var newObject = Object.Instantiate(prefab, root);
OnSpawn?.Invoke(newObject);
return newObject;
}
2023-08-11 23:57:37 +08:00
#region
private readonly ConcurrentDictionary<string, T> _dictionary=new();
public T GetByKey(string key)
{
var instance = _dictionary.GetOrAdd(key, s => Get());
return instance;
}
public void RemoveByKey(string key)
{
_dictionary.TryRemove(key);
}
#endregion
2023-06-05 19:57:17 +08:00
}
}