边沿统计改为「定向失效」:改一个信号的参数不再重算其它信号的统计
一、问题
加载 VERY_BIG_DATA.CSV 并把所有信号显示在同一个网格,同时启用「边沿计数」与
「中心轴边沿计数」(两个面板都作用于网格内全部信号)。此时改变**一个**信号的
中心轴边沿计数参数,两个浮动面板里的**所有**统计值都从头重新计算。
二、根因
参数提交路径(PlotView::EndEdit)与勾选切换路径里用的是 m_edgeScans.clear():
它把两个面板、所有信号的累积统计状态全部丢掉。于是:
- 其它信号(参数没变、键没变、块和依然有效)被迫从头重扫;
- 连普通「边沿计数」(centre == false)的状态也被一起丢掉 → 另一个面板也全部重算。
三、修法
1. 新增 PlotView::InvalidateEdgeScansFor(const SignalData* signal, bool centreOnly):
按键(文件/信号/种类/样式指纹/参数/区间)只擦除**该信号**的累积状态;
centreOnly = true 时只擦除它的「中心轴」状态。
2. EndEdit 的参数提交分支:
- 中心轴参数(EDGE_CENTER_POINTS / EDGE_CENTER_ITERATIONS)变化 →
InvalidateEdgeScansFor(该信号, true);该信号的普通边沿计数、以及其它信号完全不受影响;
- 均值滤波参数变化 → 与统计无关(中心轴用**自己的**条目列表与自己的曲线键)→ 不作废任何统计。
3. 勾选/取消勾选信号:该信号的统计(与参数相关)依然有效,只是"是否显示"变化 →
删除原来的三个 clear()(m_meanCurveCache/m_edgeScans/m_weakPeakCurveCache),
不再作废任何缓存(改为依赖 m_sceneDerived 快照做局部重画)。
四、验证(全部离屏,不占用鼠标/键盘/屏幕;harness 与探针均降到 BELOW_NORMAL 优先级)
- .preflight/uitest 新增 [AT]:3 个信号合并到同一网格,中心轴统计全部扫完后,通过**真实编辑路径**
(plot.BeginEdit(EDGE_CENTER_POINTS, 0, L"7") + plot.EndEdit(true))修改第 2 个信号的参数,
断言:
* 被改信号的中心轴状态已作废,且其条目参数确实变成 7;
* 另两个信号的 scannedPair / rising **逐位不变**(累计块和没有被丢弃);
* 被改信号的**普通**边沿计数状态 scannedPair / rising **逐位不变**(另一个面板完全未失效);
* 未被改动的信号下一次查询仍然 complete(瞬时返回,不需要重扫)。
- 合计 774/774 通过(连跑 3 次稳定);make release 零警告。
规则同步:Documents/agent_mem.md 新增 §9.24,§11.2 新增第 39 条硬约束(参数变化必须定向失效、
禁止对累积缓存整体 clear()),变更日志补一行。
This commit is contained in:
1 parent
375a15c8c2
commit
48bc534bc1
3 files changed
+78
-7
No files matched your search
@@ -2964,6 +2964,29 @@ namespace jdi
|
||||
}
|
||||
}
|
||||
|
||||
void PlotView::InvalidateEdgeScansFor(const SignalData* signal, bool centreOnly)
|
||||
{
|
||||
// ⚠️ **定向作废**:只有被改动的那个信号(并且只限需要的那一类)要重算,
|
||||
// 其它信号的键没有变化、累计的块和依然有效 → 必须原样保留。
|
||||
// 否则(过去用 `m_edgeScans.clear()`)会连**普通边沿计数**与**其它信号的中心轴统计**
|
||||
// 一起丢掉,于是两个浮动面板里的每一个数字都要从头重新扫描:
|
||||
// 用户报告“改变一个信号的中心轴参数,其它未改变参数的统计也重新计算了”。
|
||||
if (signal == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_edgeScans.erase(std::remove_if(m_edgeScans.begin(), m_edgeScans.end(),
|
||||
[signal, centreOnly](const EdgeScanState& state)
|
||||
{
|
||||
if (state.signal != signal)
|
||||
{
|
||||
return false; // 别的信号:原样保留
|
||||
}
|
||||
return !centreOnly || state.centre;
|
||||
}),
|
||||
m_edgeScans.end());
|
||||
}
|
||||
|
||||
void PlotView::EdgeScanFor(const DataFile& file, const SignalData& signal, const SignalStyle& style,
|
||||
bool centre, double threshold, int points, int iterations, bool hasRange,
|
||||
double rangeMin, double rangeMax, std::size_t& rising, std::size_t& falling,
|
||||
@@ -4226,9 +4249,14 @@ namespace jdi
|
||||
{
|
||||
item.iterations = value;
|
||||
}
|
||||
// 参数变化会改变曲线:清掉派生缓存即可(局部重画由 `m_sceneDerived` 快照驱动)。
|
||||
// ⚠️ **只作废被改动的那个信号**的统计状态。
|
||||
// 过去的 `m_edgeScans.clear()` 会把两个面板里**所有**信号的统计一起丢掉,
|
||||
// 于是改一个信号的参数会让其余未改参数的统计也从头重扫(用户报告的缺陷)。
|
||||
m_meanCurveCache.clear();
|
||||
m_edgeScans.clear();
|
||||
if (centerTarget)
|
||||
{
|
||||
InvalidateEdgeScansFor(ResolveSignal(m_editMeanRef).data, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5270,11 +5298,9 @@ namespace jdi
|
||||
{
|
||||
ToggleLaneEdgeCenterSignal(index, ref);
|
||||
}
|
||||
m_meanCurveCache.clear();
|
||||
m_edgeScans.clear();
|
||||
m_weakPeakCurveCache.clear();
|
||||
// 勾选变化只影响该网格的内容:交给 `m_sceneDerived` 快照驱动局部重画,
|
||||
// 这里**不**整体作废场景缓存(否则每次勾选都要重绘全部网格)。
|
||||
// 勾选变化只改变该信号“是否显示”,它的统计状态(与参数相关)依然有效,
|
||||
// 其它信号更是完全无关 ⇒ **不要**清任何缓存(清掉就会让所有统计重算)。
|
||||
// 这里**不**整体作废场景缓存(交给 `m_sceneDerived` 快照驱动局部重画)。
|
||||
m_dragMode = PlotDragMode::NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user