You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
6.4 KiB

  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using System.Collections.Generic;
  4. #if UNITY_2018_1_OR_NEWER
  5. using UnityEngine.Experimental.Rendering;
  6. #endif
  7. namespace TMPro
  8. {
  9. public class TMP_UpdateManager
  10. {
  11. private static TMP_UpdateManager s_Instance;
  12. private readonly List<TMP_Text> m_LayoutRebuildQueue = new List<TMP_Text>();
  13. private Dictionary<int, int> m_LayoutQueueLookup = new Dictionary<int, int>();
  14. private readonly List<TMP_Text> m_GraphicRebuildQueue = new List<TMP_Text>();
  15. private Dictionary<int, int> m_GraphicQueueLookup = new Dictionary<int, int>();
  16. //private bool m_PerformingGraphicRebuild;
  17. //private bool m_PerformingLayoutRebuild;
  18. /// <summary>
  19. /// Get a singleton instance of the registry
  20. /// </summary>
  21. public static TMP_UpdateManager instance
  22. {
  23. get
  24. {
  25. if (TMP_UpdateManager.s_Instance == null)
  26. TMP_UpdateManager.s_Instance = new TMP_UpdateManager();
  27. return TMP_UpdateManager.s_Instance;
  28. }
  29. }
  30. /// <summary>
  31. /// Register to receive rendering callbacks.
  32. /// </summary>
  33. protected TMP_UpdateManager()
  34. {
  35. Camera.onPreCull += OnCameraPreCull;
  36. #if UNITY_2018_1_OR_NEWER
  37. RenderPipeline.beginFrameRendering += OnBeginFrameRendering;
  38. #endif
  39. }
  40. /// <summary>
  41. /// Function to register elements which require a layout rebuild.
  42. /// </summary>
  43. /// <param name="element"></param>
  44. public static void RegisterTextElementForLayoutRebuild(TMP_Text element)
  45. {
  46. TMP_UpdateManager.instance.InternalRegisterTextElementForLayoutRebuild(element);
  47. }
  48. private bool InternalRegisterTextElementForLayoutRebuild(TMP_Text element)
  49. {
  50. int id = element.GetInstanceID();
  51. if (this.m_LayoutQueueLookup.ContainsKey(id))
  52. return false;
  53. m_LayoutQueueLookup[id] = id;
  54. this.m_LayoutRebuildQueue.Add(element);
  55. return true;
  56. }
  57. /// <summary>
  58. /// Function to register elements which require a layout rebuild.
  59. /// </summary>
  60. /// <param name="element"></param>
  61. public static void RegisterTextElementForGraphicRebuild(TMP_Text element)
  62. {
  63. TMP_UpdateManager.instance.InternalRegisterTextElementForGraphicRebuild(element);
  64. }
  65. private bool InternalRegisterTextElementForGraphicRebuild(TMP_Text element)
  66. {
  67. int id = element.GetInstanceID();
  68. if (this.m_GraphicQueueLookup.ContainsKey(id))
  69. return false;
  70. m_GraphicQueueLookup[id] = id;
  71. this.m_GraphicRebuildQueue.Add(element);
  72. return true;
  73. }
  74. /// <summary>
  75. /// Callback which occurs just before the Scriptable Render Pipeline (SRP) begins rendering.
  76. /// </summary>
  77. /// <param name="cameras"></param>
  78. void OnBeginFrameRendering(Camera[] cameras)
  79. {
  80. // Exclude the PreRenderCamera
  81. #if UNITY_EDITOR
  82. if (cameras.Length == 1 && cameras[0].cameraType == CameraType.Preview)
  83. return;
  84. #endif
  85. DoRebuilds();
  86. }
  87. /// <summary>
  88. /// Callback which occurs just before the cam is rendered.
  89. /// </summary>
  90. /// <param name="cam"></param>
  91. void OnCameraPreCull(Camera cam)
  92. {
  93. // Exclude the PreRenderCamera
  94. #if UNITY_EDITOR
  95. if (cam.cameraType == CameraType.Preview)
  96. return;
  97. #endif
  98. DoRebuilds();
  99. }
  100. /// <summary>
  101. /// Process the rebuild requests in the rebuild queues.
  102. /// </summary>
  103. void DoRebuilds()
  104. {
  105. // Handle Layout Rebuild Phase
  106. for (int i = 0; i < m_LayoutRebuildQueue.Count; i++)
  107. {
  108. m_LayoutRebuildQueue[i].Rebuild(CanvasUpdate.Prelayout);
  109. }
  110. if (m_LayoutRebuildQueue.Count > 0)
  111. {
  112. m_LayoutRebuildQueue.Clear();
  113. m_LayoutQueueLookup.Clear();
  114. }
  115. // Handle Graphic Rebuild Phase
  116. for (int i = 0; i < m_GraphicRebuildQueue.Count; i++)
  117. {
  118. m_GraphicRebuildQueue[i].Rebuild(CanvasUpdate.PreRender);
  119. }
  120. // If there are no objects in the queue, we don't need to clear the lists again.
  121. if (m_GraphicRebuildQueue.Count > 0)
  122. {
  123. m_GraphicRebuildQueue.Clear();
  124. m_GraphicQueueLookup.Clear();
  125. }
  126. }
  127. /// <summary>
  128. /// Function to unregister elements which no longer require a rebuild.
  129. /// </summary>
  130. /// <param name="element"></param>
  131. public static void UnRegisterTextElementForRebuild(TMP_Text element)
  132. {
  133. TMP_UpdateManager.instance.InternalUnRegisterTextElementForGraphicRebuild(element);
  134. TMP_UpdateManager.instance.InternalUnRegisterTextElementForLayoutRebuild(element);
  135. }
  136. private void InternalUnRegisterTextElementForGraphicRebuild(TMP_Text element)
  137. {
  138. //if (this.m_PerformingGraphicRebuild)
  139. //{
  140. // Debug.LogError((object)string.Format("Trying to remove {0} from rebuild list while we are already inside a rebuild loop. This is not supported.", (object)element));
  141. //}
  142. //else
  143. //{
  144. int id = element.GetInstanceID();
  145. //element.LayoutComplete();
  146. TMP_UpdateManager.instance.m_GraphicRebuildQueue.Remove(element);
  147. m_GraphicQueueLookup.Remove(id);
  148. //}
  149. }
  150. private void InternalUnRegisterTextElementForLayoutRebuild(TMP_Text element)
  151. {
  152. //if (this.m_PerformingLayoutRebuild)
  153. //{
  154. // Debug.LogError((object)string.Format("Trying to remove {0} from rebuild list while we are already inside a rebuild loop. This is not supported.", (object)element));
  155. //}
  156. //else
  157. //{
  158. int id = element.GetInstanceID();
  159. //element.LayoutComplete();
  160. TMP_UpdateManager.instance.m_LayoutRebuildQueue.Remove(element);
  161. m_LayoutQueueLookup.Remove(id);
  162. //}
  163. }
  164. }
  165. }