GraphicRegistry.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using System.Collections.Generic;
  2. using UnityEngine.UI.Collections;
  3. namespace UnityEngine.UI
  4. {
  5. /// <summary>
  6. /// Registry which maps a Graphic to the canvas it belongs to.
  7. /// </summary>
  8. public class GraphicRegistry
  9. {
  10. private static GraphicRegistry s_Instance;
  11. private readonly Dictionary<Canvas, IndexedSet<Graphic>> m_Graphics = new Dictionary<Canvas, IndexedSet<Graphic>>();
  12. private readonly Dictionary<Canvas, IndexedSet<Graphic>> m_RaycastableGraphics = new Dictionary<Canvas, IndexedSet<Graphic>>();
  13. protected GraphicRegistry()
  14. {
  15. // Avoid runtime generation of these types. Some platforms are AOT only and do not support
  16. // JIT. What's more we actually create a instance of the required types instead of
  17. // just declaring an unused variable which may be optimized away by some compilers (Mono vs MS).
  18. // See: 877060
  19. System.GC.KeepAlive(new Dictionary<Graphic, int>());
  20. System.GC.KeepAlive(new Dictionary<ICanvasElement, int>());
  21. System.GC.KeepAlive(new Dictionary<IClipper, int>());
  22. }
  23. /// <summary>
  24. /// The singleton instance of the GraphicRegistry. Creates a new instance if it does not exist.
  25. /// </summary>
  26. public static GraphicRegistry instance
  27. {
  28. get
  29. {
  30. if (s_Instance == null)
  31. s_Instance = new GraphicRegistry();
  32. return s_Instance;
  33. }
  34. }
  35. /// <summary>
  36. /// Associates a Graphic with a Canvas and stores this association in the registry.
  37. /// </summary>
  38. /// <param name="c">The canvas being associated with the Graphic.</param>
  39. /// <param name="graphic">The Graphic being associated with the Canvas.</param>
  40. public static void RegisterGraphicForCanvas(Canvas c, Graphic graphic)
  41. {
  42. if (c == null || graphic == null)
  43. return;
  44. IndexedSet<Graphic> graphics;
  45. instance.m_Graphics.TryGetValue(c, out graphics);
  46. if (graphics != null)
  47. {
  48. graphics.AddUnique(graphic);
  49. RegisterRaycastGraphicForCanvas(c, graphic);
  50. return;
  51. }
  52. // Dont need to AddUnique as we know its the only item in the list
  53. graphics = new IndexedSet<Graphic>();
  54. graphics.Add(graphic);
  55. instance.m_Graphics.Add(c, graphics);
  56. RegisterRaycastGraphicForCanvas(c, graphic);
  57. }
  58. /// <summary>
  59. /// Associates a raycastable Graphic with a Canvas and stores this association in the registry.
  60. /// </summary>
  61. /// <param name="c">The canvas being associated with the Graphic.</param>
  62. /// <param name="graphic">The Graphic being associated with the Canvas.</param>
  63. public static void RegisterRaycastGraphicForCanvas(Canvas c, Graphic graphic)
  64. {
  65. if (c == null || graphic == null || !graphic.raycastTarget)
  66. return;
  67. IndexedSet<Graphic> graphics;
  68. instance.m_RaycastableGraphics.TryGetValue(c, out graphics);
  69. if (graphics != null)
  70. {
  71. graphics.AddUnique(graphic);
  72. return;
  73. }
  74. // Dont need to AddUnique as we know its the only item in the list
  75. graphics = new IndexedSet<Graphic>();
  76. graphics.Add(graphic);
  77. instance.m_RaycastableGraphics.Add(c, graphics);
  78. }
  79. /// <summary>
  80. /// Dissociates a Graphic from a Canvas, removing this association from the registry.
  81. /// </summary>
  82. /// <param name="c">The Canvas to dissociate from the Graphic.</param>
  83. /// <param name="graphic">The Graphic to dissociate from the Canvas.</param>
  84. public static void UnregisterGraphicForCanvas(Canvas c, Graphic graphic)
  85. {
  86. if (c == null)
  87. return;
  88. IndexedSet<Graphic> graphics;
  89. if (instance.m_Graphics.TryGetValue(c, out graphics))
  90. {
  91. graphics.Remove(graphic);
  92. if (graphics.Count == 0)
  93. instance.m_Graphics.Remove(c);
  94. UnregisterRaycastGraphicForCanvas(c, graphic);
  95. }
  96. }
  97. /// <summary>
  98. /// Dissociates a Graphic from a Canvas, removing this association from the registry.
  99. /// </summary>
  100. /// <param name="c">The Canvas to dissociate from the Graphic.</param>
  101. /// <param name="graphic">The Graphic to dissociate from the Canvas.</param>
  102. public static void UnregisterRaycastGraphicForCanvas(Canvas c, Graphic graphic)
  103. {
  104. if (c == null || !graphic.raycastTarget)
  105. return;
  106. IndexedSet<Graphic> graphics;
  107. if (instance.m_RaycastableGraphics.TryGetValue(c, out graphics))
  108. {
  109. graphics.Remove(graphic);
  110. if (graphics.Count == 0)
  111. instance.m_RaycastableGraphics.Remove(c);
  112. }
  113. }
  114. private static readonly List<Graphic> s_EmptyList = new List<Graphic>();
  115. /// <summary>
  116. /// Retrieves the list of Graphics associated with a Canvas.
  117. /// </summary>
  118. /// <param name="canvas">The Canvas to search</param>
  119. /// <returns>Returns a list of Graphics. Returns an empty list if no Graphics are associated with the specified Canvas.</returns>
  120. public static IList<Graphic> GetGraphicsForCanvas(Canvas canvas)
  121. {
  122. IndexedSet<Graphic> graphics;
  123. if (instance.m_Graphics.TryGetValue(canvas, out graphics))
  124. return graphics;
  125. return s_EmptyList;
  126. }
  127. /// <summary>
  128. /// Retrieves the list of Graphics that are raycastable and associated with a Canvas.
  129. /// </summary>
  130. /// <param name="canvas">The Canvas to search</param>
  131. /// <returns>Returns a list of Graphics. Returns an empty list if no Graphics are associated with the specified Canvas.</returns>
  132. public static IList<Graphic> GetRaycastableGraphicsForCanvas(Canvas canvas)
  133. {
  134. IndexedSet<Graphic> graphics;
  135. if (instance.m_RaycastableGraphics.TryGetValue(canvas, out graphics))
  136. return graphics;
  137. return s_EmptyList;
  138. }
  139. }
  140. }