Gate the FX reclaimer on the transport, both directions; move the release's persist off the drain and onto the project save

The drain no longer dirties a project on its own initiative — a spent park record rides the user's next save via OnSaveExtensionConfig.
This commit is contained in:
2026-08-06 22:31:47 -04:00
parent 224dcf84df
commit 02790f1270
6 changed files with 288 additions and 79 deletions
+11 -4
View File
@@ -250,18 +250,25 @@ static void OnBeginLoadProjectState(bool isUndo, project_config_extension_t* /*r
g_session.requestReload();
}
// Intentional no-ops: ReaSampler stores state via project EXT STATE, not this
// extension's own project lines. The struct is registered ONLY for the
// BeginLoadProjectState undo/redo notification.
// Intentional no-op: ReaSampler stores state via project EXT STATE, not this
// extension's own project lines.
static bool OnProcessExtensionLine(const char* /*line*/, ProjectStateContext* /*ctx*/,
bool /*isUndo*/, project_config_extension_t* /*reg*/)
{
return false; // we own no project lines — ext state carries our data
}
static void OnSaveExtensionConfig(ProjectStateContext* /*ctx*/, bool /*isUndo*/,
// We write no lines into `ctx` — this is the FX reclaimer's one durability point. Its
// spent park records ride the user's save rather than dirtying the project on the
// reclaimer's own initiative (fx_reclaim.h's ReleaseFlush).
//
// A save only: an isUndo pass is REAPER capturing an undo point, not writing the file,
// and clearing the pending flush on one would leave the record unspent on disk for good.
static void OnSaveExtensionConfig(ProjectStateContext* /*ctx*/, bool isUndo,
project_config_extension_t* /*reg*/)
{
if (!isUndo)
reasampler::fxReclaimFlushRelease(g_session);
}
// Storage must outlive registration — REAPER holds this pointer until we unregister it.