UnityGame/Library/PackageCache/com.unity.ugui/Runtime/TMP/TMP_UpdateManager.cs

250 lines
8.5 KiB
C#
Raw Normal View History

2024-10-27 10:53:47 +03:00
using UnityEngine;
using Unity.Profiling;
using UnityEngine.UI;
using System.Collections.Generic;
namespace TMPro
{
public class TMP_UpdateManager
{
private static TMP_UpdateManager s_Instance;
private readonly HashSet<int> m_LayoutQueueLookup = new HashSet<int>();
private readonly List<TMP_Text> m_LayoutRebuildQueue = new List<TMP_Text>();
private readonly HashSet<int> m_GraphicQueueLookup = new HashSet<int>();
private readonly List<TMP_Text> m_GraphicRebuildQueue = new List<TMP_Text>();
private readonly HashSet<int> m_InternalUpdateLookup = new HashSet<int>();
private readonly List<TMP_Text> m_InternalUpdateQueue = new List<TMP_Text>();
private readonly HashSet<int> m_CullingUpdateLookup = new HashSet<int>();
private readonly List<TMP_Text> m_CullingUpdateQueue = new List<TMP_Text>();
// Profiler Marker declarations
private static ProfilerMarker k_RegisterTextObjectForUpdateMarker = new ProfilerMarker("TMP.RegisterTextObjectForUpdate");
private static ProfilerMarker k_RegisterTextElementForGraphicRebuildMarker = new ProfilerMarker("TMP.RegisterTextElementForGraphicRebuild");
private static ProfilerMarker k_RegisterTextElementForCullingUpdateMarker = new ProfilerMarker("TMP.RegisterTextElementForCullingUpdate");
private static ProfilerMarker k_UnregisterTextObjectForUpdateMarker = new ProfilerMarker("TMP.UnregisterTextObjectForUpdate");
private static ProfilerMarker k_UnregisterTextElementForGraphicRebuildMarker = new ProfilerMarker("TMP.UnregisterTextElementForGraphicRebuild");
/// <summary>
/// Get a singleton instance of the registry
/// </summary>
static TMP_UpdateManager instance
{
get
{
if (s_Instance == null)
s_Instance = new TMP_UpdateManager();
return s_Instance;
}
}
/// <summary>
/// Register to receive rendering callbacks.
/// </summary>
TMP_UpdateManager()
{
Canvas.willRenderCanvases += DoRebuilds;
}
/// <summary>
/// Function used as a replacement for LateUpdate() to handle SDF Scale updates and Legacy Animation updates.
/// </summary>
/// <param name="textObject"></param>
internal static void RegisterTextObjectForUpdate(TMP_Text textObject)
{
k_RegisterTextObjectForUpdateMarker.Begin();
instance.InternalRegisterTextObjectForUpdate(textObject);
k_RegisterTextObjectForUpdateMarker.End();
}
private void InternalRegisterTextObjectForUpdate(TMP_Text textObject)
{
int id = textObject.GetInstanceID();
if (m_InternalUpdateLookup.Contains(id))
return;
m_InternalUpdateLookup.Add(id);
m_InternalUpdateQueue.Add(textObject);
}
/// <summary>
/// Function to register elements which require a layout rebuild.
/// </summary>
/// <param name="element"></param>
public static void RegisterTextElementForLayoutRebuild(TMP_Text element)
{
instance.InternalRegisterTextElementForLayoutRebuild(element);
}
private void InternalRegisterTextElementForLayoutRebuild(TMP_Text element)
{
int id = element.GetInstanceID();
if (m_LayoutQueueLookup.Contains(id))
return;
m_LayoutQueueLookup.Add(id);
m_LayoutRebuildQueue.Add(element);
}
/// <summary>
/// Function to register elements which require a layout rebuild.
/// </summary>
/// <param name="element"></param>
public static void RegisterTextElementForGraphicRebuild(TMP_Text element)
{
k_RegisterTextElementForGraphicRebuildMarker.Begin();
instance.InternalRegisterTextElementForGraphicRebuild(element);
k_RegisterTextElementForGraphicRebuildMarker.End();
}
private void InternalRegisterTextElementForGraphicRebuild(TMP_Text element)
{
int id = element.GetInstanceID();
if (m_GraphicQueueLookup.Contains(id))
return;
m_GraphicQueueLookup.Add(id);
m_GraphicRebuildQueue.Add(element);
}
public static void RegisterTextElementForCullingUpdate(TMP_Text element)
{
k_RegisterTextElementForCullingUpdateMarker.Begin();
instance.InternalRegisterTextElementForCullingUpdate(element);
k_RegisterTextElementForCullingUpdateMarker.End();
}
private void InternalRegisterTextElementForCullingUpdate(TMP_Text element)
{
int id = element.GetInstanceID();
if (m_CullingUpdateLookup.Contains(id))
return;
m_CullingUpdateLookup.Add(id);
m_CullingUpdateQueue.Add(element);
}
/// <summary>
/// Callback which occurs just before the cam is rendered.
/// </summary>
void OnCameraPreCull()
{
DoRebuilds();
}
/// <summary>
/// Process the rebuild requests in the rebuild queues.
/// </summary>
void DoRebuilds()
{
// Handle text objects the require an update either as a result of scale changes or legacy animation.
for (int i = 0; i < m_InternalUpdateQueue.Count; i++)
{
m_InternalUpdateQueue[i].InternalUpdate();
}
// Handle Layout Rebuild Phase
for (int i = 0; i < m_LayoutRebuildQueue.Count; i++)
{
m_LayoutRebuildQueue[i].Rebuild(CanvasUpdate.Prelayout);
}
if (m_LayoutRebuildQueue.Count > 0)
{
m_LayoutRebuildQueue.Clear();
m_LayoutQueueLookup.Clear();
}
// Handle Graphic Rebuild Phase
for (int i = 0; i < m_GraphicRebuildQueue.Count; i++)
{
m_GraphicRebuildQueue[i].Rebuild(CanvasUpdate.PreRender);
}
// If there are no objects in the queue, we don't need to clear the lists again.
if (m_GraphicRebuildQueue.Count > 0)
{
m_GraphicRebuildQueue.Clear();
m_GraphicQueueLookup.Clear();
}
// Handle Culling Update
for (int i = 0; i < m_CullingUpdateQueue.Count; i++)
{
m_CullingUpdateQueue[i].UpdateCulling();
}
// If there are no objects in the queue, we don't need to clear the lists again.
if (m_CullingUpdateQueue.Count > 0)
{
m_CullingUpdateQueue.Clear();
m_CullingUpdateLookup.Clear();
}
}
internal static void UnRegisterTextObjectForUpdate(TMP_Text textObject)
{
k_UnregisterTextObjectForUpdateMarker.Begin();
instance.InternalUnRegisterTextObjectForUpdate(textObject);
k_UnregisterTextObjectForUpdateMarker.End();
}
/// <summary>
/// Function to unregister elements which no longer require a rebuild.
/// </summary>
/// <param name="element"></param>
public static void UnRegisterTextElementForRebuild(TMP_Text element)
{
instance.InternalUnRegisterTextElementForGraphicRebuild(element);
instance.InternalUnRegisterTextElementForLayoutRebuild(element);
instance.InternalUnRegisterTextObjectForUpdate(element);
}
private void InternalUnRegisterTextElementForGraphicRebuild(TMP_Text element)
{
k_UnregisterTextElementForGraphicRebuildMarker.Begin();
int id = element.GetInstanceID();
m_GraphicRebuildQueue.Remove(element);
m_GraphicQueueLookup.Remove(id);
k_UnregisterTextElementForGraphicRebuildMarker.End();
}
private void InternalUnRegisterTextElementForLayoutRebuild(TMP_Text element)
{
int id = element.GetInstanceID();
m_LayoutRebuildQueue.Remove(element);
m_LayoutQueueLookup.Remove(id);
}
private void InternalUnRegisterTextObjectForUpdate(TMP_Text textObject)
{
int id = textObject.GetInstanceID();
m_InternalUpdateQueue.Remove(textObject);
m_InternalUpdateLookup.Remove(id);
}
}
}