Files
endorphin-tessera-gui/examples/layout-cache.endor
T

63 lines
3.8 KiB
Plaintext

// 测量与绘制依赖分离:改颜色应复用尺寸缓存,改模型宽度才需要重新测量。
// ViewportBand 还显式读取实际页面视口,使原生 resize 可通过依赖触发重测。
// 只负责测量需要的宽度,和绘制颜色分成两个业务对象以便观察独立失效。
class WidthModel {
width: Number
// 点击把模型宽度置为 260;源 measure 读取过该字段,缓存因此失效。
// 按钮 click 的 Event 回调,只写 WidthModel.width;后续是否重测由已记录的真实读取失效决定。
function expand(self: WidthModel, event: Event): Unit {
self.width = 260
}
}
// 保存 paint 使用的颜色,不参与 CachedRect 的测量。
class Tint {
color: String
// 只改颜色;正常情况下需重绘而不重新执行无关源测量。
// 另一按钮的 Event 回调只写 Tint.color,不改 dimensions,避免用无关模型写入混淆测量依赖。
function blue(self: Tint, event: Event): Unit {
self.color = "#526AC7"
}
}
// 原生矩形的尺寸/颜色策略分别由源协议覆盖,业务模型通过字段持有。
class CachedRect: RectBlock {
// CachedRect 引用两个不同策略对象;measure 读尺寸对象,paint 读颜色对象,各阶段依赖分开记录。
dimensions: WidthModel
tint: Tint
// 读取 dimensions.width 返回固定高 60;实际读观察由运行时缓存记录,不手工声明依赖表。
// 只读测量由 source_layout 调用,self 是共享矩形,mount/constraints 是当前出现输入,不写 geometry。
function measure(self: CachedRect, mount: Mount, constraints: Constraints): MeasureResult {
return MeasureResult(self.dimensions.width, 60)
}
// 复用原生矩形命令,再改新命令的颜色;修改新结果被允许,但 paint 不能修改已有业务对象。
function paint(self: CachedRect, mount: Mount, geometry: Bounds): DisplayList {
// 源 paint 由 source_paint 调用,显式委托基类得到本轮新 DisplayList,不在这里发输入事件或改变 Page。
drawing = RectBlock.paint(self, mount, geometry)
// 修改的是新分配命令的颜色字段,再由宿主统一解码校验;self.tint 仍只读。
drawing.commands.at(0).color = self.tint.color
return drawing
}
}
// 宽度来自 ui.viewport 的当前逻辑页面区域,显示窗口变化也能成为测量依赖。
class ViewportBand: RectBlock {
// 返回可用视口宽度,最终仍服从父容器约束;外层 padding 会减少分配宽度。
// ui.viewport 取当前窗口逻辑页面范围,实际返回尺寸还会受父级更窄的 Constraints 约束。
function measure(self: ViewportBand, mount: Mount, constraints: Constraints): MeasureResult {
return MeasureResult(ui.viewport().width, 24)
}
}
// 创建相互独立的宽度/颜色模型并绑定两个按钮,用相同对象观察缓存与可见结果。
dimensions = WidthModel(200)
tint = Tint("#ED6A5A")
// 源字段 dimensions/tint 放在原生构造参数后,RectBlock 的默认尺寸不是这个覆盖 measure 的最终输出。
rect = CachedRect(80, 20, 0, "#ED6A5A", dimensions, tint)
band = ViewportBand(80, 24, 0, "#237A45")
blue = Button("只改绘制颜色")
expand = Button("修改测量依赖")
// 保存两个监听连接,颜色按钮绑定 tint,宽度按钮绑定 dimensions,不把 UI 事件对象用作缓存 owner。
blueConnection = blue.on("click", tint.blue)
expandConnection = expand.on("click", dimensions.expand)
// 根组合同时展示 viewport 依赖和业务尺寸依赖;按钮回调完成后宿主统一刷新,不在点击方法里手工重排。
root = Column(24, 16, TextBlock("改变颜色保留测量缓存;改变宽度重新测量"), band, rect, blue, expand)
page = Page()
page.render(root)