feat(app-iced)+test(presenter): 句柄按 (目录,mtime,大小) 复用;缓存可清空;端到端出图

复审 r1 的三条:

1. 端到端图:DevDocs/artifacts/m251/saves-real-decode-light.png —— 真 host
   (ULL_SCREENSHOT_REAL_HOST=1 + --data-dir 一个临时数据根)→ 后台列 screenshots/ →
   palette_extract::thumbnail 真解码 → DTO → Handle::from_rgba → 上屏。三格是三张真 PNG
   的真像素,副文案的 2.3 KB / 2.2 KB / 24.1 KB 也是真扫描值。造根脚本与复现命令进
   artifacts/m251/{README.md,make-real-root.py},并写明「哪张是排版、哪张是端到端」。
2. 每帧重建 Handle 的成本:改成**缓存**(不是实测)。model.rs 新增 process-level
   memo,键 = (截图目录, 文件, mtime, 字节数)(与 presenter 的缓存键同源,目录单列一格),
   上限 120 条(≈12MB)。判据:the_same_screenshot_reuses_one_handle 断言两次
   from_state 拿到**同一个 Handle id**;变异(换回 Handle::from_rgba)即红。
   a_changed_screenshot_gets_a_new_handle 钉住「文件变了必须换句柄」。
3. 进程级 memo 的副作用:两层各加 #[cfg(test)] clear_cache()/clear_handles(),用例从
   已知状态起跑;两条上限从 240 收到 120(≈12MB/层,算术写进常量文档)。

顺带:句柄键改用 push 拼(format! 模板串会被页面字面量守门当成英文文案抓走);
preview 的页面模型用例拆到 tests/saves/preview.rs(saves.rs 破 400)。
This commit is contained in:
AskaEth committed 2026-11-11 17:09:17 +08:00
1 parent dd9962e610
commit 779a2ae254
6 files changed
+288 -110

No files matched your search

@@ -87,6 +87,9 @@ mod model;
mod rows;
mod wall;
/// 句柄 memo 的清空入口(只给用例:它是进程级 memo)。
#[cfg(test)]
pub(super) use model::clear_handles;
pub use model::{failure_line, from_state, Row, Saves, Shot, ShotPreview};
/// 写操作成功那句话的产地(实现在 [`rows`] 里)。
///