Files
WhiteMan_Unity2D/Assets/HighlightPlus/Runtime/Scripts/HighlightLabelPoolManager.cs

136 lines
4.6 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace HighlightPlus {
[ExecuteAlways]
[DefaultExecutionOrder(-100)]
public class HighlightLabelPoolManager : MonoBehaviour {
private static HighlightLabelPoolManager instance;
private static readonly Dictionary<GameObject, Queue<HighlightLabel>> labelPools = new Dictionary<GameObject, Queue<HighlightLabel>>();
private static readonly HashSet<HighlightLabel> activeLabels = new HashSet<HighlightLabel>();
private static readonly int initialPoolSize = 5;
const string LABEL_INSTANCE_NAME = "Highlight Plus Label";
const string LABEL_POOL_NAME = "Highlight Plus Label Pool Manager";
[RuntimeInitializeOnLoadMethod]
static void DomainReloadDisabledSupport () {
DestroySceneLabels();
}
void OnEnable () {
if (instance == null) {
instance = this;
} else if (instance != this) {
DestroyImmediate(gameObject);
}
ClearPools();
}
void OnDestroy () {
if (instance == this) {
instance = null;
}
labelPools.Clear();
activeLabels.Clear();
}
public static void DestroySceneLabels () {
if (instance != null) {
DestroyImmediate(instance.gameObject);
instance = null;
}
ClearPools();
}
static void ClearPools () {
if (instance != null) {
for (int i = instance.transform.childCount - 1; i >= 0; i--) {
Transform child = instance.transform.GetChild(i);
if (child != null) {
DestroyImmediate(child.gameObject);
}
}
}
labelPools.Clear();
activeLabels.Clear();
}
private static void InitializePool (GameObject prefab) {
if (!labelPools.ContainsKey(prefab)) {
labelPools[prefab] = new Queue<HighlightLabel>();
for (int i = 0; i < initialPoolSize; i++) {
CreatePooledLabel(prefab);
}
}
}
private static HighlightLabel CreatePooledLabel (GameObject prefab) {
GameObject labelInstanceGO = Instantiate(prefab);
labelInstanceGO.name = LABEL_INSTANCE_NAME;
labelInstanceGO.hideFlags = HideFlags.DontSave;
labelInstanceGO.transform.SetParent(instance.transform, false);
HighlightLabel labelInstance = labelInstanceGO.GetComponentInChildren<HighlightLabel>();
labelInstance.labelPrefab = prefab;
labelInstance.isPooled = true;
labelInstanceGO.SetActive(false);
labelPools[prefab].Enqueue(labelInstance);
return labelInstance;
}
public static HighlightLabel GetLabelInstance (GameObject prefab) {
if (instance == null) {
GameObject go = new GameObject(LABEL_POOL_NAME);
go.hideFlags = HideFlags.DontSave;
instance = go.AddComponent<HighlightLabelPoolManager>();
}
// Initialize pool if needed
InitializePool(prefab);
// Try to get from pool
HighlightLabel labelInstance = null;
while (labelInstance == null && labelPools[prefab].Count > 0) {
labelInstance = labelPools[prefab].Dequeue();
}
if (labelInstance != null) {
activeLabels.Add(labelInstance);
return labelInstance;
}
// Create new instance if pool is empty
HighlightLabel newLabel = CreatePooledLabel(prefab);
activeLabels.Add(newLabel);
return newLabel;
}
public static void ReturnToPool (HighlightLabel label) {
if (label.labelPrefab != null && labelPools.ContainsKey(label.labelPrefab)) {
labelPools[label.labelPrefab].Enqueue(label);
activeLabels.Remove(label);
}
}
public static void Refresh () {
if (instance == null) return;
instance.LateUpdate();
}
void LateUpdate () {
foreach (var label in activeLabels) {
if (label == null) continue;
if (label.isVisible) {
label.UpdatePosition();
if (!label.gameObject.activeSelf) {
label.gameObject.SetActive(true);
}
}
}
}
}
}