refactor(panels): 平行数组合并为 std::vector<PanelRow>(消除错位与字段重载)
对应 Code_Review_Report §15.6 第 1 项(方案 B:有结构,无列视图)。
结构
- EdgePanelLayout 的 16 个平行 std::vector 合并为 std::vector<PanelRow> rows,
PanelRow 带 17 个具名成员:ref / header / nameRect / nameClose / triangle / check /
stats / levelTrack / levelValue / levelReset / iterTrack / iterValue / iterReset /
infoMaxInterval / infoMinInterval / intervalField / frequencyField。
- 唯一新增入口:AppendRow(ref, header, nameRect, triangle, check)(返回新行引用)与
AppendMarkerGroupRow(ref, nameRect, nameClose)(「自由标记」分组行)。
参数行/重采样行一律 layout.rows.back().xxx = … 赋值。
- 原 int rows(可见信号数)与新容器同名 ⇒ 改名 signalCount,并注明它与 rows.size()
在 MARK 面板里不相等(只有有固定点的信号才有行)。
消掉的两类问题
1. 某分支漏 push 一列 ⇒ 该列之后所有行读到别人的矩形(静默错位)。现在一行一次成型。
2. rowRefs 字段重载(列表式 = 行信号 / MARK = 分组信号,其余 12 列必须为空)。
现在每行自带 ref,语义由“填哪些字段”表达;不变式简化为语义断言
(每行必须有名称区;MARK 行不得带 header/check/stats/滑块/重采样字段)。
顺带清理
- 合并后 rowIndex < layout.rowXxx.size() 全部变成恒真,批量删除 50+ 处
(含 15 元组长度数组、? x : gd::RectF() 三元判空、if(...){extendRow(...)} 包裹)。
- 调试框与缓存键改为逐行遍历(新增字段只需在 PanelRow 与这两处循环各加一行)。
等价性证明(rowgeom 键名刻意保持不变,故可逐键比对)
old keys = 919, new keys = 965
仅存在于旧 = 0;已有键值变化 = 20(全部是 ".count":0 -> N)
仅存在于新 = 46(全部是新增列的 [NNN],值 0.00,0.00,0.00,0.00)
⇒ 逐行逐字段的真实几何零位移;7 个面板像素哈希(含 resample=2BFC74B3D9B3239C)逐项不变。
验证
- make release:零 warning;784,896 → 782,336 B(−2,560);make debug / make -C Tools 同样零 warning
- UnitTests:checks=260 failed=0 cases=19
- OffscreenChecks -all:7 检查 / 133 断言(上轮 127)全 PASS
- panels -mode compare:7 面板像素哈希逐项不变
- rowgeom -mode compare:965+7 键 0 差异;-data MF4-Record.MF4 时 1268+7 键 0 差异
- 读点:旧 243 处 layout.rowXxx[…] → 现 95 处 layout.rows[…](84 命中判定 / 11 绘制)
过程记录:清理恒真判空时曾用整段替换把「均值滤波」双滑块段误换成「弱峰」双滑块,
编译器报 brace 不平衡,用备份回滚后重做 —— 整段替换必须先精确读出上下文。
文档:Plan §十一、Progress 第 39 轮、Report §16、agent_mem 第 39 轮、Tools/README §4.1/§4.4
This commit is contained in:
1 parent
f07ac74988
commit
1463f9d3f8
11 files changed
+672
-591
No files matched your search
@@ -683,3 +683,73 @@ B 的**剩余收益**主要是"单一分配 + 少 15 个 vector 头"(`EdgePane
|
||||
让"MARK 面板 12 列为空"的注释消失。
|
||||
3. 面板几何算式重写(§13.6 遗留):基线已就绪,但需先完成 1 或 2。
|
||||
|
||||
---
|
||||
|
||||
## 十六、第 39 轮:平行数组合并为 `std::vector<PanelRow>`(§15.6 第 1 项,方案 B)
|
||||
|
||||
### 16.1 结论
|
||||
|
||||
| §15.6 建议 | 结果 |
|
||||
| --- | --- |
|
||||
| 1. 方案 B(`vector<PanelRow>` 无视图) | ✅ 完成:16 个平行数组 → `std::vector<PanelRow> rows`(17 个具名成员) |
|
||||
| 2. 在 B 之上拆分 `rowRefs` 双语义 | ✅ **顺带完成**:`rows[i].ref` 取代重载的 `rowRefs`,MARK 分组行改走 `AppendMarkerGroupRow` |
|
||||
| 3. 面板几何算式重写 | ⏸ 未做(本轮只做结构合并,算式未动) |
|
||||
|
||||
### 16.2 结构对比
|
||||
|
||||
| | 旧(16 个平行数组) | 新(`std::vector<PanelRow>`) |
|
||||
| --- | --- | --- |
|
||||
| 新增一列 | 改 `AppendRow` + 14 处布局分支 + 绘制 + 缓存键 + 调试框 + 检查的 15 元组 | 只在 `PanelRow` 加一个成员 |
|
||||
| 漏推一列 | 该列之后**所有行**读到别人的矩形(静默) | 不可能(一行一次成型) |
|
||||
| `rowRefs` 语义 | 列表式 = 行信号;MARK = 分组信号(同一字段两种含义) | `rows[i].ref` 一种含义;MARK 的分组行只填 `nameRect`/`nameClose` |
|
||||
| 长度不变式 | 15 个 `size()` 组成的判据,且 MARK 要单独分流 | 恒真 ⇒ 改为语义断言(每行都要有名称区;MARK 行不得带参数行字段) |
|
||||
| `EdgePanelLayout` 每实例 | 16 个 vector 头(16×24 B)+ 各自独立分配 | 1 个 vector 头 |
|
||||
|
||||
### 16.3 为什么这次敢做(前一轮不敢)
|
||||
|
||||
上一轮的顾虑是"列视图拷贝后忘重绑 = 静默悬垂"。方案 B **没有视图**:
|
||||
所有访问都是 `rows[i].check`,`PanelRow` 是值类型、随 `rows` 一起拷贝,**结构上不可能悬垂**。
|
||||
代价是 243 处读点必须机械改写(不省),收益是"漏推一列"与"字段重载"两类问题**从根上消失**。
|
||||
|
||||
### 16.4 等价性证明(本轮方法论的核心)
|
||||
|
||||
`rowgeom` 的键名刻意保持 `<panel>.<旧列名>[NNN]`,于是重构前后可以直接逐键比对:
|
||||
|
||||
```
|
||||
old keys = 919, new keys = 965
|
||||
仅存在于旧 = 0 ← 没有任何键消失
|
||||
已有键的值变化 = 20 ← 全部是 ".count" 键:0 -> N(结构变化)
|
||||
仅存在于新 = 46 ← 全部是新增列的 [NNN],值 0.00,0.00,0.00,0.00
|
||||
```
|
||||
|
||||
再叠加 7 个面板的像素哈希逐项不变 ⇒ **渲染与几何都没有任何位移**。
|
||||
这比"编译通过 + 肉眼看一眼"强得多:它把"等价重构"变成了**可证伪**的断言。
|
||||
|
||||
### 16.5 过程中唯一的一次事故
|
||||
|
||||
清理恒真判空时用"整段替换"把「均值滤波」双滑块段落误替换成「弱峰」双滑块,
|
||||
编译器立刻报 brace 不平衡;用备份回滚后重做。
|
||||
**结论:整段替换必须先精确读出上下文,oldString 不能凭记忆拼。**
|
||||
|
||||
### 16.6 验证
|
||||
|
||||
| 项 | 结果 |
|
||||
| --- | --- |
|
||||
| `make release` | 零 warning;784,896 → **782,336 B**(−2,560) |
|
||||
| `make debug` / `make -C Tools` | 零 warning |
|
||||
| `UnitTests` | 260 / 19 PASS |
|
||||
| `OffscreenChecks -all` | 7 / **133** PASS(上轮 127) |
|
||||
| `panels -mode compare` | 7 面板像素哈希逐项不变 |
|
||||
| `rowgeom -mode compare` | 965 + 7 键 / 1268 + 7 键(MF4),0 差异 |
|
||||
|
||||
### 16.7 下一步(按价值排序)
|
||||
|
||||
1. **面板几何算式重写**(§13.6 遗留):结构合并与逐行基线都已就绪,现在"改算式"是**安全的**;
|
||||
建议先做 `EdgePanelWidth`(逐信号量宽)与 `EdgePanelLayoutFor` 的行高累加,
|
||||
判据 = `rowgeom -mode compare` + `panels -mode compare` 双基线归零。
|
||||
2. **`PaintPanelListRows` 的通用参数行**提取(上轮因需 9 个参数而搁置):
|
||||
现在 `row` 是一个整体、`extendRow` 已成组,可把"参数行"收成一个函数,
|
||||
参数表从 9 个降到 `(g, layout, row, kind, state)` 5 个。
|
||||
3. 若还要压体积:`EdgePanelLayout` 已无冗余列,剩余空间主要在字符串/浮点格式化(见 §11 的 gdtoa 结论)。
|
||||
|
||||
|
||||
Reference in new issue
Block a user