334015c1a951c55a85d4f4f42916468550b2e2d0
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
944c074ab3 |
288 信号卡顿根治 + 中心轴面板重做 + 标签页默认状态
一、卡顿真因(实测 29.8ms/帧 → 6.6ms/帧) 1. 中心轴面板高度没有上限:288 个信号时面板高 9996px(绘图区只有 1141px) ⇒ PanelRectInsideLayer 恒为假 ⇒ 面板像素缓存一次都存不进去 ⇒ 每帧全量重画。 2. PanelGlobalKey 混入鼠标驱动状态(m_hoverSignal / m_hoverLane / m_hoverCursor / CursorTime / EdgeRangeMin/Max)⇒ 鼠标一动键就变 ⇒ 所有面板每帧重画; PanelSlotKey 里还会为每个信号调一次 EdgeCenterCountsFor(单帧 288 次查询)。 3. 缓存命中路径的投影(与面板同大的半透明抗锯齿圆角矩形)每帧重画,GDI+ 实测 > 20ms。 修法: * 新增 PlotView::InputIsInteractive()(拖拽中 / 鼠标 140ms 内移动过)。交互期间冻结 全部鼠标驱动项与统计数字、跳过投影、统计预算降到 8 万(静止时 40 万)。 m_meanRowHoverLane/Ref 例外 —— 它直接改面板像素且只在进出某行时变化。 * kEdgeScanPairsPerFrame 由 1,200,000 降为 400,000。 * 中心轴面板重做为可滚动列表 ⇒ 面板高度被绘图区夹住、缓存可用、只画可见行。 二、「中心轴边沿计数」面板重做(与「均值滤波」同风格) 条目栏为信号色叠底的可折叠栏 + 右端复选框;栏下同一行显示「上升沿 / 下降沿」; 再下面两行滑块(均值点数 / 迭代次数,标签不带 X/N),数值可点击输入上限、 右侧复位按钮;整个面板可滚动;未勾选时条目栏不可展开。 新增 Lane::edgeCenterScroll + SetLaneEdgeCenterScroll;交互复用 MEAN_* 拖拽模式 + m_meanDragCenter / m_editMeanCenter 标志分派;光标形状与均值滤波一致。 三、标签页 * 唯一标签页点 ✕ 不再弹警告:直接 erase 后 NewTab(true),名字必然为「视图 1」。 * 新建标签页(含手动新建)默认:组全部折起、无选中信号(清空全局 Selected)、 样式区无目标。 四、验证 .preflight/bugcheck.exe 59/59(A1 空闲 0.7ms、A2 平移 2.5ms、A3 双光标 2.4ms、 A4 自由标记 5.2ms、A5 中心轴拖动 6.6ms;B3 真实 WM_TIMER+WM_PAINT 路径; B5 快速连点与动画反向;C 中心轴面板交互;D 标签页默认状态) panelcheck 71/71、markercheck 13/13、ringcheck 6/6 make release / make debug 零 warning |
||
|
|
2d83b494a3 |
均值面板越界根因 + 网格线进入主题配色 + 条目栏悬停/整行点击 + 均值点数下限 1
1. 「元素超出浮动面板」真根因(用户 2026-10-30 报告的截图)
- 绘制侧 PaintEdgeCursor 的 itemized 仍是 (centerAxis || meanFilter || weakPeak),
而布局侧 EdgePanelLayoutFor 早已是 (centerAxis || weakPeak)。
于是均值滤波面板被旧的「逐条目」分支**再画一遍**(每行名称 + 复选框,且没有任何裁切),
滚动后那些行的坐标是负值/越界 ⇒ 直接画到标题栏上。
- 修法:绘制侧与布局侧统一;旧分支的兜底循环跳过条件补 meanFilter。
底部「构建为新信号」由共享的 if (hasButton) 绘制,不受影响。
- 顺带删除「只画完全落在内容区里的行」的 fullyInside 门控:真因修掉后
g.SetClip(layout.content) 已足够,半截行正常显示,滚动观感连续。
2. 条目栏交互(与「自由标记」分组栏一致)
- 整行可点:复选框区 = 切换是否预览;已启用 = 展开/收起参数行;未启用 = 直接开始预览。
命中只要求点落在 layout.content 内(不再要求整行在内容区内),因此半截行也能操作。
- 悬停行 → 对应预览曲线高亮:新增 m_meanRowHoverLane / m_meanRowHoverRef,
由 OnMouseMove 维护、OnMouseLeave 与 InvalidateDerivedCaches 清除;
PaintDerivedCurve/PaintMeanFilterCurve/PaintWeakPeakCurve 新增 bool highlight,
先画 +5px 半透明同色光晕再把线加粗,行头叠一层 accent;悬停态变化会 InvalidateSceneCache。
3. 均值点数下限 1(用户要求:不可以为 0)
- kMeanFilterPointsMin 0 → 1;输入提交用 centerTarget ? 0 : kMeanFilterPointsMin
(中心轴边沿计数沿用旧语义 0 = 不平滑);预览与构建请求都再夹一次下限,
即使条目被外部写成 0,渲染/构建结果与 1 点逐位一致。
4. 网格线颜色成为主题配色的一部分
- struct Theme 新增 laneBg(网格叠底色);NormalizePlotContrast → FinalizeTheme,
先解 laneBg = EnsureContrast(plotBg, cardBg, 1.03),再让 gridWeak/gridStrong/
axisLine/borderStrong 统一对 laneBg 归一(1.30 / 1.70 / 2.10 / 1.70)。
- 四个主题各自给出显式取值:Dark 的网格线对叠底色原本只有 1.071(几乎不可见)⇒ 现 ≥1.30;
其它三个主题同步微调,网格可见性一致。ThemeLaneBackground 返回 laneBg。
5. 行三角尺寸统一
- 新增 kEdgePanelRowTriangleSize = 12 逻辑像素,均值滤波行与自由标记分组栏共用;
标题栏的 kEdgePanelDisclosureWidth = 20 保持不变。
6. 均值面板滚动条与文本
- 滚动条必须在 g.Restore(meanSave) 之后绘制(它在内容裁剪区之外,裁剪内画会被整条裁掉)。
- 滑块标签/数值改用 UiTextClipped(..., layout.content)(GDI 文本不受 GDI+ 裁剪约束)。
验证(全部离屏)
uicheck 69/69、lbcheck 21/21、lbresid 5/5、lbzorder 4/4、lbcovr 7/7、lbpanel 10/10、
derivecheck 16/16、round15check 28/28、themecheck 17/17、.preflight/meancheck 17/17;
.preflight/meanpix:滚到顶/中/底时标题栏与面板外均为 0 像素差异,内容区正常滚动;
rendercheck:A–H 八个场景哈希与基线完全一致;
make release 零 warning(805,376 B);make debug 零 warning。
同步文档:Documents/agent_mem.md 追加「2026-10-30 第十七轮」,
并把第十六轮里「均值点数(0…上限)」「命中要求行完全落在内容区里」两条改成现行做法。
|
||
|
|
bdd703b88b |
主题自适应配色 + 预览曲线连续配色 + 样式区复位按钮 + 均值滤波面板重做 + 面板缓存环带残留 + 调试层序 + 自由标记选取与性能
① 主题自适应(`Theme.cpp`):新增 `SrgbLuminance` / `ContrastRatio` / `EnsureContrast` /
`MixToLuminance` / `ThemeLaneBackground`;四套主题的结构色(gridWeak 1.30 / gridStrong 1.65 /
axisLine 2.10 / borderStrong 1.70)按底色自动校正,Solarised Light 逐位不变;网格叠底改用
`ThemeLaneBackground()`(4 处),深色主题下网格层与绘图区底色可辨。
② 派生预览曲线(`HighContrastDerived`)重写为**连续**方案:方向沿信号所在侧远离底色,
目标亮度 = max(与底色对比度 3.2, 信号亮度 ± 0.18),再按亮度平滑混色;调用点传入真实网格底色
(旧实现默认写死 Solarised Light 底色 ⇒ 深色主题永远选到更暗的那一侧、几乎看不见)。
③ 信号样式区「线宽 / 透明度」两行右侧新增**复位按钮**(`UiPaintResetIcon` 成为唯一实现,
菜单/弱峰面板/样式区共用同一套笔画);默认线宽统一到 `DefaultSignalLineWidth(finiteCount)`
(单点信号取 10.0)。按钮右边界与内容列对齐,内容列过窄时整列不显示。
④ 「均值滤波」面板重做:信号色叠底标题栏 + 复选框 + 展开三角 + 「均值点数 / 迭代次数」两行滑块
(点击数值可改滑块上限、右侧复位)+ 内容区滚动;新增 `MeanFilterItem::{maxPoints,maxIterations,
collapsed}` 与 `Lane::meanFilterScroll`,缓存键同步补全。
⑤ 浮动面板命中像素缓存时只贴**面板圆角形状之内**的像素(`CreateRoundRectRgn` 裁剪)并按本帧重画投影
⇒ 中键移视界后面板周围不再出现一圈旧波形。
⑥ 显示布局边界:每个浮动面板**独占一个绘制层**(按 `m_panelOrder` 递增),绘制侧
`UiSetTextLayer` 在同一循环内同步推进 ⇒ 下层面板的边框/文字不再画到上层面板上。
⑦ 自由标记:采样候选距离改为**二维欧氏距离**(单点信号不再在整幅宽度内吸住光标),
纵向光标画在鼠标位置、圆点落在真实采样点(新增 `FreeMarkerProbe::pointX`);
`MinorCellSparse` 只对胜出信号算一次;折线缓存容量改为 `max(64, 信号数×2)` 且查找改为
单键哈希 ⇒ MF4 的 285 信号合并网格中 `ProbeFreeMarker` 平均 0.11ms。
验证:`.preflight` 探针重建(`panelcheck` 71/71、`markercheck` 13/13、`ringcheck` 6/6,合计 90 条,
LTO 目标文件上复跑同样全绿);`make release` / `make debug` 零警告;产物 815,104 B。
文档:`agent_mem.md` 第十六轮(含补丁脚本与编码/行尾踩坑)。
|
||
|
|
044b87383b |
体积 L3(-fno-exceptions + MemProbe + LTO)与 L1 几何产物层;产物 909,824 -> 788,992 B
## 为什么
用户 2026-10-29 要求:按既定计划完整实现改进,但
① **不得把编译产物拆成 DLL**(项目定位是单文件轻量工具,最终只能有一个 .exe);
② 异常处理改用**预检验**而不是 try/catch(-fno-exceptions 省体积,且 try/catch 本身开销大);
③ 先删除 Documents 内三份 UI 重构文档再按"计划 / 当前进度 / 最终报告"重建;
④ 顺便审计代码,删除无用/过时注释,修复名实不符;
⑤ 提交到本地仓库,期间不要占用用户的鼠标/键盘/屏幕。
## 改了什么
### 1. 体积(909,824 B -> 788,992 B,-120,832 B,-13.3%)
Makefile 新增三个可覆盖开关(默认全为 1):
- `LAYOUT_BOUNDS` 编入/剔除「显示布局边界」叠加层
- `NO_EXCEPTIONS` 追加 `-fno-exceptions`
- `LTO` 追加 `-flto`(编译 + 链接)
派生:`FUNC_SECTIONS`(LTO 下为空)、`GC_SECTIONS`(`-Wl,--gc-sections`)、
`ASM_LISTING`/`ASM_LISTING_C`(LTO 下为空,因为 lto-wrapper 会丢弃 `-Wa` 清单)。
两个实测复现的坑(已写进 Makefile 注释):
- **切换 LTO 必须 `make clean`**:LTO 与非 LTO 目标文件混链会让 GCC 15.2.0 在
`binds_to_current_def_p (symtab.cc:2598)` 处 ICE。
- **`-flto` 与 `-ffunction-sections -fdata-sections` 同时打开也 ICE**(干净重编也必崩,
报错落点是 `DataModel.hpp:393`,但那是 COMDAT 解析落点、不是原因)⇒
LTO 下 `FUNC_SECTIONS` 置空,并加 `-flto-partition=one`:默认 11 个分区的 LTRANS
稳定复现,单分区从未复现。**这是稳定性选项,不是性能选项。**
### 2. 关异常必须成对交付:预检验 + 兜底
新增 `Utilities/Inc/MemProbe.hpp` + `Utilities/Src/MemProbe.cpp`:
- `MemAvailablePhysical()`:`GlobalMemoryStatusEx` + 200ms 缓存
- `MemCanAllocate(bytes)`:预留后仍须保有 1/8 可用内存
- `MemReserveIfRoom(container, n)`:含 `capacity()` 早退与乘法溢出保护
- `MemInstallTerminateHandler()`:OOM 时弹一次带建议的模态提示后 `_Exit`(而不是静默消失)
接入:
- `Utilities/Src/DataModel.cpp`:全仓**唯一**的 `try/catch`(`extremes.reserve` 捕
`std::bad_alloc`)改为 `MemReserveIfRoom(extremes, count / 8)`
- `Components/PlotView/Src/PlotView.cpp`:`AvailablePhysicalBytes()` 原有一份**完整重复**
的 `GlobalMemoryStatusEx` + 缓存实现 → 转发 `MemAvailablePhysical()`
- `Components/Application/Src/Application.cpp`:`Initialize()` 开头安装 terminate handler
### 3. L1 几何产物层
新增 `Components/Shared/Inc/UiBox.hpp` + `Src/UiBox.cpp`:
- `struct UiBox { rect, clip, depth, layer }` —— 纯值类型,不继承任何东西
(继承会和 PlotView 4 层位图缓存 / SignalPanel 行位图缓存的失效体系打架)
- `class UiBoxTable : public UiTextRectSink` —— 只累计几何 + 裁剪/层/遮挡,**不含绘制代码**
`UiComponent::CollectDebugBoxes` → **`virtual void BuildBoxes(UiBoxTable&)`**:
组件从"收集布局边界(调试用)"改为"上报几何产物",不再需要知道"调试"这个概念存在。
`UiDebugBounds.hpp/.cpp` 退化为唯一的消费者(配色 + 包角描边 + 遮挡挖洞)。
除宿主 `ApplicationCommands.cpp` 外,所有组件源码现在只包含 `UiBox.hpp`。
### 4. 审计
- `MemProbe` 里"省 40~60KB"的估算 → 改为实测 27,136 B
- `MemProbe.hpp` 的 `<new>`、`MemProbe.cpp` 的 `<cstdio>`:未使用,删除
- `UiDebugPaintBounds(g, rect, depth)`:零调用者,删除(只保留带 clip 的版本)
- `TabBar`/`Toolbar`/`PlotView`/`SignalPanel` 的 `BuildBoxes` 文档"(调试用)"→"几何 box"
- `PlotView::SetForceFullRepaint` 补写"为什么保留而不优化"
### 5. 文档
`Documents/UI_Refactor_Plan.md` / `_Progress.md` / `_Report.md` 先 `git rm` 再按
「计划 / 当前进度 / 最终报告」重建;`Documents/agent_mem.md` 追加第十三轮记录。
## 怎么验证
```
make clean
make release TARGET_FILE_NAME=JustDataInspector -j16 # 零 error / 零 warning,788,992 B
make debug TARGET_FILE_NAME=JustDataInspectorD -j16 # 零 warning
uicheck 69/69 lbcheck 21/21 lbresid 5/5 lbzorder 4/4 lbcovr 7/7 lbpanel 10/10
rendercheck: 8 个场景哈希与改造前逐一相同 + FUNC 7/7 PASS, exit=0
A FAED59DF284153DB B E6443BFE4E3955F8 C 96A0AA8C402F1729 D E3D5DBD998E43720
E DA0583CB13C26A6F F FFB822159F604D1D G 19F8DE8FE3A8DF18 H DBBDDE4CB2C97C92
```
体积溯源(`objdump -h`,基线 → 最终):
`.text` 735,600 → 657,168;`.rdata` 49,184 → 35,016;
`.xdata` 48,132 → 27,512;`.pdata` 35,424 → 28,524;`.rsrc` 20,656 不变。
## 没做什么(有意为之)
- **没有拆 DLL**(用户明确要求单文件)
- **没有改优化等级**(`-Oz` 保持)
- **L2(`UiDamage` 脏矩形 + 独立叠加层)评估后缓做**:受益方只有"调试开关打开时的帧率",
而正确实现必须把叠加层旧矩形注入底层组件重绘范围,穿透 PlotView 四条快路径 + 两层缓存;
在用户反复报过"拖拽错位 / 贴图残留"的背景下,风险与收益不成比例。理由写在
`Documents/UI_Refactor_Plan.md` §5 与 `PlotView::SetForceFullRepaint` 的文档里。
|
||
|
|
affb9cc340 |
目录规范化(Inc/Src)+「自由标记」第六轮交互调整
1) 目录规范化:所有 .hpp 只放 Inc,Src 只放 .cpp
- 4 个 *Internal.hpp 从 Src 迁到 Inc(DataModel/Application/PlotView/SignalPanel)
- Makefile 固化该约定(注释必须单独成行:写在同一行会把 CXX_INCLUDES_PATHS 整条注释掉)
- include 全是扁平形式,搬家无需改任何 include
2) 常规模式 = 普通鼠标(未开启「自由标记点选取」)
- ProbeFreeMarker 早退:不预览、不画纵向光标、单击不固定
- 补 if (!hitCurve) continue:否则整列光标下 probe.ref 恒有效,任意位置都能固定
- 固定点仍恒吸附到真实采样时刻;「已吸附」圆环只在稀疏判据成立时画
3) 两个显示开关:按钮改名「自由标记点选取」,其下新增「显示增量 | 显示枚举文本」
- 默认关闭,只影响已固定点的胶囊文本;预览胶囊恒为「值 = 枚举」
- 开关行计入面板高度与内容区高度
4) 面板六列:新增恒存在的「序号」列(组内 1 起)
- 枚举列存在时,无枚举/对不上任何枚举项显示 N/A
- 列与列之间画竖线;悬停某行时其它固定点封顶 50% 不透明度,移出恢复
- 删除固定点 ✕ 的悬停浮动提示(PaintFreeMarkerTooltip 实现与声明全部移除)
- 开启选取模式的网格上,信号悬停提示只显示信号名
5) 缓存键补齐
- FreeMarkerContents 混入枚举表指纹(旧键会让加上枚举表后仍显示 N/A)
- PanelSlotKey 混入两个新按钮矩形与开关状态
6) 注释/文档
- 修正 FreeMarkerProbe、SetLaneFreeMarkerCursor、标记透明度等处的过期说明
- 空态提示按是否开启选取模式区分文案
验证(全离屏,未占用鼠标/键盘/屏幕)
- 新增 .preflight/mark5check 52/52
- 回归:markcheck 67/67、mark4check 40/40、fixcheck 37/37、round3check 31/31、
round4check 34/34、round5check 5/5、editcheck 20/20、convcheck 18/18、diag 19/19
- check 136/137(唯一失败项为既有不稳定项,drift=15818 与改动前逐位相同)
- make release / make debug 零警告;Release 产物 TargetCheck.exe 857,600 字节
|