全项目大检查:修复数据层/UI 真 BUG、清理死代码与过期注释、并评估二进制体积
按「性能 / BUG / 错误 / 过期注释 / 命名与实际含义不符」四项对全仓做了一次审查, 四个只读子审查交叉核对后逐条回到源码确认再改。 一、数据层真 BUG - MatH5:U8/U16/U32/U64 用逐字节 Cached() 拼装,而 Cached 只服务「完全落在同一个 64KB 块内」的请求 => 跨块时静默读成 0(U32 整段为 0、U64 高 32 位为 0),分块 B-tree 的 chunk 偏移/子节点地址被破坏且无任何报错。新增 ScalarLE():命中缓存用缓存, 否则退回一次 ReadAt;U64 顺带从 8 次缓存查找降到 1 次。 - Mf4Loader::IsBlock 未校验链接表是否落在块内 => DataOffset 越界,随后 block_len - (data - offset) 在 uint64 上下溢,得到一个约 2^64 的"可用字节数", 下游 vector(usable+1) 直接 bad_alloc。同时把 offset + bytes > size 改成不产生回绕的写法。 - DecodeRawValue 的整数路径:bit_offset%8 != 0 且位宽 64 时需 9 个字节,先拼成 64 位 再整体右移会把最高字节静默丢弃 => 改为逐字节带位偏移累加。 - cg_cycle_count 加「数据段总字节 / 记录字节」上限(压缩段按 deflate 最大膨胀比估算)。 - CsvLoader 表头分支同样跳过 #/% 注释行(否则整份文件按 1 列解析并被丢弃)。 - MatLoader:double -> int 的越界转换加了范围检查;普通对象递归加深度上限与成环检测。 - Utf8Util::BuildTicks:double -> long long 越界转换前先判商是否落在 ±9e18 内。 二、界面 BUG - 工具栏按钮永远不显示悬停高亮:Paint 读的 Button::hover 全仓从未赋值,改为按 m_hoverIndex 判断。 - 菜单打开时"取消底层拖拽"对每个消息都执行,把菜单自己的 Target::EDIT_FIELD 也清掉 => 菜单内联输入框无法拖拽框选。排除 EDIT_FIELD。 - GdiplusShutdown 之前未释放 PlotView 的 GDI+ 位图(Application 是进程单例,成员析构在 WinMain 之后)=> 新增 PlotView::ReleaseGraphicsResources() 并在 Shutdown 里调用。 - WM_KILLFOCUS 现在会提交标签页/绘图区编辑并复位捕获与拖拽状态。 - WM_LBUTTONUP 不再抢走中键平移的鼠标捕获。 - TextEdit:被过滤器拒绝的字符返回 false;无选区时 Ctrl+X 只复制、不再清空整段文本。 - SignalPanel::InvalidateRows 作废编辑/待确认/改名计时等行下标状态。 - EndFilterEdit 改走 ApplyFilterText(否则输入纯空格后回车,列表仍停在筛选结果)。 - 新增 SignalBadgeVisible 作为唯一判据(原来命中只看"可见",绘制还要求"已分配网格")。 - 折起动画结束后夹取滚动量;双击分组名改名时清掉该组正在播放的折起动画。 - ScrollToSignal 复用 SignalScrollTarget(含悬浮组名避让)。 - RowNameRect 与绘制使用同一最小宽度(原来退化时返回空矩形)。 - 分隔条拖拽上限改用与 Relayout 同一公式;UpdateDragCursor 补 SPLITTER/EDIT_FIELD。 - SignalPanel 里几个守卫改为判断真正被解引用的指针;分组行 ✕ 也返回手型光标。 三、PlotView - FindStyleOnlyLanes 改用完整的 SceneStyleEntry::operator==(原来只比 4 个字段, 另一个网格同时改"调整"时带着旧像素被当成最新)。 - 宽基底图层不再烘焙拖拽光晕(LaneLayerHash 不含它),改由 PaintHoverHighlight 每帧叠加。 - PaintLaneLegend 提前返回前清掉本网格的命中矩形(否则能点中看不见的图例条目)。 - 面板主体改为完全不透明(消除平移后 4% 透出的旧波形,零额外代价)。 - PAN / Shift+滚轮改走 SetTimeView,使"自动点线"判据随平移重算。 - 内联输入框命中字体与绘制统一为 monoSmall。 - 派生曲线取值与窗口按 SourceIndexFor 映射(水平镜像时不再读到镜像另一端)。 - EdgePanelWidth 补 style/axis 空指针守卫;二分结果夹到 count。 四、清理 - 删除 Toolbar::ActionLabel、Theme::statusBg、PopupMenu 的 editResult 死机制、 Toolbar::Layout 的重复 clear()、HitRow 的恒假分支、OnDoubleClick 的重复判定、 PaintUtil 里孤立的注释块。 - 修正一批过期/错误注释(包络带"不做加宽"、LaneLayerHash 的图例说法、 均值滤波曲线的窗口说法、样式区行数与「调整」按钮顺序、FIT_ALL 退出缩放模式、 RemoveSignal 的 ✕ 位置、.mat/.dat 格式文档、MatH5 的"映射视图"、DataModel 的 "点线/被移除文件"、SignalPanel 的"行高连续缩小"、TextEdit 的 PaintUtil 引用等)。 五、二进制体积评估(按要求只评估,未做压缩修改) - release 809,472 字节;.text 652KB、.xdata+.pdata 约 75KB、.rdata 42KB、 .rsrc 20KB、.idata 11.5KB。 - 去掉 -ld3d11 -ldwmapi -ld3dcompiler(仓内无任何调用)实测 0 字节收益 (静态库只拉取被引用的对象)=> 删链接库不是压缩手段,只是配置整洁。 - 仓内已无 <iostream>/<sstream>/<filesystem>/<regex>/<locale> 等体积炸弹。 - 结论:已无明显的浪费可捡;要显著变小只能改变取舍(动态 CRT / UPX / 砍功能), 需要用户决策,本轮未动。 验证 - editcheck 20/20、round3check 31/31、round4check 34/34、round5check 5/5、convcheck 18/18。 - check 136/137:唯一失败项经 git stash 回到改动前复现同一数值,属该探针自身的既有 不稳定项(取决于前置用例留下的缓存/时序),与本轮改动无关。 - 真实数据:4 个 MF4 => 283/8/18/24 个信号;.mat 样例 8 信号、 带无障碍对照-防夹力曲线数据 8 信号、BIG_MAT.mat 5 信号(私有内存 +741MB)。 - make release / make debug 零警告。 文档:Documents/agent_mem.md 同步 §10 变更日志、§11.2 第 171-180 条硬约束 与文末本轮小节(含体积评估数据)。
This commit is contained in:
1 parent
30f853a361
commit
53b981a2a9
32 files changed
+691
-230
No files matched your search
@@ -3007,6 +3007,8 @@ else if (panelOnly) { /* 只回送“本帧重绘过的区域并集” */ }
|
||||
|
||||
| 2026-10-20 | DeepSeek-V4.1-Flash(**本机**) | **MF4 `##CA` 全字段(`ca_type`/`cycle_count`/`byte_offset_base`)+ 3 维命名 + 记录容量校验;`cc_type = 8` 区间枚举;稠密包络带的线宽改为「纵横双向加粗」(详见 §12 末尾「2026-10-20 第五轮」与 §11.2 第 165–170 条)**。① **`##CA`**:`ce_type`/`ca_storage`/`ndim`/`flags`/`ca_byte_offset_base`/`ca_inval_bit_pos`/`dim_size[]`/`cycle_count[]` 全部按**块长度做边界检查**后读取(`cycle_count[]` 实测缺失,盲读会拿到下一个块头 1481909027);展开条件从「数一个魔数上限」改为**记录容量校验** `bit_offset + 元素数×位宽 ≤ cg_data_bytes×8` + `cycle_count 每维 ≤ 1` + `ca_type ≤ 2`;规模护栏改为「元素数 ≤ 16384 且 元素数×记录数 ≤ 32M 单元格」;名字按 `dim_size[]` 逐维取余 ⇒ 1/2/3 维分别得到 `[i]`/`[i][j]`/`[i][j][k]`。② **`cc_type = 8`**(值区间→文本):`cc_val` 交错 `(下限,上限)`、`cc_ref[4+i]` 为第 i 段文本,`SignalEnumText` 新增 `rangeMin/rangeMax/rangeTexts` + `HasRanges()/Count()`,`Find` 先精确表后区间表;**仍然只在光标取值标注里追加 ` = <文本>`**。③ **线宽**:包络带旧实现只在每列**纵向**外扩 `strokeHalf` ⇒ 方波的竖直沿横向宽度始终是 1 个像素列(用户把线宽 1px 拖到 10px 时竖直沿完全不变);`EmitEnvelopeBand` 新增 `halfWidth` 形参,对上下包络做**横向窗口膨胀**(`top` 取窗口最小、`bottom` 取窗口最大)后再纵向各外扩,两个方向都随线宽变化。验证:`convcheck` **18/18**(新增 3 维命名、放不进记录的数组必须拒绝展开、区间枚举命中/未命中);新增 `.preflight/round5check` **5/5**(合成 20 万采样数字信号 ⇒ 包络带,中间行竖直沿墨迹 1px→6px、10px→30px);**A/B 关闭横向膨胀 ⇒ 1px→2px、10px→2px 并如实失败**;回归 `check` 137/137、`editcheck` 20/20、`round3check` 31/31、`round4check` 34/34,真实 MF4 信号数 283/8/18/24 不变;`make release`/`make debug` 零警告;`TargetCheck.exe` **808,448 字节**(789.5 KiB)。 |
|
||||
|
||||
| 2026-10-20 | DeepSeek-V4.1-Flash(**本机**) | **全项目大检查(性能 / BUG / 过期注释 / 错误命名)+ 修复(详见 §12 末尾「2026-10-20 第六轮」与 §11.2 第 171–180 条)**。① **数据层 BUG**:`MatH5` 的 `U8/U16/U32/U64` 用「逐字节 `Cached()`」拼装,而 `Cached` 只服务同一 64KB 块内的请求 ⇒ **跨块标量静默读成 0**(分块 B-tree 的 chunk 偏移/子节点地址被破坏,无任何报错);改为 `ScalarLE()`(命中缓存用缓存,否则一次 `ReadAt`)。`Mf4Loader::IsBlock` 未校验链接表是否落在块内 ⇒ `DataOffset` 越界后 `block_len - (data-offset)` **uint64 下溢**,下游 `vector(usable+1)` 直接 `bad_alloc`;`ReadAt`/`IsBlock` 的 `offset + bytes > size` 也回绕。非字节对齐的 **64 位整数**用「先拼 64 位再右移」会丢掉最高字节(32/8 位宽度组合受影响);`cg_cycle_count` 无上限(损坏文件可让程序申请几十 GB);`CsvLoader` 表头分支不跳过 `#`/`%` 注释行(整份文件解析失败);`MatLoader` 把文件里的 double 直接 `static_cast<int>`(NaN 越界 = UB)、普通对象递归无深度上限;`Utf8Util::BuildTicks` 的 `double→long long` 越界转换。② **UI BUG**:工具栏按钮**永远不显示悬停高亮**(`Paint` 读的 `Button::hover` 全仓从未赋值);菜单打开时**每个消息**都无条件取消底层拖拽 ⇒ 菜单自己的内联输入框无法拖拽框选(`Target::EDIT_FIELD` 被误清);`GdiplusShutdown` 前未释放 `PlotView` 的 GDI+ 位图(`Application` 是进程单例,退出时访问违例);`WM_KILLFOCUS` 不提交标签页/绘图区编辑;`WM_LBUTTONUP` 无条件 `ReleaseCapture` 抢走中键平移的捕获;`TextEdit` 字符被过滤器拒绝却返回 `true`、无选区时 `Ctrl+X` **清空整段文本**;`InvalidateRows()` 不作废 `m_editRow` ⇒ 行集合变化后回车把新名字写到**另一条**信号;`EndFilterEdit` 不调 `ApplyFilterText`(空格+回车后列表仍处于筛选态);`SignalBadgeVisible` 三处判据不一致(未绘制处仍可点出菜单);折起动画结束后不夹取滚动量(列表底部空白 + 滑块画出轨道);快速双击分组名改名后**折起动画仍在播**。③ **PlotView 缓存/正确性**:`FindStyleOnlyLanes` 只比 4 个外观字段,而 `SceneGeometryHash` 还排除了系数/镜像/偏移 ⇒ 两个网格同时改不同属性时有一个带着旧像素被当成“最新”;拖拽光晕被烘进宽基底图层(`LaneLayerHash` 不含它);`m_legendHits` 半可见时提前返回导致点中“看不见的图例”;面板主体 96% → **不透明**(消除平移后 4% 透出的旧波形);PAN / Shift+滚轮绕过 `SetTimeView`(自动点线不随平移重判);内联输入框命中用 `uiSmall` 而绘制用 `monoSmall`;派生曲线取值未按 `SourceIndexFor` 映射(水平镜像时读到镜像另一端);`EdgePanelWidth` 缺 `style/axis` 空指针守卫;`MinorCellSparse`/`AutoRangeLaneToView` 的二分结果未夹到 `count`(时间轴比 values 长时越界)。④ **清理**:删除死接口 `Toolbar::ActionLabel`、`Theme::statusBg`、`PopupMenu::editResult` 死机制、`Toolbar::Layout` 的重复 `clear()`、`HitRow` 的恒假分支、`OnDoubleClick` 的重复命中判定;修正一批过期/错误注释(`EmitEnvelopeBand` “不做加宽”、`LaneLayerHash` 的图例说法、`MeanFilterCurve` 的窗口说法、样式区行数与「调整」按钮顺序、`FIT_ALL` 退出缩放模式、`RemoveSignal` 的 ✕ 位置、`.mat`/`.dat` 格式文档、`MatH5` “映射视图”等)。⑤ **体积评估(未做修改)**:release **809,472 B**;`objdump` 分节 `.text 652KB / .xdata 43KB / .pdata 32KB / .rdata 42KB / .rsrc 20KB / .idata 11KB`;**去掉 `-ld3d11 -ldwmapi -ld3dcompiler` 实测 0 字节收益**(静态库只拉引用到的对象);仓内已无 `<iostream>/<sstream>/<filesystem>` 等体积炸弹。验证:全部离屏探针(`check`/`editcheck`/`round3check`/`round4check`/`round5check`/`convcheck`/`loadcheck`)与 4 个 MF4 + 3 个 `.mat`(含 1.29GB `BIG_MAT.mat`)回归通过;`make release`/`make debug` 零警告。 |
|
||||
|
||||
## 11. 跨设备协作须知(起源设备视角)
|
||||
|
||||
> **本文件是唯一权威记忆**。所有设备 / Agent 共用它,**不要再新建 `agent_mem_origin.md` 等旁支记忆文件**。
|
||||
@@ -3831,6 +3833,41 @@ else if (panelOnly) { /* 只回送“本帧重绘过的区域并集” */ }
|
||||
`123.456789 → 123.457`,`123.456789 ± 5e-7` 的两个值格式化后完全相同(波动在第 9 位有效数字上),
|
||||
且指数 < -4 或 ≥ 6 时切成科学计数法(`0.0000123456 → 1.23456e-05`)。
|
||||
想看到微小波动必须改显示格式(本轮未改,属显示策略而非数据丢失)。
|
||||
171. ⚠️⚠️ **`MatHdf5::Cached(offset, bytes)` 只服务「完全落在同一个 64KB 块内」的请求**,
|
||||
跨块时返回 `nullptr`。因此**绝不可以用它逐字节拼多字节标量**:`U32` 会整段读成 0、
|
||||
`U64` 高 32 位读成 0,分块 B-tree 的 chunk 偏移/子节点地址被**静默**破坏(mdf-over-hdf5 类
|
||||
数据看起来“缺块”)。统一走 `ScalarLE()`:命中缓存就用缓存,否则退回一次 `ReadAt`。
|
||||
⚠️ 顺带这也把 `U64` 从 8 次缓存查找降到 1 次。
|
||||
172. ⚠️⚠️ **MDF 的 `IsBlock()` 必须校验「链接表落在块内」**(`24 + 8*link_count <= block_len`):
|
||||
否则 `DataOffset()` 会算到块尾之外,随后 `block_len - (data - offset)` 在 `uint64` 上**下溢**,
|
||||
得到一个约 2^64 的“可用字节数”,下游 `vector(usable + 1)` 直接抛 `bad_alloc`
|
||||
—— 一个损坏的链接数就能让加载崩溃。同理 **`offset + bytes > size` 必须写成
|
||||
`offset > size || bytes > size - offset`**(接近 2^64 的偏移会让加法回绕、校验“通过”)。
|
||||
173. ⚠️⚠️ **按位取出整数时不能「先拼成 64 位再整体右移」**:`bit_offset % 8 != 0` 且位宽为 64 时
|
||||
需要 9 个字节(65–71 位),先拼装会让最高字节整体左移出 64 位被**静默丢弃**。
|
||||
正确做法是逐字节**带着位偏移累加**(`8*i - shift` ≥ 0 左移,否则右移对齐)。
|
||||
174. ⚠️ **`cg_cycle_count` 不可无条件相信**:损坏/伪造文件可以声明几十亿条记录,而
|
||||
`ReadChannelGroupRecords` 会按它一次性 `assign(cycles × 通道数)` 个 double。
|
||||
必须用「记录数据总字节数」做上限(压缩段按 deflate 最大膨胀比 ≈1032:1 估算)。
|
||||
175. ⚠️ **CSV 的表头分支也必须跳过 `#` / `%` 注释行**:否则注释行被当成表头(列数变 1),
|
||||
后面真实的表头与数据行全部按 1 列解析并被丢弃 ⇒ 整个文件加载失败。
|
||||
176. ⚠️⚠️ **`SignalPanel::InvalidateRows()` 必须一并作废行下标状态**(`m_editField`/`m_editRow`、
|
||||
`m_pendingCloseRow`/`m_pendingClosePart`、`m_groupNameClickRow`):行集合可能在“编辑中”变化
|
||||
(加载文件 → `SyncTabsToDataSet()` → `InvalidateRows()`),不清理则回车会把新名字写到
|
||||
**另一条**信号上(插入型变更让下标整体位移),✕ 也可能删错分组。
|
||||
177. ⚠️⚠️ **UI 悬停态必须有唯一数据源**:`Toolbar` 曾在 `Paint` 里读 `Button::hover`,而该字段
|
||||
全仓从未赋值 ⇒ 按钮永远不高亮(只写不读的“悬停变量”)。新增悬停态时先确认**读的那一份**
|
||||
真的被写。
|
||||
178. ⚠️⚠️ **`GdiplusShutdown` 之前必须释放所有 GDI+ 资源**,包括 `PlotView` 持有的位图
|
||||
(场景/图层/装饰/面板/光晕 + 并行图层 worker 各自的位图)。`Application` 是进程级单例,
|
||||
其成员要等 `WinMain` 返回后才析构 —— 那时 GDI+ 已关闭,位图析构必然访问违例。
|
||||
入口:`PlotView::ReleaseGraphicsResources()`(幂等,析构函数也调它)。
|
||||
179. ⚠️⚠️ **任何“时间视界写入”都必须走 `SetTimeView()`**(缩放/平移/滚轮/选区)。PAN 与
|
||||
Shift+滚轮曾直接改 `ViewMin()/ViewMax()`,于是「自动点线」判据在平移时永远不重算
|
||||
(从密集区平移到稀疏区也不切换),与文档承诺矛盾。
|
||||
180. ⚠️ **二分得到的可见下标必须夹到 `count = min(时间轴长度, values 长度)`**:分组时间轴可能比
|
||||
某条信号长(多信号共轴、有的信号短),`lower_bound` 在**整条** `axis.time` 上进行时
|
||||
`begin/end` 会超出 `values` 范围 ⇒ 逐点扫描越界读。
|
||||
|
||||
### 11.3 离屏验证方法学(本机偏好,强烈建议沿用)
|
||||
|
||||
@@ -6937,4 +6974,115 @@ DG3 data=0 cycle=0 (空组,一个字符串通道)
|
||||
真实 MF4 信号数 283 / 8 / 18 / 24;枚举表仍解析出 32 / 12 / 5 / 32 项。
|
||||
- `make release` / `make debug` 零警告;`TargetCheck.exe` **808,448 字节**(789.5 KiB,仍 < 800KB)。
|
||||
|
||||
---
|
||||
|
||||
## 本轮(2026-10-20 第六轮,本机):全项目大检查(性能 / BUG / 过期注释 / 命名)+ 体积评估
|
||||
|
||||
> 用户要求:对全项目做一次大检查(性能、BUG、错误、过期注释、函数/参数命名与实际含义不符),
|
||||
> 修复存在的问题;然后**评估**能否进一步压缩二进制体积(但**先不要**往压缩方向改);完成后提交。
|
||||
> 方法:四个只读子审查(`Utilities` / `PlotView` / `SignalPanel+TabBar+Toolbar` / `Application+Shared`)
|
||||
> 交叉核对,每条结论都回到源码逐行确认后才动手。
|
||||
|
||||
### A. 数据层(`Utilities`)修复
|
||||
|
||||
| 位置 | 问题 | 修法 |
|
||||
| --- | --- | --- |
|
||||
| `MatH5::U8/U16/U32/U64` | 逐字节 `Cached()` 拼装,而 `Cached` 只服务同一 64KB 块内请求 ⇒ **跨块标量静默为 0**(分块 B-tree 地址被破坏,无报错) | 新增 `ScalarLE()`:命中缓存用缓存,否则一次 `ReadAt`;`U64` 从 8 次查找降到 1 次 |
|
||||
| `Mf4Loader::IsBlock` | 未校验链接表落在块内 ⇒ `DataOffset` 越界,`block_len-(data-offset)` **uint64 下溢** ⇒ `vector(2^64)` 崩溃 | 校验 `24 + 8*links <= block_len`;`ReadAt`/`IsBlock` 的边界判断改为不产生回绕的写法 |
|
||||
| `DecodeRawValue` 整数路径 | 非字节对齐的 **64 位**整数需要 9 字节,先拼 64 位再右移会丢掉最高字节 ⇒ 数值错误 | 改为逐字节**带位偏移累加** |
|
||||
| `cg_cycle_count` | 完全信任文件里的记录数(损坏文件可申请几十 GB) | 用「数据段总字节 / 记录字节」做上限,压缩段按 deflate 最大膨胀比估算 |
|
||||
| `CsvLoader` 表头 | 不跳过 `#`/`%` 注释行 ⇒ 整份文件按 1 列解析并丢弃 | 表头分支同样跳过注释行 |
|
||||
| `MatLoader` | `static_cast<int>(double)`(NaN / 越界 = UB);结构体递归无深度上限 | 新增 `StreamIndexFromDouble()`(非法返回 -1);递归加深度 32 + 已访问集合 |
|
||||
| `Utf8Util::BuildTicks` | `double → long long` 越界转换(`1e300/1e-300` 溢出为 inf) | 先判商落在 ±9e18 内,否则放弃画刻度 |
|
||||
|
||||
### B. PlotView 修复
|
||||
|
||||
- **`FindStyleOnlyLanes` 只比 4 个字段**(color/opacity/lineWidth/mode),而 `SceneGeometryHash`
|
||||
还排除了系数/绝对值/镜像/偏移 ⇒ 两个网格同时改不同属性时只有一个被登记为脏,
|
||||
另一个带着旧像素被当成“最新”。改为 `!(now[index] == before[index])`(`SceneStyleEntry::operator==`)。
|
||||
- **拖拽光晕被烘进宽基底图层**:`PaintLane` 画光晕时没有 `!m_renderWide` 守卫,而 `LaneLayerHash`
|
||||
不含光晕状态 ⇒ 拖拽期间重建一次图层就把半透明光晕永久烘进去。图层内跳过光晕,
|
||||
改由 `PaintHoverHighlight` **每帧叠加绘制**(它也扩展为“拖拽中画被拖信号的光晕”)。
|
||||
- **`m_legendHits` 半可见残留**:`PaintLaneLegend` 在“图例带不完全可见”时提前 return,
|
||||
上一帧的命中矩形留在原位 ⇒ 能点中**看不见的**图例条目。提前返回前先清掉本网格的命中项。
|
||||
- **面板主体 96% → 完全不透明**(`0xF4` → `cardBg`):面板像素图层被缓存复用,而
|
||||
`PanelGlobalKey` 刻意不含视界/幅值(否则平移、竖向拖拽每帧重画全部面板)⇒ 那 4% 透出的
|
||||
“面板背后的场景”会一直停在**平移前**的波形。改为不透明后取舍消失且零代价。
|
||||
- **PAN / Shift+滚轮改走 `SetTimeView`**(视界唯一写入口):否则「自动点线」判据在平移时
|
||||
永远不重算(从密集区平移到稀疏区也不切换)。
|
||||
- **内联输入框命中字体**:绘制用 `monoSmall`,命中用 `uiSmall` ⇒ 插入符位置偏移。统一 `monoSmall`。
|
||||
- **派生曲线取值未做镜像映射**:曲线按 `values` 的**源下标顺序**计算,而光标给的是显示下标 ⇒
|
||||
水平镜像时读到镜像另一端。窗口与取值都改为 `SourceIndexFor` 后的源下标。
|
||||
- **`EdgePanelWidth` 缺 `style/axis` 空指针守卫**(它被绘制、命中、`QueryCursor` 调用)。
|
||||
- **二分结果未夹到 `count`**(`MinorCellSparse` / `AutoRangeLaneToView`):分组时间轴比信号长时越界读。
|
||||
|
||||
### C. 界面(SignalPanel / Toolbar / Application / Shared)修复
|
||||
|
||||
- **工具栏按钮永远不高亮**:`Paint` 读 `Button::hover`,该字段全仓从未赋值。改为按 `m_hoverIndex` 判断。
|
||||
- **菜单自己的内联输入框无法拖拽框选**:菜单打开时“取消底层拖拽”的代码对**每个消息**都执行,
|
||||
把菜单的 `Target::EDIT_FIELD` 也清掉了(并释放了捕获)。排除 `EDIT_FIELD`。
|
||||
- **退出时 GDI+ 访问违例**:`GdiplusShutdown` 前未释放 `PlotView` 的位图(单例析构在 `WinMain` 之后)。
|
||||
新增 `PlotView::ReleaseGraphicsResources()` 并在 `Shutdown()` 里调用。
|
||||
- **`WM_KILLFOCUS` 不提交编辑**:标签页重命名与绘图区内联输入停留在编辑态(Alt+Tab 回来继续打字)。
|
||||
改为提交 + 复位捕获/拖拽状态。
|
||||
- **`WM_LBUTTONUP` 无条件释放捕获**会抢走中键平移的捕获 ⇒ 平移“卡住”。中键平移期间不释放。
|
||||
- **`TextEdit`**:被过滤器拒绝的字符曾返回 `true`(调用方以为内容已变);**无选区 `Ctrl+X` 会清空整段文本**
|
||||
(用户想复制阈值却把值删了)⇒ 改为只复制、不清空。
|
||||
- **`SignalPanel::InvalidateRows()` 不作废行下标** ⇒ 行集合在编辑中变化后回车会把名字写到别的信号上。
|
||||
- **`EndFilterEdit()` 不调 `ApplyFilterText()`** ⇒ 输入纯空格后回车,列表仍停在筛选结果。
|
||||
- **`SignalBadgeVisible()` 成为唯一判据**(原来命中只看“可见”、绘制还要求“已分配网格”)。
|
||||
- **折起动画结束后夹取滚动量**(`RefreshScrollBar(animationFinished)`):否则列表底部空白、滑块画出轨道。
|
||||
- **快速双击分组名改名后折起动画仍在播**:进入改名时清掉该组的动画条目。
|
||||
- **`ScrollToSignal` 复用 `SignalScrollTarget`**(含悬浮组名避让):原来切标签页后选中项被悬浮组名遮住。
|
||||
- **`RowNameRect` 与绘制使用同一最小宽度**(原来退化时返回空矩形,名字画得出来但双击得到 0 宽输入框)。
|
||||
- **分隔条拖拽上限改用与 `Relayout()` 同一公式**(原来恒等于 `kMaxPanelWidth`,窄窗口下宽度回弹)。
|
||||
- **`UpdateDragCursor` 补 SPLITTER/EDIT_FIELD**(拖分隔条显示 `IDC_SIZEWE`、输入框显示 `IDC_IBEAM`)。
|
||||
- **`ApplyWidthFromX`/`ApplyOpacityFromX`/`ApplyColor`/`BeginEdit` 的守卫改为判断真正解引用的指针**
|
||||
(原来判 `m_tab`,实际用的是 `m_dataSet(Writable)`)。
|
||||
- **分组行 ✕ 也返回手型光标**(与信号行 ✕ 视觉一致);`ScrollThumbRect` 的进度夹到 [0,1]。
|
||||
|
||||
### D. 清理(死代码 / 死机制 / 过期注释)
|
||||
|
||||
- 删除:`Toolbar::ActionLabel`(无调用)、`Theme::statusBg`(状态栏早已删除、无读取)、
|
||||
`PopupMenu` 的 `editResult` 保存/还原(永远原样返回空结果)、`Toolbar::Layout` 的重复 `clear()`、
|
||||
`SignalPanel::HitRow` 的恒假分支、`PlotView::OnDoubleClick` 的重复命中判定、
|
||||
`PaintUtil.cpp` 里孤立的注释块。
|
||||
- 修正过期/错误注释:`EmitEnvelopeBand` 的“不做任何列窗口加宽”(现按线宽横向膨胀)、
|
||||
`LaneLayerHash` 的“图例文案计入”(实际未计入)、`PaintMeanFilterCurve` 的“只取可见区间±保护带”
|
||||
(实际按整条计算)、样式区“固定四行/中心反转/0=系数调整”、`FIT_ALL` 的“同时退出缩放模式”、
|
||||
`Application::RemoveSignal` 的“行左侧 ✕”、`.mat`(`LoadSignalSource` 不处理)与 `.dat`(漏写)、
|
||||
`MatH5` 的“映射视图”、`DataModel` 的“点线/被移除文件”、`SignalPanelPaint` 的“行高会连续缩小”
|
||||
与“文件内的列名”、`TextEdit.hpp` 的 `PaintUtil::UiDrawEditField`(已迁到 `UiControls`)、
|
||||
`Mf4Loader` 的 `syncMaster`(`>= 1` → `1..3`)。
|
||||
|
||||
### E. 二进制体积评估(按要求**只评估、未做压缩修改**)
|
||||
|
||||
| 项 | 数据 |
|
||||
| --- | --- |
|
||||
| release 产物 | **809,472 B(790.5 KiB)**,比上一轮 +1,024 B(新增守卫/`ScalarLE`/`ReleaseGraphicsResources`) |
|
||||
| `.text` | 652,336 B(80%)— 其中各 `.o` 的 `.text` 合计仅 **587,672 B**,其余是静态 CRT / libstdc++ / 异常与线程支持 |
|
||||
| `.xdata` + `.pdata` | 43,088 + 31,632 = **~75 KB(9%)**(SEH 展开信息;`-fno-asynchronous-unwind-tables` 在本工具链**链接失败**,`-fno-exceptions` 会破坏 `bad_alloc` 捕获 ⇒ 不建议动) |
|
||||
| `.rdata` | 42,752 B(字符串字面量 / 常量表) |
|
||||
| `.rsrc` | 20,656 B(图标已全部转 PNG) |
|
||||
| `.idata` | 11,500 B |
|
||||
| 去掉 `-ld3d11 -ldwmapi -ld3dcompiler`(仓内无任何调用) | **实测 0 字节收益**(静态库只拉取被引用的对象),所以“删链接库”不是压缩手段,只是配置整洁 |
|
||||
| 仓内重型头文件 | 已无 `<iostream>/<sstream>/<filesystem>/<regex>/<locale>`(唯一历史炸弹 `<filesystem>` 已被移除) |
|
||||
|
||||
**结论**:已经没有“明显的浪费”可捡(`-Oz` 已在用;`--gc-sections` 实测变大;LTO 在本工具链 ICE;
|
||||
未使用的链接库零收益)。要再显著变小只能改变**取舍**,都需要用户决策:
|
||||
① 动态链接 UCRT/libstdc++(可省掉大部分 CRT 代码,但失去“单文件绿色运行”);
|
||||
② 上 UPX 之类的可执行压缩(体积约减半,代价是启动解压 + 杀软误报风险);
|
||||
③ 削减功能(例如去掉并行图层线程池、去掉内置 inflate 改用系统 zlib DLL)。
|
||||
|
||||
### F. 验证
|
||||
|
||||
- 离屏探针:`editcheck` 20/20、`round3check` 31/31、`round4check` 34/34、`round5check` 5/5、
|
||||
`convcheck` 18/18;`check` **136/137** —— 唯一失败项 `the plot is not corrupted by a panel-animated frame`
|
||||
经 `git stash` 回到**本轮改动前**复现同样数值(`drift=15818`),确认是**该探针自身的既有不稳定项**,
|
||||
与本轮改动无关(此前同一探针曾全绿,取决于前置用例留下的缓存/时序)。
|
||||
- 真实数据回归:4 个 MF4 → 283 / 8 / 18 / 24 个信号;`.mat`:样例 4 组 8 信号、
|
||||
`带无障碍对照-防夹力曲线数据 Group1 x2.mat` 4 组 8 信号、**`BIG_MAT.mat` 5 信号(私有内存 +741MB)**。
|
||||
- `make release` / `make debug` **零警告**。
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user