Terminate the FX reclaimer's undo span on EVERY project-state load, not just undo

BeginLoadProjectState now routes unbranched through fxReclaimAbandonForStateLoad;
only the session's deferred reload stays undo-only.
This commit is contained in:
2026-08-07 13:57:06 -04:00
parent 9b6f725747
commit 39b995e824
3 changed files with 48 additions and 34 deletions
+9 -11
View File
@@ -241,21 +241,19 @@ static void OnTimer()
// TIMING: BeginLoadProjectState fires BEFORE any state restore, so reading
// GetProjExtState here would return the PRE-undo value. Instead we raise a one-shot
// reload request that OnTimer's poll() drains on the NEXT tick, once REAPER has
// finished restoring the <EXTSTATE> block. A normal project open also fires this
// (isUndo=false); ignored here so a normal open flows solely through the timer's
// identity-transition Load path (no double load).
// finished restoring the <EXTSTATE> block. Only the RELOAD REQUEST is undo-only: a
// normal open's reload belongs to the timer's identity-transition Load path, whose
// forked-sibling re-GUID branch requesting a reload here would bypass.
static void OnBeginLoadProjectState(bool isUndo, project_config_extension_t* /*reg*/)
{
// UNBRANCHED, and the reason the terminator is a hook at all: this is REAPER's one
// entry for a state load — "project load/undo", plus a new project
// (reaper_plugin.h:1203-1205) — and the last moment before the restore. Why that
// matters, and why isUndo does not narrow it: fxReclaimAbandonForStateLoad.
reasampler::fxReclaimAbandonForStateLoad();
if (isUndo)
{
// BEFORE the reload request, and the whole reason this is a hook rather than
// something the reload's own reapply does on arrival: the reclaimer's undo block
// is open for at least kParkHoldMs after every real mode switch, and a switch is
// exactly what this undo is rolling back. Closing it here is the last moment it
// still closes over the state it was opened on.
reasampler::fxReclaimAbandonForStateLoad();
g_session.requestReload();
}
}
// Intentional no-op: ReaSampler stores state via project EXT STATE, not this