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

53 lines
2.6 KiB
Plaintext

// 测量与绘制依赖分离:改颜色应复用尺寸缓存,改模型宽度才需要重新测量。
// ViewportBand 还显式读取实际页面视口,使原生 resize 可通过依赖触发重测。
// 只负责测量需要的宽度,和绘制颜色分成两个业务对象以便观察独立失效。
class WidthModel {
width: Number
// 点击把模型宽度置为 260;源 measure 读取过该字段,缓存因此失效。
function expand(self: WidthModel, event: Event): Unit {
self.width = 260
}
}
// 保存 paint 使用的颜色,不参与 CachedRect 的测量。
class Tint {
color: String
// 只改颜色;正常情况下需重绘而不重新执行无关源测量。
function blue(self: Tint, event: Event): Unit {
self.color = "#526AC7"
}
}
// 原生矩形的尺寸/颜色策略分别由源协议覆盖,业务模型通过字段持有。
class CachedRect: RectBlock {
dimensions: WidthModel
tint: Tint
// 读取 dimensions.width 返回固定高 60;实际读观察由运行时缓存记录,不手工声明依赖表。
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 {
drawing = RectBlock.paint(self, mount, geometry)
drawing.commands.at(0).color = self.tint.color
return drawing
}
}
// 宽度来自 ui.viewport 的当前逻辑页面区域,显示窗口变化也能成为测量依赖。
class ViewportBand: RectBlock {
// 返回可用视口宽度,最终仍服从父容器约束;外层 padding 会减少分配宽度。
function measure(self: ViewportBand, mount: Mount, constraints: Constraints): MeasureResult {
return MeasureResult(ui.viewport().width, 24)
}
}
// 创建相互独立的宽度/颜色模型并绑定两个按钮,用相同对象观察缓存与可见结果。
dimensions = WidthModel(200)
tint = Tint("#ED6A5A")
rect = CachedRect(80, 20, 0, "#ED6A5A", dimensions, tint)
band = ViewportBand(80, 24, 0, "#237A45")
blue = Button("只改绘制颜色")
expand = Button("修改测量依赖")
blueConnection = blue.on("click", tint.blue)
expandConnection = expand.on("click", dimensions.expand)
root = Column(24, 16, TextBlock("改变颜色保留测量缓存;改变宽度重新测量"), band, rect, blue, expand)
page = Page()
page.render(root)