Split unidentified from missing FX in Design View drop report, fix message + console pop
Distinguish no-GUID-at-capture from identity-no-longer-live; rewrite the drop message to state the real recovery step; mark FX-GUID stability [verify — DAW]; guard mismatched fx/fxOffline lengths; the report never force-opens now.
This commit is contained in:
@@ -82,19 +82,22 @@ static void testReorderedChainRestoresEachPluginItsOwnState() {
|
||||
// -- 2. FX deleted while parked ----------------------------------------------
|
||||
|
||||
static void testDeletedFxDropsExplicitlyAndTouchesNothingElse() {
|
||||
// B (true) and C (false) carry OPPOSITE captured states — the discriminator.
|
||||
// A test where both carried `true` couldn't tell "C's own state followed it
|
||||
// to slot 1" apart from "B's dropped state leaked onto whatever moved there".
|
||||
const std::vector<FxOfflineOp> ops =
|
||||
identityOps({{"{A}", false}, {"{B}", true}, {"{C}", true}});
|
||||
identityOps({{"{A}", false}, {"{B}", true}, {"{C}", false}});
|
||||
|
||||
// B was deleted while parked; A and C closed the gap.
|
||||
const FxRestoreResolution res = resolveFxRestore(ops, {"{A}", "{C}"});
|
||||
|
||||
CHECK(res.writes.size() == 2);
|
||||
CHECK(res.drops.missingIdentity == 1);
|
||||
CHECK(res.drops.unidentified == 0);
|
||||
CHECK(res.drops.slotOutOfRange == 0);
|
||||
CHECK(hasWrite(res, 0, false)); // A
|
||||
CHECK(hasWrite(res, 1, true)); // C followed its identity to slot 1
|
||||
// B's captured `true` did NOT land on whatever moved into slot 1.
|
||||
CHECK(res.writes.size() == 2);
|
||||
// C's OWN captured `false` landed at slot 1, not B's dropped `true`.
|
||||
CHECK(hasWrite(res, 1, false));
|
||||
|
||||
// The drop is reportable, not silent.
|
||||
const std::string msg = describeFxRestoreDrops(res.drops, /*trackCount=*/1);
|
||||
@@ -107,15 +110,17 @@ static void testDeletedFxDropsExplicitlyAndTouchesNothingElse() {
|
||||
CHECK(describeFxRestoreDrops(FxRestoreDrops{}, 0).empty());
|
||||
}
|
||||
|
||||
static void testDescribeNamesBothDropKinds() {
|
||||
static void testDescribeNamesAllThreeDropKinds() {
|
||||
FxRestoreDrops drops;
|
||||
drops.missingIdentity = 2;
|
||||
drops.unidentified = 1;
|
||||
drops.slotOutOfRange = 3;
|
||||
CHECK(drops.total() == 5);
|
||||
CHECK(drops.total() == 6);
|
||||
|
||||
const std::string msg = describeFxRestoreDrops(drops, /*trackCount=*/2);
|
||||
CHECK(msg.find("5 captured FX offline state(s) on 2 track(s)") != std::string::npos);
|
||||
CHECK(msg.find("6 captured FX offline state(s) on 2 track(s)") != std::string::npos);
|
||||
CHECK(msg.find("2 FX no longer in the chain") != std::string::npos);
|
||||
CHECK(msg.find("1 FX REAPER could not identify at capture time") != std::string::npos);
|
||||
CHECK(msg.find("3 from a project saved before FX identity was recorded")
|
||||
!= std::string::npos);
|
||||
}
|
||||
@@ -180,6 +185,10 @@ static void testSlotKeyedSnapshotRestoresByPositionAndBoundsChecks() {
|
||||
static void testUnresolvableIdentityNeverFallsBackToItsSlot() {
|
||||
// An identity-keyed entry with NO identity (REAPER reported none at capture)
|
||||
// is a drop — the slot it happens to carry must not be used as a substitute.
|
||||
// Counted as `unidentified`, not `missingIdentity`: unlike a real captured
|
||||
// identity going missing, this FX may still be sitting right there — we
|
||||
// simply never had a name for it, and the report must say that, not "no
|
||||
// longer in the chain".
|
||||
std::vector<FxOfflineOp> ops = identityOps({{"{A}", false}});
|
||||
ops.push_back(FxOfflineOp{"{TRACK}", FxKeying::Identity, "", /*slot=*/1, /*offline=*/true});
|
||||
|
||||
@@ -187,7 +196,12 @@ static void testUnresolvableIdentityNeverFallsBackToItsSlot() {
|
||||
CHECK(res.writes.size() == 1);
|
||||
CHECK(hasWrite(res, 0, false));
|
||||
CHECK(!writesTouch(res, 1)); // {B} would have been the slot-1 victim
|
||||
CHECK(res.drops.missingIdentity == 1);
|
||||
CHECK(res.drops.missingIdentity == 0);
|
||||
CHECK(res.drops.unidentified == 1);
|
||||
|
||||
const std::string msg = describeFxRestoreDrops(res.drops, /*trackCount=*/1);
|
||||
CHECK(msg.find("1 FX REAPER could not identify at capture time") != std::string::npos);
|
||||
CHECK(msg.find("no longer in the chain") == std::string::npos); // not this FX's story
|
||||
}
|
||||
|
||||
static void testLiveFxWithNoIdentityIsNeverARestoreTarget() {
|
||||
@@ -225,7 +239,7 @@ static void testDuplicateLiveIdentityResolvesToTheFirstSlotOnly() {
|
||||
int main() {
|
||||
testReorderedChainRestoresEachPluginItsOwnState();
|
||||
testDeletedFxDropsExplicitlyAndTouchesNothingElse();
|
||||
testDescribeNamesBothDropKinds();
|
||||
testDescribeNamesAllThreeDropKinds();
|
||||
testAddedFxIsNotTouched();
|
||||
testTwoInstancesOfOnePluginKeyIndependently();
|
||||
testSlotKeyedSnapshotRestoresByPositionAndBoundsChecks();
|
||||
|
||||
Reference in New Issue
Block a user