Defer Design View's per-FX park to an idle tick; honest undo mask, compare-before-write, PreventUIRefresh bracket, O(1) handle resolve

This commit is contained in:
2026-08-03 12:39:22 -04:00
parent 0eb2c67875
commit a4a1c3860f
8 changed files with 568 additions and 170 deletions
+7
View File
@@ -38,6 +38,7 @@ add_library(reaper_reasampler MODULE
${LICE_SRC}
${REASAMPLER_SRC_DIR}/shell/capture/insert.cpp
${REASAMPLER_SRC_DIR}/shell/view/view.cpp
${REASAMPLER_SRC_DIR}/shell/view/view_fx_park.cpp
${REASAMPLER_SRC_DIR}/shell/view/view_solo.cpp
${REASAMPLER_SRC_DIR}/shell/capture/track_guid.cpp
${REASAMPLER_SRC_DIR}/shell/capture/provenance_shell.cpp
@@ -59,6 +60,12 @@ target_link_libraries(reaper_reasampler PRIVATE json wire file_bytes bank_model
# link graph free of the voice engine — a link edge to it here means the design drifted.
target_include_directories(reaper_reasampler PRIVATE ${SDK_INC} ${WDL_INC})
# The deferred FX-park queue's re-entrancy rule is pure (header-inline, no REAPER
# types), so it is CTest-covered like a core/ module. Declared here rather than in a
# src/shell/view/CMakeLists.txt because that directory deliberately has none — its
# TUs are compiled into this target directly.
reasampler_test(view_fx_park LINK fx_offline)
# Bank-package import: the promptless verb plus its action skin. Kept as its own
# appended block rather than merged into the lists above, so the two package
# directions stay textually independent.
+7
View File
@@ -38,6 +38,7 @@
#include "shell/panel/panel_window.h" // panel lifecycle (init/toggle/open-query/shutdown)
#include "shell/persist/session.h" // ReaSamplerSession
#include "shell/view/view.h" // reconcileManagedLanes / applyMode
#include "shell/view/view_fx_park.h" // the mode switch's deferred FX park
namespace capture = reasampler::capture;
@@ -172,6 +173,12 @@ 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