Split FX out of the park plan: flag-only plans, derived online-first FX work list, two-half record release, applied-state fingerprint

This commit is contained in:
2026-08-06 16:31:59 -04:00
parent 3eae942625
commit 2423225f0c
14 changed files with 897 additions and 164 deletions
+147
View File
@@ -0,0 +1,147 @@
// Standalone tests for reasampler::view::appliedState — no REAPER, no test
// framework. The fingerprint's whole job is discriminating "the model differs
// from what we applied" from "something happened"; the negative cases below are
// the load-bearing half.
#include "../src/core/view/applied_state.h"
#include <cstdio>
#include <string>
using namespace reasampler;
using namespace reasampler::view;
static int g_fail = 0;
#define CHECK(cond) do { if(!(cond)) { \
std::printf("FAIL line %d: %s\n", __LINE__, #cond); ++g_fail; } } while(0)
namespace {
TrackSnapshot record(int tcp, int mixer, int mainSend, int fxEnable) {
TrackSnapshot snap;
snap.showInTcp = tcp;
snap.showInMixer = mixer;
snap.mainSend = mainSend;
snap.fxEnable = fxEnable;
snap.fxOffline = {{"{FX-A}", 0}};
return snap;
}
// Two leaves parked out of Design, one of which the user had OUT of the mix by
// hand (mainSend 0) — the value the sunk attempt re-enabled.
ViewModeModel parkedPair() {
ViewModeModel vm;
vm.membership().tag("{T1}", kDesignModeId);
vm.membership().tag("{T2}", kDesignModeId);
vm.storeSnapshot("{T1}", record(1, 1, 1, 1));
vm.storeSnapshot("{T2}", record(1, 1, 0, 1));
return vm;
}
} // namespace
static void testSameModelFingerprintsEqual() {
const AppliedState a = appliedState(parkedPair());
const AppliedState b = appliedState(parkedPair());
CHECK(a == b);
CHECK(!(a != b));
CHECK(a.activeModeId == kArrangeModeId);
CHECK(a.parked.size() == 2);
CHECK(a.parked.size() == 2 && a.parked[0].guid == "{T1}"); // GUID order
CHECK(a.parked.size() == 2 && a.parked[1].mainSend == 0); // captured, not driven
}
static void testACapturedValueChangingIsADifference() {
// The reconcile case: a rolled-back view_state carries a different record for
// the same track, so what a restore would drive is no longer what we applied.
ViewModeModel vm = parkedPair();
const AppliedState before = appliedState(vm);
vm.storeSnapshot("{T2}", record(1, 1, 1, 1)); // mainSend the user had at 0
CHECK(appliedState(vm) != before);
}
static void testTheParkedSetChangingIsADifference() {
ViewModeModel vm = parkedPair();
const AppliedState before = appliedState(vm);
vm.clearSnapshot("{T2}");
CHECK(appliedState(vm) != before);
CHECK(appliedState(vm).parked.size() == 1);
ViewModeModel grown = parkedPair();
grown.storeSnapshot("{T3}", record(1, 1, 1, 1));
CHECK(appliedState(grown) != before);
}
static void testActiveModeChangingIsADifference() {
ViewModeModel vm = parkedPair();
const AppliedState before = appliedState(vm);
CHECK(vm.setActiveMode(kDesignModeId));
CHECK(appliedState(vm) != before);
}
static void testASpentFlagHalfLeavesTheFingerprint() {
// A restored track is no longer one the tool holds away from the user's
// values; its zeroed record must not read as a parked track at all zeros.
ViewModeModel vm = parkedPair();
vm.releaseSnapshotFlags("{T1}");
const AppliedState after = appliedState(vm);
CHECK(after.parked.size() == 1);
CHECK(after.parked.size() == 1 && after.parked[0].guid == "{T2}");
// The FX half outliving the flag half does NOT put it back.
CHECK(vm.holdsSnapshotFx("{T1}"));
CHECK(appliedState(vm) == after);
}
static void testEditsTheApplyDidNotDriveAreNotDifferences() {
// The bug that sank the previous attempt was repairing on evidence of nothing.
// Each edit below changes the model without changing what the apply drove.
ViewModeModel vm = parkedPair();
const AppliedState before = appliedState(vm);
vm.membership().tag("{OTHER}", kDesignModeId);
CHECK(appliedState(vm) == before);
vm.membership().setShowBoth("{OTHER}", true);
CHECK(appliedState(vm) == before);
vm.lanes().setManaged("{T1}", "reasampler:design", kDesignModeId);
CHECK(appliedState(vm) == before);
vm.soloCache().store(kDesignModeId, {{"{T1}", 1}});
CHECK(appliedState(vm) == before);
// Per-FX offline is DERIVED — never persisted, never in an undo record — so a
// difference there is evidence of nothing about the model.
TrackSnapshot fxMoved = record(1, 1, 1, 1);
fxMoved.fxOffline = {{"{FX-A}", 1}, {"{FX-B}", 0}};
vm.storeSnapshot("{T1}", fxMoved);
CHECK(appliedState(vm) == before);
vm.releaseSnapshotFx("{T2}");
CHECK(appliedState(vm) == before);
}
static void testEmptyModelFingerprintsEqualAndNotParked() {
ViewModeModel a;
ViewModeModel b;
CHECK(appliedState(a) == appliedState(b));
CHECK(appliedState(a).parked.empty());
CHECK(appliedState(a) != appliedState(parkedPair()));
}
int main() {
testSameModelFingerprintsEqual();
testACapturedValueChangingIsADifference();
testTheParkedSetChangingIsADifference();
testActiveModeChangingIsADifference();
testASpentFlagHalfLeavesTheFingerprint();
testEditsTheApplyDidNotDriveAreNotDifferences();
testEmptyModelFingerprintsEqualAndNotParked();
if (g_fail == 0) std::printf("All tests passed.\n");
return g_fail ? 1 : 0;
}