CanvasUpdate
枚举类:CanvasUpdate,用于表示当前的布局阶段
public enum CanvasUpdate
{
/// <summary>
/// Called before layout.
/// </summary>
Prelayout= 0,
/// <summary>
/// Called for layout.
/// </summary>
Layout= 1,
/// <summary>
/// Called after layout.
/// </summary>
PostLayout= 2,
/// <summary>
/// Called before rendering.
/// </summary>
PreRender= 3,
/// <summary>
/// Called late, before render.
/// </summary>
LatePreRender= 4,
/// <summary>
/// Max enum value. Always last.
/// </summary>
MaxUpdateValue= 5
}
ICanvasElement
- 重建方法: void Rebuild(CanvasUpdate executing);
- 布局重建完成: void LayoutComplete();
- 图像重建完成: void GraphicUpdateComplete();
- 检查Element是否无效:bool IsDestroyed();
CanvasUpdateRegistry
内部管理了两个队列m_LayoutRebuildQueue和m_GraphicRebuildQueue。
private readonly IndexedSet<ICanvasElement> m_LayoutRebuildQueue = new IndexedSet<ICanvasElement>();
private readonly IndexedSet<ICanvasElement> m_GraphicRebuildQueue = new IndexedSet<ICanvasElement>();
构造函数中注册了画布渲染监听
Canvas.willRenderCanvases += PerformUpdate;
PerformUpdate简化后的逻辑如下,依次处理了m_LayoutRebuildQueue和m_GraphicRebuildQueue两个队列。
private void PerformUpdate()
{
//处理m_LayoutRebuildQueue队列
m_PerformingLayoutUpdate = true;
var layoutRebuildQueueCount = m_LayoutRebuildQueue.Count;
for (int i = 0; i <= (int)CanvasUpdate.PostLayout; i++)
{
for (int j = 0; j < layoutRebuildQueueCount; j++)
{
var rebuild = m_LayoutRebuildQueue[j];
rebuild.Rebuild((CanvasUpdate)i);
}
}
for (int i = 0; i < layoutRebuildQueueCount; ++i)
m_LayoutRebuildQueue[i].LayoutComplete();
m_LayoutRebuildQueue.Clear();
m_PerformingLayoutUpdate = false;
//处理裁切相关
ClipperRegistry.instance.Cull();
//处理m_GraphicRebuildQueue队列
m_PerformingGraphicUpdate = true;
var graphicRebuildQueueCount = m_GraphicRebuildQueue.Count;
for (var i = (int)CanvasUpdate.PreRender; i < (int)CanvasUpdate.MaxUpdateValue; i++)
{
for (var k = 0; k < graphicRebuildQueueCount; k++)
{
var element = m_GraphicRebuildQueue[k];
element.Rebuild((CanvasUpdate)i);
}