fx_reclaim: use GetCurrentProjectInLoadSave for the save hook, stop disarming ReleaseFlush on one write, validate project before cached-track lookup
This commit is contained in:
@@ -110,11 +110,11 @@ struct FakeHost {
|
||||
};
|
||||
|
||||
// What the project-save hook does (fxReclaimFlushRelease): write the in-memory model into
|
||||
// this project's view state, but only when it is the project holding the release.
|
||||
// this project's view state, but only when it is the project holding the release. Does
|
||||
// NOT clear the arm — see ReleaseFlush — so calling this twice re-issues the same write.
|
||||
void saveProject(FakeHost& host, ReleaseFlush& flush, ReaProject* active) {
|
||||
if (!flush.pendingFor(active)) return;
|
||||
host.persisted = host.model->serialize();
|
||||
flush.clear();
|
||||
}
|
||||
|
||||
// -- model helpers -------------------------------------------------------------
|
||||
@@ -570,9 +570,10 @@ static void testACompletedOnlineReachesDiskOnTheSaveAndNotOnTheDrain() {
|
||||
CHECK(flush.pendingFor(kProjA)); // ...and the save knows it is owed
|
||||
|
||||
// The user's next save is what spends it — and afterwards a reload plans no work,
|
||||
// so nothing re-drives the chain.
|
||||
// so nothing re-drives the chain. The arm itself survives the write (see
|
||||
// testTheFlushArmSurvivesASaveAndCanBeReIssued) — this test is about the disk content.
|
||||
saveProject(host, flush, kProjA);
|
||||
CHECK(!flush.pendingFor(kProjA));
|
||||
CHECK(flush.pendingFor(kProjA));
|
||||
const std::optional<ViewModeModel> afterSave = ViewModeModel::deserialize(host.persisted);
|
||||
CHECK(afterSave.has_value());
|
||||
CHECK(afterSave->snapshot("{T}") == nullptr); // both halves spent ⇒ record erased
|
||||
@@ -640,6 +641,36 @@ static void testATickThatSpendsNoRecordOwesNoSaveAnything() {
|
||||
CHECK(host.persisted.empty());
|
||||
}
|
||||
|
||||
static void testTheFlushArmSurvivesASaveAndCanBeReIssued() {
|
||||
// Whether a write made from inside the save hook reaches the very file being written
|
||||
// now, or lands one save late, is unsettled (ReleaseFlush's [verify — DAW]). The arm
|
||||
// must not treat one issued write as proof of a durable spend: it stays armed, so an
|
||||
// unfavourable answer still gets a retry on the project's NEXT save rather than
|
||||
// stranding the record in memory for the rest of the session.
|
||||
ViewModeModel vm = parkedDesignLeaf({"{FX-A}", "{FX-B}"});
|
||||
vm.setActiveMode(kDesignModeId);
|
||||
vm.releaseSnapshotFlags("{T}");
|
||||
|
||||
FakeHost host;
|
||||
host.model = &vm;
|
||||
ReleaseFlush flush;
|
||||
flush.arm(kProjA);
|
||||
|
||||
saveProject(host, flush, kProjA);
|
||||
CHECK(!host.persisted.empty());
|
||||
CHECK(flush.pendingFor(kProjA)); // survives the flush — not disarmed by one write
|
||||
|
||||
// A second save re-issues the identical write rather than finding nothing to do.
|
||||
host.persisted.clear();
|
||||
saveProject(host, flush, kProjA);
|
||||
CHECK(!host.persisted.empty());
|
||||
CHECK(flush.pendingFor(kProjA));
|
||||
|
||||
// A different project's save must still leave this arm untouched.
|
||||
saveProject(host, flush, kProjB);
|
||||
CHECK(flush.pendingFor(kProjA));
|
||||
}
|
||||
|
||||
// -- 7. captured FX state the online direction cannot place -------------------------
|
||||
|
||||
static void testADropIsReportedOnceAcrossRepeatedRederivations() {
|
||||
@@ -930,6 +961,7 @@ int main() {
|
||||
testACompletedOnlineReachesDiskOnTheSaveAndNotOnTheDrain();
|
||||
testAReleaseKilledBeforeTheFlushIsSimplyReEarned();
|
||||
testATickThatSpendsNoRecordOwesNoSaveAnything();
|
||||
testTheFlushArmSurvivesASaveAndCanBeReIssued();
|
||||
|
||||
testADropIsReportedOnceAcrossRepeatedRederivations();
|
||||
testAnOfflineTickReportsNoDrops();
|
||||
|
||||
Reference in New Issue
Block a user