Clear the park snapshot where the restore is planned, not where it drains; make the drain re-entrant and reload-aware

This commit is contained in:
2026-08-03 13:35:30 -04:00
parent a4a1c3860f
commit 7169d7f22b
7 changed files with 298 additions and 91 deletions
+12 -6
View File
@@ -173,12 +173,6 @@ static void OnTimer()
g_session.poll();
// A mode switch applies its visibility/routing writes synchronously and leaves
// the per-FX offline work here, so the new mode paints before the plugins
// unload. Drained AFTER poll() so a project switch discards the queue instead
// of applying it to the project that replaced it; idle cost is one empty test.
reasampler::drainDeferredFxParks(g_session.view());
// persist stays MODEL-ONLY (loads the saved view model but does not apply
// visibility, to avoid coupling persist to the view shell); poll() raises a
// one-shot load signal that we drain here to reapply the SAVED active mode so a
@@ -187,12 +181,24 @@ static void OnTimer()
// reapply so re-arm and model restore ride the one load event (otherwise
// pre-existing tracks can be mis-detected as "new" and mass-tagged).
if (g_session.consumeLoadSignal()) {
// Every path that raises this signal — open, project switch, recycled
// pointer, undo/redo state restore — replaced the model the pending FX
// intents were planned against, so they are discarded rather than applied
// to the project that replaced it. This is the queue's ONLY guard against
// a recycled ReaProject*, which a pointer compare cannot see.
reasampler::discardDeferredFxParks();
reasampler::bankPanelNotifyProjectLoaded();
// Reconcile lane ownership against the live project's lanes (P_LANENAME,
// the cross-session source of truth) BEFORE reapplying visibility. Never
// re-mints, never mass-tags.
reasampler::reconcileManagedLanes(g_session.view(), nullptr);
reasampler::applyMode(g_session.view(), g_session.view().activeModeId(), nullptr);
} else {
// A mode switch applies its visibility/routing writes synchronously and
// leaves the per-FX offline work here, so the new mode paints before the
// plugins unload. Idle cost is one empty test. Skipped on a load tick so
// the reapply's own intents defer one tick like any other switch's.
reasampler::drainDeferredFxParks();
}
reasampler::bankPanelRefresh(); // cheap fingerprint compare; no-op when unchanged/closed