From f13944034ae233eba890de122feb90ed9c963869 Mon Sep 17 00:00:00 2001 From: "DeepSeek-V4.1-Flash" <> Date: Wed, 4 Nov 2026 03:07:48 +0800 Subject: [PATCH] =?UTF-8?q?docs(review):=20=E6=B8=85=E7=90=86=E8=BF=87?= =?UTF-8?q?=E6=97=B6=E6=B3=A8=E9=87=8A=E5=B9=B6=E6=A0=A1=E6=AD=A3=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E8=AE=B0=E5=BF=86=E4=B8=AD=E7=9A=84=E6=9E=84=E5=BB=BA?= =?UTF-8?q?/=E7=9B=AE=E5=BD=95=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PlotView.hpp:删除“已迁移到数据层的公式包络缓存”这个指向已删代码的注释块。 - agent_mem.md §2:修正 -Os -> -Oz;补充体积相关开关(NO_EXCEPTIONS / NO_RTTI / LTO / RELEASE_ONLY_OPT)与“改 Makefile 必须删 .o 全量重编”的提醒; 链接库列表补 msimg32;忽略列表补 Temp/、.preflight/、Tools/。 - agent_mem.md §3:目录结构按现状重写(Shared/ 已承载通用控件与 PopupMenu/ ColorPickerPopup;Utilities 现为数据与格式层:DataModel/DataLoader/CsvLoader/ Mf4Loader/MatLoader/MatH5/Deflate/FormulaEval/Utf8Util/MemProbe; 删掉早已不存在的 CsvTable/、DataModel/、PaintUtil/ 等旧条目),并写明依赖方向。 - agent_mem.md 末尾新增第 33 轮(本轮审查)记录。 - Code_Review_Progress.md 追加 P15(注释/文档校正)。 --- Components/PlotView/Inc/PlotView.hpp | 7 -- Documents/Code_Review_Progress.md | 17 ++++ Documents/agent_mem.md | 123 ++++++++++++++++++++++----- 3 files changed, 121 insertions(+), 26 deletions(-) diff --git a/Components/PlotView/Inc/PlotView.hpp b/Components/PlotView/Inc/PlotView.hpp index 4d5a9c2..b731884 100644 --- a/Components/PlotView/Inc/PlotView.hpp +++ b/Components/PlotView/Inc/PlotView.hpp @@ -3620,13 +3620,6 @@ namespace jdi * 只在信号带公式时建立;条目键含公式文本与影响数值的样式字段, * 公式 / 系数 / 镜像等变化时自然失效。用 `deque` 保证追加时已有引用不失效。 */ - /** - * @brief 「公式映射」信号的绘制值缓存(**唯一实现在数据层**)。 - * - * 旧实现是 `mutable std::deque m_formulaEnvelopes;` —— 与 - * `TabConfig::ComputeLaneRange` 各扫一遍整条信号。现已合并进 - * `DataSet::m_formulaTransforms`(见 `DataSet::FormulaTransformFor`)。 - */ /** * @brief 折线顶点缓存的**容量上限**(条目数)。 * diff --git a/Documents/Code_Review_Progress.md b/Documents/Code_Review_Progress.md index db6d1da..e2d7aa6 100644 --- a/Documents/Code_Review_Progress.md +++ b/Documents/Code_Review_Progress.md @@ -101,5 +101,22 @@ map 中 `cp-demangle.o` 已无 `.text` 段分配。 且崩溃会弹模态框),纯逻辑重写无法自证“像素完全一致”。已通过上面的派发收敛 消除最容易出错的一类重复,剩余重复属于“几何算式本身”,风险高于收益。 +### P11 拆分 `ApplicationCommands.cpp` —— ✅ 完成(提交 `8437100`) + +原文件 **2,165 行**,混杂六类职责。按职责**纯搬移**(零逻辑改动): + +| 新文件 | 行数 | 内容 | +| --- | --- | --- | +| `ApplicationTabs.cpp` | 355 | 标签页新建/关闭/切换/重排、视图同步、窗口标题、标签栏回调、标签页右键菜单 | +| `ApplicationDerive.cpp` | 786 | 派生烘焙、重采样、选区截取(新建/就地)、克隆(含带调整) | +| `ApplicationMenus.cpp` | 409 | 绘图区右键菜单、菜单数值回写、主题切换、设置菜单、菜单结果派发 | +| `ApplicationCommands.cpp` | 642 | 分组/信号增删、移动与重排、文件对话框、工具栏动作、键盘鼠标分发、布局边界绘制 | + +Makefile 按目录通配收集源文件,**无需登记新文件**。 + +**验证**:release 零 error 零 warning;产物 793,088 → 794,112 B(+1,024,LTO 内联边界 +变化,< 0.13%)。 + + diff --git a/Documents/agent_mem.md b/Documents/agent_mem.md index 4b4b02f..988f324 100644 --- a/Documents/agent_mem.md +++ b/Documents/agent_mem.md @@ -20,13 +20,20 @@ - 工具链:**MinGW-w64**(`x86_64-win32-seh-rev0`, MinGW-Builds 16.1.0),可直接用 `make`。 - 构建入口:根目录 `Makefile`(C / C++ / windres 混合构建)。 - 常用命令: - - `make release` → `Build/Release/Target.exe`(`-Os`,strip:`-s`)。 - - `make debug` → `Build/Debug/Target.exe`(`-O0 -g`)。 + - `make release` → `Build/Release/Target.exe`(`-Oz` + LTO + `-s`,strip)。 + - `make debug` → `Build/Debug/Target.exe`(`-O0 -g`,**不** strip)。 - `make` → 同时构建 Release 与 Debug。 - `make clean` → 删除 `Build/`。 -- 关键编译设置:`-std=c++17`;`-finput-charset=UTF-8 -fexec-charset=GBK -fwide-exec-charset=UTF-16LE`;`-static`;`-mwindows`(GUI);链接 `gdi32 gdiplus comdlg32 d3d11 dwmapi d3dcompiler`。 -- **新增组件/工具目录后,必须在 `Makefile` 的 `CXX_INCLUDES_PATHS` 与 `CXX_SOURCES_PATHS` 中登记**(源文件按目录通配自动收集)。 -- 构建产物统一在 `Build/`,已由 `.gitignore` 忽略;同时忽略 `*.o/*.d/*.lst/*.map/*.exe` 与 `TestData/`。 +- 关键编译设置:`-std=c++17`;`-finput-charset=UTF-8 -fexec-charset=GBK -fwide-exec-charset=UTF-16LE`; + `-static`;`-mwindows`(GUI);链接 `gdi32 gdiplus msimg32 comdlg32 d3d11 dwmapi d3dcompiler`。 +- 体积相关开关(Makefile 顶部,**改这些必须删 `*.o` 全量重编,Makefile 变更不会自动触发重编**): + - `NO_EXCEPTIONS = 1` → `-fno-exceptions`。 + - `NO_RTTI = 1` → `-fno-rtti`(全仓无 `dynamic_cast`/`typeid`;见 `MemProbe.cpp` 里对 + `__gnu_cxx::__verbose_terminate_handler` 的覆盖,它同时省掉 56 KB 的 `cp-demangle`)。 + - `LTO = 1` → `-flto -flto-partition=one`。 + - `RELEASE_ONLY_OPT` = `-fno-asynchronous-unwind-tables`(**只**加在 Release 规则上)。 +- **新增组件/工具目录后,必须在 `Makefile` 的 `CXX_INCLUDES_PATHS` 与 `CXX_SOURCES_PATHS` 中登记**(源文件按目录通配自动收集;只加 `.cpp` 文件到已登记目录时无需改 Makefile)。 +- 构建产物统一在 `Build/`,已由 `.gitignore` 忽略;同时忽略 `*.o/*.d/*.lst/*.map/*.exe`、`TestData/`、`Temp/`、`.preflight/`、`Tools/`。 --- @@ -34,27 +41,42 @@ ``` Components/ 功能组件块(每块 Inc/ 放 .hpp,Src/ 放 .cpp) - Application/ 应用主框架:窗口、布局、消息分发、标签页、绘制合成 + Application/ 应用主框架:窗口、布局、消息分发、绘制合成 + (分片:Application.cpp / ApplicationTabs.cpp / ApplicationDerive.cpp / + ApplicationMenus.cpp / ApplicationCommands.cpp / ApplicationLoading.cpp) Main/ 程序入口(WinMain → Application::Run) + Shared/ 与业务无关的通用层:UiComponent(顶层组件协议)、UiWidget(控件树)、 + UiLayout / UiBox / UiSurface / UiButtonWidget / UiControls、 + PaintUtil(低层绘制原语)、Theme、TextEdit、PopupMenu、ColorPickerPopup、 + UiDebugBounds(「显示布局边界」唯一消费者) TabBar/ 顶部多标签栏 - Toolbar/ 顶部工具栏(导入文件 / 适应视图 / 时间轴自适应 / Y 轴自适应 / 选区放大 / 光标 / 合并·拆分·清空网格) - SignalPanel/ 左侧信号面板:按文件分组的信号树、可见性勾选、样式编辑 + Toolbar/ 顶部工具栏(设置 / 导入文件 / 适应视图 / Y 轴自适应 / 选区放大 / 光标 / + 合并·拆分·清空网格) + SignalPanel/ 左侧信号面板:按分组信号树、可见性勾选、样式与公式编辑、拖拽排序 PlotView/ 波形绘图区:网格、时间轴、光标、缩放、拖拽、实验性功能面板 -Utilities/ 工具与辅助模块(Inc/ + Src/) - Application/ ... (见上) - CsvTable/ CSV 流式解析(列优先) - DataModel/ 数据层:DataSet / DataFile / SignalData / 显示配置 - PaintUtil/ GDI+ 绘制与文本/控件辅助(含 UiPointInRect、UiMeasureTextWidth 等) - PopupMenu/ 主题化自绘弹出菜单(含二级子菜单、内联编辑) - ColorPickerPopup/ 浮动拾色器 - TextEdit/ 内联文本编辑模型 - Theme/ 主题色板(Solarised Light)与波形默认配色 - Utf8Util/ 编码转换(UTF-8 ↔ UTF-16 等) + (分片:PlotView.cpp / PlotViewPaint.cpp / PlotViewRaster.cpp / + PlotViewPanels.cpp / PlotViewCacheKey.cpp / PlotViewFeatures.cpp / + PlotViewInteraction.cpp) +Utilities/ 与 UI 无关的数据与格式层(Inc/ + Src/) + DataModel.* 数据层:DataSet / SignalGroup / TimeAxis / SignalData / SignalStyle / TabConfig + DataModelTab.* TabConfig(每标签页的视图配置)实现 + DataTable.hpp 加载层中间表(TableBlock) + DataLoader.* 加载入口(按扩展名分发) + CsvLoader.* CSV(多 time 列 = 多时间轴) + Mf4Loader.* ASAM MDF v4(.mf4/.mdf) + MatLoader.* MATLAB .mat(v5 / v7.3 HDF5) + MatH5.* HDF5 只读子集 + Deflate.* HDF5 分块解压(内置 inflate,不依赖 zlib) + FormulaEval.* 「公式映射」表达式编译与求值 + Utf8Util.* 编码转换 + 数值/时长/频率格式化 + MemProbe.* 内存预检验与 terminate 兜底 Resources/ 图标、清单(.manifest)、版本信息(.rc)、ResourceIds.h TestData/ 本地测试 CSV(**不纳入版本控制**) -Documents/ 项目文档(含本文件) +Documents/ 项目文档(含本文件、Code_Review_* 系列) ``` +- **依赖方向固定**:`Components/*` → `Components/Shared` → `Utilities`(不得反向)。 + `PopupMenu` / `ColorPickerPopup` 历史上放在 `Utilities`,现已在 `Components/Shared`。 - **命名硬性约束**:源文件/头文件**不得含空格**,只能字母与下划线组合。 - **头文件后缀**:C 用 `.h`,C++ 用 `.hpp`;C 源 `.c`,C++ 源 `.cpp`。 - **防重复包含**:每个头文件必须 `#ifndef __XXX_XX_HPP__ / #define __XXX_XX_HPP__ / ... / #endif`;宏名 = 文件名的双边双下划线 + 全大写。 @@ -10283,3 +10305,66 @@ release/debug **零警告**;Release `TargetCheck.exe` **890,880 B**(< 1 MB * 首次 379ms 仍是同步阻塞。若要彻底无感需把公式缓存改成后台线程计算 + 未就绪时回退到保序端点映射;当前收益不足以承担该复杂度。 +--- + +## 2026-11-04 · 第 33 轮(`Code_Review` 分支):全项目结构/性能/体积审查 + +> 完整节点计划见 `Documents/Code_Review_Plan.md`,逐节点记录见 +> `Documents/Code_Review_Progress.md`,结论见 `Documents/Code_Review_Report.md`。 +> 本轮同时删除了过时的 `Documents/UI_Refactor_{Plan,Progress,Report}.md`。 + +### 1. 体积:890,880 B → **794,112 B**(−96,768,−10.9%) + +* **`dynamic_cast` 是体积炸弹**:`Toolbar::BuildBoxes` 里唯一的 + `dynamic_cast` 是**多余强转**(`Button::widget` 本来就是该类型)。 + 最小复现程序实测 39,936 → 115,200 B(+75,264)。 +* **光关 RTTI 不够**:`cp-demangle.o` 仍在链接里 —— 真凶是 libstdc++ 的 `vterminate.o` + (被 `eh_terminate.o` 的 `std::terminate` 拉入,它引用 `__cxa_demangle`)。 + 在 `MemProbe.cpp` 里**自行定义** `__gnu_cxx::__verbose_terminate_handler()` + ⇒ `vterminate.o` 不再被拉入 ⇒ 整个 demangler 消失(`.text` −49,520、`.rdata` −10,320)。 + ⚠️ 该定义**必须**在全局 `__gnu_cxx` 命名空间,不能嵌在 `jdi` 里。 +* **Release 关闭异步展开表**(`RELEASE_ONLY_OPT = -fno-asynchronous-unwind-tables`): + `-fno-exceptions` 下 `.pdata` 30,420 → 12,684、`.xdata` 28,904 → 10,156(**−36,352**)。 + 代价:Release 崩溃时 WER 拿不到可靠调用栈(不打印栈回溯的程序功能不受影响)。 + +### 2. ⚠️ 修掉一个真实构建缺陷:`DEBUG_OPT` 从未生效 + +`DEBUG_OPT = -O0` 定义了却**没有任何规则使用它** —— Debug 的两条编译规则误用 +`$(RELEASE_OPT)`(`-Oz`),且全程没有 `-g`。所谓 "Debug 构建" 其实只是 +"不 strip 的 Release",**根本无法调试**。现已改用 `$(DEBUG_OPT) -g`(链接也加 `-g`)。 +⚠️ 因此 Debug 产物从 1.73 MB 变成 6.0 MB,属预期(真实 `-O0 -g`)。 + +### 3. 架构:面板"按种类分派"收敛为唯一派发点 + +`Lane` 里 7 种实验性功能各有 1 份 `LanePanelState` + 1 个滚动偏移。旧实现在 +**每一处**按种类取用的地方各写一遍嵌套三元式/`switch`(`EdgePanelLayoutFor` 里就有 +5 条 7 层嵌套三元式),新增一种面板要改 20+ 处,漏一处就是「拖不动 / 关不掉 / +滚轮滚不到底」——`MARK`、`RESAMPLE`、`CLIP` 三种都真实踩过。 + +现在唯一派发点是 `PlotViewInternal.hpp` 的 +`LanePanelEnabled` / `LanePanelStateOf` / `LanePanelScrollOf`。 +⚠️ **这些 `switch` 一律不写 `default:`**,让 `-Wswitch`(属 `-Wall`)在新增 +`EdgePanelKind` 而漏登记时直接**编译报错**(已用最小程序验证 `-Wswitch` 确实会报)。 +⇒ **今后新增实验性功能面板,忘记登记会编译失败,而不是运行时静默出 BUG。** + +### 4. 架构:`ApplicationCommands.cpp`(2,165 行)拆成 4 个分片 + +`ApplicationTabs.cpp`(355)/ `ApplicationDerive.cpp`(786)/ `ApplicationMenus.cpp`(409)/ +`ApplicationCommands.cpp`(642)。纯搬移、零逻辑改动;Makefile 按目录通配,无需登记。 + +### 5. 审查结论中的"没有发现问题"项(同样重要) + +* **无死代码**:`-Wall` 零警告(未使用的 `static` 函数会报警);对 + `PlotView` / `SignalPanel` / `Application` / `TabBar` / `Toolbar` / `DataSet` + 的 233+ 个 `m_*` 成员做全仓引用统计,**没有"只声明不使用"的字段**。 +* **无 TODO/FIXME/未完成的临时方案**(源码里的"未完成"全是边沿统计进行中的业务语义)。 +* **`UiMeasureTextWidth` 有记忆化**(键 = 字体 + 文本),因此布局层的重复测量不是热点。 + +### 6. 未做(诚实记录) + +* `EdgePanelLayoutFor`(957 行分支)未改成"每面板一行元数据表": + 没有离屏像素对比工具(`.preflight` 已删,崩溃会弹模态框),无法自证像素一致。 +* `EdgeScanFor` 的累积状态查找是**线性扫描** `m_edgeScans`(上限 2×信号数+余量)。 + 288 信号时每帧约 16 万次比较(~0.3ms 量级)。可改哈希索引,但收益有限、风险不小。 +* `SceneContentHash` 里 6 段逐面板混入循环未合并(同上:无法验证"仅失效条件不变")。 +