83 lines
2.7 KiB
C++
83 lines
2.7 KiB
C++
#pragma once
|
|
// Step 522: Cross-Panel Consistency Sweep
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <algorithm>
|
|
|
|
struct PanelVisualContract {
|
|
std::string panelId;
|
|
float spacing = 0.0f;
|
|
float elevation = 0.0f;
|
|
float border = 0.0f;
|
|
std::string stateModelVersion;
|
|
std::string tokenVersion;
|
|
};
|
|
|
|
struct ConsistencyReport {
|
|
bool pass = true;
|
|
std::vector<std::string> drifts;
|
|
int checkedPanels = 0;
|
|
};
|
|
|
|
class CrossPanelConsistencySweep {
|
|
public:
|
|
static ConsistencyReport run(const std::vector<PanelVisualContract>& panels,
|
|
const PanelVisualContract& baseline,
|
|
float spacingTolerance = 1.0f,
|
|
float elevationTolerance = 1.0f,
|
|
float borderTolerance = 0.5f) {
|
|
ConsistencyReport r;
|
|
r.checkedPanels = (int)panels.size();
|
|
for (const auto& p : panels) {
|
|
if (std::abs(p.spacing - baseline.spacing) > spacingTolerance) {
|
|
recordDrift(r, "spacing:" + p.panelId);
|
|
}
|
|
if (std::abs(p.elevation - baseline.elevation) > elevationTolerance) {
|
|
recordDrift(r, "elevation:" + p.panelId);
|
|
}
|
|
if (std::abs(p.border - baseline.border) > borderTolerance) {
|
|
recordDrift(r, "border:" + p.panelId);
|
|
}
|
|
if (p.stateModelVersion != baseline.stateModelVersion) {
|
|
recordDrift(r, "state-model:" + p.panelId);
|
|
}
|
|
if (p.tokenVersion != baseline.tokenVersion) {
|
|
recordDrift(r, "token-version:" + p.panelId);
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
static std::vector<PanelVisualContract> normalize(
|
|
const std::vector<PanelVisualContract>& panels,
|
|
const PanelVisualContract& baseline) {
|
|
std::vector<PanelVisualContract> out = panels;
|
|
for (auto& p : out) {
|
|
p.spacing = baseline.spacing;
|
|
p.elevation = baseline.elevation;
|
|
p.border = baseline.border;
|
|
p.stateModelVersion = baseline.stateModelVersion;
|
|
p.tokenVersion = baseline.tokenVersion;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
static std::map<std::string, int> driftHistogram(const ConsistencyReport& r) {
|
|
std::map<std::string, int> h;
|
|
for (const auto& d : r.drifts) {
|
|
auto pos = d.find(':');
|
|
std::string key = pos == std::string::npos ? d : d.substr(0, pos);
|
|
h[key] += 1;
|
|
}
|
|
return h;
|
|
}
|
|
|
|
private:
|
|
static void recordDrift(ConsistencyReport& r, const std::string& drift) {
|
|
r.pass = false;
|
|
r.drifts.push_back(drift);
|
|
}
|
|
};
|