review(panels+size): 面板结构收敛收尾、审查清理、新增平行数组护栏
一、审查清理 * `PlotView::FreeMarkerValue` 的 `const Lane&` 形参从未使用(函数体里只有一句 `(void)lane;`)⇒ 删除形参与该语句,更新 2 个调用点。 * `EdgePanelLayoutFor` 里「选区截取是否就绪(双光标)」算了 3 遍 ⇒ 收敛为函数顶部 一次 `clipReady`。它同时决定面板高度 footer、条目行可见性、按钮几何, 三处各算一遍时只要有一处条件写错,就是"底部多一段空白"或"没双光标却能滚动"。 二、新增护栏(离屏检查) * `panels`:新增「平行数组长度一致」不变式 —— `EdgePanelLayout` 的 13 个按行平行 vector 必须与行数一致;4 个「重采样」专属数组允许为空、非空则必须对齐。 这是"某列读到别人矩形"这类错位缺陷的唯一低成本护栏(O(1))。 * `panelscroll`:同样加一份(大文件、566 行时才会暴露的问题)。 * `panels` 输出增加 rows 数,便于定位。 三、文档 * `Documents/Code_Review_Plan.md` 新增 §七(第 35 轮节点与硬约束)。 * `Documents/Code_Review_Progress.md` 新增第 35 轮(面板架构评估 + 三次重构记录)。 * `Documents/Code_Review_Report.md` 新增 §12(评估结论 + gdtoa 最终结论 + 护栏价值)。 * `Documents/agent_mem.md` 新增第 35 轮六条规则。 * `Tools/README.md`:补 `panelscroll`、`integer_replacement_matches_std`, 断言数更新为 260 / 108,最小集表补充面板相关条目。 验证: * `make release`(删 .o 全量)零 error / 零 warning,产物 **786,944 B**。 * `make -C Tools` 零 error / 零 warning。 * `UnitTests` → checks=260 failed=0 cases=19。 * `OffscreenChecks -all` → 6/6 检查 PASS,checks=108 failed=0。 * `panels -mode compare` → 7 个面板像素哈希与几何逐项不变。
This commit is contained in:
1 parent
34365b3c1c
commit
b58b427f62
8 files changed
+408
-15
No files matched your search
@@ -417,6 +417,69 @@ namespace jdi
|
||||
rect.y + rect.height <= plotRect.y + plotRect.height + 1;
|
||||
Expect(inside, std::string("panel inside plot area: ") + PanelKindName(kind));
|
||||
|
||||
// 不变式:`EdgePanelLayout` 的**平行数组长度必须全部等于行数**。
|
||||
// 这 13 个按行平行的 vector 每个分支都要按同一顺序 push 恰好 13 项,
|
||||
// 漏一项就会让某一列读到别的行的矩形("改布局就出错"的典型机制)。
|
||||
// ⚠️ 「重采样」专属的 4 个数组(最大/最小间隔、间隔/频率输入框)在**其它**
|
||||
// 面板里允许为空(没人读),但只要非空就必须同样与行数对齐。
|
||||
// 成本极低(O(1) 比长度),但能挡住整类错位缺陷。
|
||||
const std::size_t rowCount = layout.rowRefs.size();
|
||||
const std::size_t coreSizes[] = {
|
||||
layout.rowRefs.size(), layout.rowHeaders.size(),
|
||||
layout.rowNameRects.size(), layout.rowTriangles.size(),
|
||||
layout.rowChecks.size(), layout.rowPoints.size(),
|
||||
layout.rowIterations.size(), layout.rowStats.size(),
|
||||
layout.rowLevelTracks.size(), layout.rowLevelValues.size(),
|
||||
layout.rowLevelResets.size(), layout.rowIterTracks.size(),
|
||||
layout.rowIterValues.size(), layout.rowIterResets.size()};
|
||||
bool parallel = true;
|
||||
for (const std::size_t size : coreSizes)
|
||||
{
|
||||
if (size != rowCount)
|
||||
{
|
||||
parallel = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const std::size_t resampleSizes[] = {
|
||||
layout.rowInfoMaxInterval.size(), layout.rowInfoMinInterval.size(),
|
||||
layout.rowIntervalField.size(), layout.rowFrequencyField.size()};
|
||||
bool resampleParallel = true;
|
||||
for (const std::size_t size : resampleSizes)
|
||||
{
|
||||
if (size != 0 && size != rowCount)
|
||||
{
|
||||
resampleParallel = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!parallel || !resampleParallel)
|
||||
{
|
||||
EmitLine("[panels] %s row arrays: refs=%d hdr=%d name=%d tri=%d chk=%d pts=%d it=%d "
|
||||
"stat=%d lvl=%d/%d/%d iter=%d/%d/%d info=%d/%d fld=%d/%d\n",
|
||||
PanelKindName(kind), static_cast<int>(layout.rowRefs.size()),
|
||||
static_cast<int>(layout.rowHeaders.size()),
|
||||
static_cast<int>(layout.rowNameRects.size()),
|
||||
static_cast<int>(layout.rowTriangles.size()),
|
||||
static_cast<int>(layout.rowChecks.size()),
|
||||
static_cast<int>(layout.rowPoints.size()),
|
||||
static_cast<int>(layout.rowIterations.size()),
|
||||
static_cast<int>(layout.rowStats.size()),
|
||||
static_cast<int>(layout.rowLevelTracks.size()),
|
||||
static_cast<int>(layout.rowLevelValues.size()),
|
||||
static_cast<int>(layout.rowLevelResets.size()),
|
||||
static_cast<int>(layout.rowIterTracks.size()),
|
||||
static_cast<int>(layout.rowIterValues.size()),
|
||||
static_cast<int>(layout.rowIterResets.size()),
|
||||
static_cast<int>(layout.rowInfoMaxInterval.size()),
|
||||
static_cast<int>(layout.rowInfoMinInterval.size()),
|
||||
static_cast<int>(layout.rowIntervalField.size()),
|
||||
static_cast<int>(layout.rowFrequencyField.size()));
|
||||
}
|
||||
Expect(parallel, std::string("row arrays have identical lengths: ") + PanelKindName(kind));
|
||||
Expect(resampleParallel,
|
||||
std::string("resample row arrays empty-or-aligned: ") + PanelKindName(kind));
|
||||
|
||||
char buffer[160] = {};
|
||||
std::snprintf(buffer, sizeof(buffer), "%s=%016llX,%d,%d,%d,%d\n", PanelKindName(kind),
|
||||
static_cast<unsigned long long>(HashRegion(session.LastFrame(), rect)), rect.x,
|
||||
@@ -537,9 +600,36 @@ namespace jdi
|
||||
const PlotView::EdgePanelLayout initial = plot.EdgePanelLayoutFor(0, kind);
|
||||
const float maxScroll =
|
||||
std::max(0.0f, initial.markerContentHeight - initial.content.Height);
|
||||
EmitLine("[panelscroll] %-8s content=%.1f view=%.1f maxScroll=%.1f scrollable=%d\n", name,
|
||||
initial.markerContentHeight, initial.content.Height, maxScroll,
|
||||
initial.scrollTrack.Width > 0.0f ? 1 : 0);
|
||||
EmitLine("[panelscroll] %-8s content=%.1f view=%.1f maxScroll=%.1f scrollable=%d rows=%d\n",
|
||||
name, initial.markerContentHeight, initial.content.Height, maxScroll,
|
||||
initial.scrollTrack.Width > 0.0f ? 1 : 0,
|
||||
static_cast<int>(initial.rowRefs.size()));
|
||||
|
||||
// 多信号场景下额外守住"平行数组长度一致"(本轮新增,成本 O(1))。
|
||||
{
|
||||
const std::size_t rows = initial.rowRefs.size();
|
||||
const std::size_t sizes[] = {initial.rowHeaders.size(), initial.rowNameRects.size(),
|
||||
initial.rowTriangles.size(), initial.rowChecks.size(),
|
||||
initial.rowPoints.size(), initial.rowIterations.size(),
|
||||
initial.rowStats.size(), initial.rowLevelTracks.size(),
|
||||
initial.rowLevelValues.size(), initial.rowLevelResets.size(),
|
||||
initial.rowIterTracks.size(), initial.rowIterValues.size(),
|
||||
initial.rowIterResets.size(), initial.rowInfoMaxInterval.size(),
|
||||
initial.rowInfoMinInterval.size(),
|
||||
initial.rowIntervalField.size(),
|
||||
initial.rowFrequencyField.size()};
|
||||
bool aligned = true;
|
||||
for (const std::size_t size : sizes)
|
||||
{
|
||||
// 「重采样」专属数组在其它面板允许为空(见 `panels` 检查的说明)。
|
||||
if (size != rows && size != 0)
|
||||
{
|
||||
aligned = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Expect(aligned, std::string("row arrays aligned with rows: ") + name);
|
||||
}
|
||||
|
||||
if (maxScroll <= 1.0f)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user