Stabilize visible item snapshots (T-609)

This commit is contained in:
ila
2026-07-17 17:31:46 +08:00
parent ed9ded2110
commit 171572973b
9 changed files with 180 additions and 18 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ UI 固定交互模式:
控件状态按**软件 ID**保存,不按列表序号;列表用惰性 `layout.List`;图标走内存 + 磁盘缓存。
T-203 已把共享列表状态落在 `core/application.CatalogListModel`:源快照、搜索、单分类、all/installed/updates 视图和 selected app ID 都是无 IO 纯内存状态。两个 Gio 适配分别保存 Editor、`layout.List` 与以 app ID 为键的 Clickable;主循环或后台用例通过 `SetItems` 替换准备好的快照,Layout 不扫描 installed-app.json、不获取 Catalog。T-608 在两个隔离 workspace 以同场景交互契约验证 Editor/Clickable 经 `Layout`/`drainInput` 更新共享 model、重排后行点击仍按 AppID、关闭详情保留筛选与列表位置、500 项只布局 `layout.List.Position.Count` 所示可见子集,并通过语义树区分空 Catalog 与过滤无结果;不重复 ViewModel 纯逻辑。
T-203 已把共享列表状态落在 `core/application.CatalogListModel`:源快照、搜索、单分类、all/installed/updates 视图和 selected app ID 都是无 IO 纯内存状态。两个 Gio 适配分别保存 Editor、`layout.List` 与以 app ID 为键的 Clickable;主循环或后台用例通过 `SetItems` 替换准备好的快照,Layout 不扫描 installed-app.json、不获取 Catalog。T-608 在两个隔离 workspace 以同场景交互契约验证 Editor/Clickable 经 `Layout`/`drainInput` 更新共享 model、重排后行点击仍按 AppID、关闭详情保留筛选与列表位置、500 项只布局 `layout.List.Position.Count` 所示可见子集,并通过语义树区分空 Catalog 与过滤无结果;不重复 ViewModel 纯逻辑。T-609 让每次实际 refilter 在局部新 backing array 完整构造后发布 `VisibleItems` generation,旧 generation 可安全保留到后续帧且每帧读取不复制;返回值严格只读,model 仍由单 owner goroutine 串行操作,不承诺并发安全。
T-204/T-606/T-607 图标链路为 `Catalog icon digest + DPI → 32 MiB/256-key memory LRU → verified disk → 流式 IconFetcher(maxBytes+1) → SHA-256/图片资源限制校验 → 原子磁盘缓存 → 后台 DecodeIcon → IconReady/IconFailed application event → bounded FIFO relay + Window.Invalidate → Frame/UI ApplyEvent → ApplyIcon(paint.ImageOp)`。同一 key 由一个 in-flight leader 去重,不同 key 的磁盘/网络工作并行;全局锁只保护 memory/LRU/in-flight 元数据。relay 队列满时无损背压且可由 context/close 取消,后台从不修改 shell map。UI 只接受当前 app 最新且 icon_ref/DPI 匹配的 request_id;删除 app、替换 IconRef 或取消会使迟到结果失效,替换 IconRef 同时清除旧 ImageOp。磁盘与远端都重新校验,断网只使用已验证磁盘缓存;详情右栏只读取 `CatalogListModel.SelectedItem` 与内存 ImageOp,关闭详情不清空筛选或列表位置。