暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

TMP_UpdateManager.cs 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using UnityEngine;
  2. using Unity.Profiling;
  3. using UnityEngine.UI;
  4. using System.Collections.Generic;
  5. namespace TMPro
  6. {
  7. public class TMP_UpdateManager
  8. {
  9. private static TMP_UpdateManager s_Instance;
  10. private readonly HashSet<int> m_LayoutQueueLookup = new HashSet<int>();
  11. private readonly List<TMP_Text> m_LayoutRebuildQueue = new List<TMP_Text>();
  12. private readonly HashSet<int> m_GraphicQueueLookup = new HashSet<int>();
  13. private readonly List<TMP_Text> m_GraphicRebuildQueue = new List<TMP_Text>();
  14. private readonly HashSet<int> m_InternalUpdateLookup = new HashSet<int>();
  15. private readonly List<TMP_Text> m_InternalUpdateQueue = new List<TMP_Text>();
  16. private readonly HashSet<int> m_CullingUpdateLookup = new HashSet<int>();
  17. private readonly List<TMP_Text> m_CullingUpdateQueue = new List<TMP_Text>();
  18. // Profiler Marker declarations
  19. private static ProfilerMarker k_RegisterTextObjectForUpdateMarker = new ProfilerMarker("TMP.RegisterTextObjectForUpdate");
  20. private static ProfilerMarker k_RegisterTextElementForGraphicRebuildMarker = new ProfilerMarker("TMP.RegisterTextElementForGraphicRebuild");
  21. private static ProfilerMarker k_RegisterTextElementForCullingUpdateMarker = new ProfilerMarker("TMP.RegisterTextElementForCullingUpdate");
  22. private static ProfilerMarker k_UnregisterTextObjectForUpdateMarker = new ProfilerMarker("TMP.UnregisterTextObjectForUpdate");
  23. private static ProfilerMarker k_UnregisterTextElementForGraphicRebuildMarker = new ProfilerMarker("TMP.UnregisterTextElementForGraphicRebuild");
  24. /// <summary>
  25. /// Get a singleton instance of the registry
  26. /// </summary>
  27. static TMP_UpdateManager instance
  28. {
  29. get
  30. {
  31. if (s_Instance == null)
  32. s_Instance = new TMP_UpdateManager();
  33. return s_Instance;
  34. }
  35. }
  36. /// <summary>
  37. /// Register to receive rendering callbacks.
  38. /// </summary>
  39. TMP_UpdateManager()
  40. {
  41. Canvas.willRenderCanvases += DoRebuilds;
  42. }
  43. /// <summary>
  44. /// Function used as a replacement for LateUpdate() to handle SDF Scale updates and Legacy Animation updates.
  45. /// </summary>
  46. /// <param name="textObject"></param>
  47. internal static void RegisterTextObjectForUpdate(TMP_Text textObject)
  48. {
  49. k_RegisterTextObjectForUpdateMarker.Begin();
  50. instance.InternalRegisterTextObjectForUpdate(textObject);
  51. k_RegisterTextObjectForUpdateMarker.End();
  52. }
  53. private void InternalRegisterTextObjectForUpdate(TMP_Text textObject)
  54. {
  55. int id = textObject.GetInstanceID();
  56. if (m_InternalUpdateLookup.Contains(id))
  57. return;
  58. m_InternalUpdateLookup.Add(id);
  59. m_InternalUpdateQueue.Add(textObject);
  60. }
  61. /// <summary>
  62. /// Function to register elements which require a layout rebuild.
  63. /// </summary>
  64. /// <param name="element"></param>
  65. public static void RegisterTextElementForLayoutRebuild(TMP_Text element)
  66. {
  67. instance.InternalRegisterTextElementForLayoutRebuild(element);
  68. }
  69. private void InternalRegisterTextElementForLayoutRebuild(TMP_Text element)
  70. {
  71. int id = element.GetInstanceID();
  72. if (m_LayoutQueueLookup.Contains(id))
  73. return;
  74. m_LayoutQueueLookup.Add(id);
  75. m_LayoutRebuildQueue.Add(element);
  76. }
  77. /// <summary>
  78. /// Function to register elements which require a layout rebuild.
  79. /// </summary>
  80. /// <param name="element"></param>
  81. public static void RegisterTextElementForGraphicRebuild(TMP_Text element)
  82. {
  83. k_RegisterTextElementForGraphicRebuildMarker.Begin();
  84. instance.InternalRegisterTextElementForGraphicRebuild(element);
  85. k_RegisterTextElementForGraphicRebuildMarker.End();
  86. }
  87. private void InternalRegisterTextElementForGraphicRebuild(TMP_Text element)
  88. {
  89. int id = element.GetInstanceID();
  90. if (m_GraphicQueueLookup.Contains(id))
  91. return;
  92. m_GraphicQueueLookup.Add(id);
  93. m_GraphicRebuildQueue.Add(element);
  94. }
  95. public static void RegisterTextElementForCullingUpdate(TMP_Text element)
  96. {
  97. k_RegisterTextElementForCullingUpdateMarker.Begin();
  98. instance.InternalRegisterTextElementForCullingUpdate(element);
  99. k_RegisterTextElementForCullingUpdateMarker.End();
  100. }
  101. private void InternalRegisterTextElementForCullingUpdate(TMP_Text element)
  102. {
  103. int id = element.GetInstanceID();
  104. if (m_CullingUpdateLookup.Contains(id))
  105. return;
  106. m_CullingUpdateLookup.Add(id);
  107. m_CullingUpdateQueue.Add(element);
  108. }
  109. /// <summary>
  110. /// Callback which occurs just before the cam is rendered.
  111. /// </summary>
  112. void OnCameraPreCull()
  113. {
  114. DoRebuilds();
  115. }
  116. /// <summary>
  117. /// Process the rebuild requests in the rebuild queues.
  118. /// </summary>
  119. void DoRebuilds()
  120. {
  121. // Handle text objects the require an update either as a result of scale changes or legacy animation.
  122. for (int i = 0; i < m_InternalUpdateQueue.Count; i++)
  123. {
  124. m_InternalUpdateQueue[i].InternalUpdate();
  125. }
  126. // Handle Layout Rebuild Phase
  127. for (int i = 0; i < m_LayoutRebuildQueue.Count; i++)
  128. {
  129. m_LayoutRebuildQueue[i].Rebuild(CanvasUpdate.Prelayout);
  130. }
  131. if (m_LayoutRebuildQueue.Count > 0)
  132. {
  133. m_LayoutRebuildQueue.Clear();
  134. m_LayoutQueueLookup.Clear();
  135. }
  136. // Handle Graphic Rebuild Phase
  137. for (int i = 0; i < m_GraphicRebuildQueue.Count; i++)
  138. {
  139. m_GraphicRebuildQueue[i].Rebuild(CanvasUpdate.PreRender);
  140. }
  141. // If there are no objects in the queue, we don't need to clear the lists again.
  142. if (m_GraphicRebuildQueue.Count > 0)
  143. {
  144. m_GraphicRebuildQueue.Clear();
  145. m_GraphicQueueLookup.Clear();
  146. }
  147. // Handle Culling Update
  148. for (int i = 0; i < m_CullingUpdateQueue.Count; i++)
  149. {
  150. m_CullingUpdateQueue[i].UpdateCulling();
  151. }
  152. // If there are no objects in the queue, we don't need to clear the lists again.
  153. if (m_CullingUpdateQueue.Count > 0)
  154. {
  155. m_CullingUpdateQueue.Clear();
  156. m_CullingUpdateLookup.Clear();
  157. }
  158. }
  159. internal static void UnRegisterTextObjectForUpdate(TMP_Text textObject)
  160. {
  161. k_UnregisterTextObjectForUpdateMarker.Begin();
  162. instance.InternalUnRegisterTextObjectForUpdate(textObject);
  163. k_UnregisterTextObjectForUpdateMarker.End();
  164. }
  165. /// <summary>
  166. /// Function to unregister elements which no longer require a rebuild.
  167. /// </summary>
  168. /// <param name="element"></param>
  169. public static void UnRegisterTextElementForRebuild(TMP_Text element)
  170. {
  171. instance.InternalUnRegisterTextElementForGraphicRebuild(element);
  172. instance.InternalUnRegisterTextElementForLayoutRebuild(element);
  173. instance.InternalUnRegisterTextObjectForUpdate(element);
  174. }
  175. private void InternalUnRegisterTextElementForGraphicRebuild(TMP_Text element)
  176. {
  177. k_UnregisterTextElementForGraphicRebuildMarker.Begin();
  178. int id = element.GetInstanceID();
  179. m_GraphicRebuildQueue.Remove(element);
  180. m_GraphicQueueLookup.Remove(id);
  181. k_UnregisterTextElementForGraphicRebuildMarker.End();
  182. }
  183. private void InternalUnRegisterTextElementForLayoutRebuild(TMP_Text element)
  184. {
  185. int id = element.GetInstanceID();
  186. m_LayoutRebuildQueue.Remove(element);
  187. m_LayoutQueueLookup.Remove(id);
  188. }
  189. private void InternalUnRegisterTextObjectForUpdate(TMP_Text textObject)
  190. {
  191. int id = textObject.GetInstanceID();
  192. m_InternalUpdateQueue.Remove(textObject);
  193. m_InternalUpdateLookup.Remove(id);
  194. }
  195. }
  196. }