CanvasUpdateRegistry(画布更新注册处)是一个单例,它是UGUI与Canvas之间的中介,继承了ICanvasElement接口的组件都可以注册到它,它监听了Canvas即将渲染的事件,并调用已注册组件的Rebuild等方法。
CanvasUpdateRegistry维护了两个索引集(不会存放相同的元素):
//布局重建序列索引集
private readonly IndexedSet<ICanvasElement> m_LayoutRebuildQueue = new IndexedSet<ICanvasElement>();
//图形重建序列索引集
private readonly IndexedSet<ICanvasElement> m_GraphicRebuildQueue = new IndexedSet<ICanvasElement>();
m_LayoutRebuildQueue是通过RegisterCanvasElementForLayoutRebuild
和TryRegisterCanvasElementForLayoutRebuild方法添加元素。
m_GraphicRebuildQueue是通过RegisterCanvasElementForGraphicRebuild
和TryRegisterCanvasElementForGraphicRebuild方法添加元素。
二者通过UnRegisterCanvasElementForRebuild移除注册元素。
CanvasUpdateRegistry的构造函数:
protected CanvasUpdateRegistry()
{
Canvas.willRenderCanvases += PerformUpdate;
}
willRenderCanvases是Canvas的静态事件,事件是一种特殊的委托,在渲染所有的Canvas之前,抛出willRenderCanvases事件,继而调用CanvasUpdateRegistry的PerformUpdate方法。
public enum CanvasUpdate
{
Prelayout = 0,
Layout = 1,
PostLayout = 2,
PreRender = 3,
LatePreRender = 4,
MaxUpdateValue = 5
}
除了最后一个枚举项,其他五个项分别代表了布局的三个阶段和渲染的两个阶段。
在PerformUpdate方法中
- 从两个序列中删除不可用的元素 CleanInvalidItems();
- 布局更新开始
- 对m_LayoutRebuildQueue依据父对象的数量进行排序
- 分别以PreLayout,Layout,PostLayout的参数顺序调用每一个元素的Rebuild方法
- 调用所有元素的LayoutComplete方法
- 清除布局重建序列中的所有元素
- 布局更新结束
- 完成布局后,调用组件的修剪方法
- 图形更新开始
- 以PreRender,LatePreRender的参数顺序调用每一个元素的Rebulid方法
- 调用所有元素的GraphicUpdateComplete方法
- 清除图形重建序列中的所有元素
- 图形更新结束
至此,一个完整的更新流程就完成了。