summaryrefslogtreecommitdiff
path: root/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2020-10-08 09:50:33 +0800
committerchai <chaifix@163.com>2020-10-08 09:50:33 +0800
commit00dae1bd426d892dff73a50f1c505afd1ac00a90 (patch)
tree5d75f8495406f5b8dd01595e3dd9216887996a34 /Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs
+init
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs')
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs275
1 files changed, 275 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs
new file mode 100644
index 0000000..bc7263b
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs
@@ -0,0 +1,275 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.UI.Collections;
+
+namespace UnityEngine.UI
+{
+ public enum CanvasUpdate
+ {
+ Prelayout = 0,
+ Layout = 1,
+ PostLayout = 2,
+ PreRender = 3,
+ LatePreRender = 4,
+ MaxUpdateValue = 5
+ }
+
+ public interface ICanvasElement
+ {
+ void Rebuild(CanvasUpdate executing);
+ Transform transform { get; }
+ void LayoutComplete();
+ void GraphicUpdateComplete();
+ // due to unity overriding null check
+ // we need this as something may not be null
+ // but may be destroyed
+ bool IsDestroyed();
+ }
+
+ public class CanvasUpdateRegistry
+ {
+ private static CanvasUpdateRegistry s_Instance;
+
+ private bool m_PerformingLayoutUpdate;
+ private bool m_PerformingGraphicUpdate;
+
+ private readonly IndexedSet<ICanvasElement> m_LayoutRebuildQueue = new IndexedSet<ICanvasElement>();
+ private readonly IndexedSet<ICanvasElement> m_GraphicRebuildQueue = new IndexedSet<ICanvasElement>();
+
+ protected CanvasUpdateRegistry()
+ {
+ Canvas.willRenderCanvases += PerformUpdate;
+ }
+
+ public static CanvasUpdateRegistry instance
+ {
+ get
+ {
+ if (s_Instance == null)
+ s_Instance = new CanvasUpdateRegistry();
+ return s_Instance;
+ }
+ }
+
+ private bool ObjectValidForUpdate(ICanvasElement element)
+ {
+ var valid = element != null;
+
+ var isUnityObject = element is Object;
+ if (isUnityObject)
+ valid = (element as Object) != null; //Here we make use of the overloaded UnityEngine.Object == null, that checks if the native object is alive.
+
+ return valid;
+ }
+
+ private void CleanInvalidItems()
+ {
+ // So MB's override the == operator for null equality, which checks
+ // if they are destroyed. This is fine if you are looking at a concrete
+ // mb, but in this case we are looking at a list of ICanvasElement
+ // this won't forward the == operator to the MB, but just check if the
+ // interface is null. IsDestroyed will return if the backend is destroyed.
+
+ for (int i = m_LayoutRebuildQueue.Count - 1; i >= 0; --i)
+ {
+ var item = m_LayoutRebuildQueue[i];
+ if (item == null)
+ {
+ m_LayoutRebuildQueue.RemoveAt(i);
+ continue;
+ }
+
+ if (item.IsDestroyed())
+ {
+ m_LayoutRebuildQueue.RemoveAt(i);
+ item.LayoutComplete();
+ }
+ }
+
+ for (int i = m_GraphicRebuildQueue.Count - 1; i >= 0; --i)
+ {
+ var item = m_GraphicRebuildQueue[i];
+ if (item == null)
+ {
+ m_GraphicRebuildQueue.RemoveAt(i);
+ continue;
+ }
+
+ if (item.IsDestroyed())
+ {
+ m_GraphicRebuildQueue.RemoveAt(i);
+ item.GraphicUpdateComplete();
+ }
+ }
+ }
+
+ private static readonly Comparison<ICanvasElement> s_SortLayoutFunction = SortLayoutList;
+ private void PerformUpdate()
+ {
+ UISystemProfilerApi.BeginSample(UISystemProfilerApi.SampleType.Layout);
+ CleanInvalidItems();
+
+ m_PerformingLayoutUpdate = true;
+
+ m_LayoutRebuildQueue.Sort(s_SortLayoutFunction);
+ for (int i = 0; i <= (int)CanvasUpdate.PostLayout; i++)
+ {
+ for (int j = 0; j < m_LayoutRebuildQueue.Count; j++)
+ {
+ var rebuild = instance.m_LayoutRebuildQueue[j];
+ try
+ {
+ if (ObjectValidForUpdate(rebuild))
+ rebuild.Rebuild((CanvasUpdate)i);
+ }
+ catch (Exception e)
+ {
+ Debug.LogException(e, rebuild.transform);
+ }
+ }
+ }
+
+ for (int i = 0; i < m_LayoutRebuildQueue.Count; ++i)
+ m_LayoutRebuildQueue[i].LayoutComplete();
+
+ instance.m_LayoutRebuildQueue.Clear();
+ m_PerformingLayoutUpdate = false;
+
+ // now layout is complete do culling...
+ ClipperRegistry.instance.Cull();
+
+ m_PerformingGraphicUpdate = true;
+ for (var i = (int)CanvasUpdate.PreRender; i < (int)CanvasUpdate.MaxUpdateValue; i++)
+ {
+ for (var k = 0; k < instance.m_GraphicRebuildQueue.Count; k++)
+ {
+ try
+ {
+ var element = instance.m_GraphicRebuildQueue[k];
+ if (ObjectValidForUpdate(element))
+ element.Rebuild((CanvasUpdate)i);
+ }
+ catch (Exception e)
+ {
+ Debug.LogException(e, instance.m_GraphicRebuildQueue[k].transform);
+ }
+ }
+ }
+
+ for (int i = 0; i < m_GraphicRebuildQueue.Count; ++i)
+ m_GraphicRebuildQueue[i].GraphicUpdateComplete();
+
+ instance.m_GraphicRebuildQueue.Clear();
+ m_PerformingGraphicUpdate = false;
+ UISystemProfilerApi.EndSample(UISystemProfilerApi.SampleType.Layout);
+ }
+
+ private static int ParentCount(Transform child)
+ {
+ if (child == null)
+ return 0;
+
+ var parent = child.parent;
+ int count = 0;
+ while (parent != null)
+ {
+ count++;
+ parent = parent.parent;
+ }
+ return count;
+ }
+
+ private static int SortLayoutList(ICanvasElement x, ICanvasElement y)
+ {
+ Transform t1 = x.transform;
+ Transform t2 = y.transform;
+
+ return ParentCount(t1) - ParentCount(t2);
+ }
+
+ public static void RegisterCanvasElementForLayoutRebuild(ICanvasElement element)
+ {
+ instance.InternalRegisterCanvasElementForLayoutRebuild(element);
+ }
+
+ public static bool TryRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
+ {
+ return instance.InternalRegisterCanvasElementForLayoutRebuild(element);
+ }
+
+ private bool InternalRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
+ {
+ if (m_LayoutRebuildQueue.Contains(element))
+ return false;
+
+ /* TODO: this likely should be here but causes the error to show just resizing the game view (case 739376)
+ if (m_PerformingLayoutUpdate)
+ {
+ Debug.LogError(string.Format("Trying to add {0} for layout rebuild while we are already inside a layout rebuild loop. This is not supported.", element));
+ return false;
+ }*/
+
+ return m_LayoutRebuildQueue.AddUnique(element);
+ }
+
+ public static void RegisterCanvasElementForGraphicRebuild(ICanvasElement element)
+ {
+ instance.InternalRegisterCanvasElementForGraphicRebuild(element);
+ }
+
+ public static bool TryRegisterCanvasElementForGraphicRebuild(ICanvasElement element)
+ {
+ return instance.InternalRegisterCanvasElementForGraphicRebuild(element);
+ }
+
+ private bool InternalRegisterCanvasElementForGraphicRebuild(ICanvasElement element)
+ {
+ if (m_PerformingGraphicUpdate)
+ {
+ Debug.LogError(string.Format("Trying to add {0} for graphic rebuild while we are already inside a graphic rebuild loop. This is not supported.", element));
+ return false;
+ }
+
+ return m_GraphicRebuildQueue.AddUnique(element);
+ }
+
+ public static void UnRegisterCanvasElementForRebuild(ICanvasElement element)
+ {
+ instance.InternalUnRegisterCanvasElementForLayoutRebuild(element);
+ instance.InternalUnRegisterCanvasElementForGraphicRebuild(element);
+ }
+
+ private void InternalUnRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
+ {
+ if (m_PerformingLayoutUpdate)
+ {
+ Debug.LogError(string.Format("Trying to remove {0} from rebuild list while we are already inside a rebuild loop. This is not supported.", element));
+ return;
+ }
+
+ element.LayoutComplete();
+ instance.m_LayoutRebuildQueue.Remove(element);
+ }
+
+ private void InternalUnRegisterCanvasElementForGraphicRebuild(ICanvasElement element)
+ {
+ if (m_PerformingGraphicUpdate)
+ {
+ Debug.LogError(string.Format("Trying to remove {0} from rebuild list while we are already inside a rebuild loop. This is not supported.", element));
+ return;
+ }
+ element.GraphicUpdateComplete();
+ instance.m_GraphicRebuildQueue.Remove(element);
+ }
+
+ public static bool IsRebuildingLayout()
+ {
+ return instance.m_PerformingLayoutUpdate;
+ }
+
+ public static bool IsRebuildingGraphics()
+ {
+ return instance.m_PerformingGraphicUpdate;
+ }
+ }
+}