Fix undo-label misnomer, tighten drain-nesting/abort-path docs, mark inferred undo behavior as unverified

Renamed the drain's undo point to "Design View FX state" (it restores as often as it parks). Extended the nesting audit to cover a block opening inside the drain's own block. Marked post-fix undo behavior as inference pending DAW checks.
This commit is contained in:
2026-08-05 20:54:31 -04:00
parent 13c824c63d
commit 8a7056d19d
5 changed files with 59 additions and 32 deletions
+10 -4
View File
@@ -106,10 +106,16 @@ RestoreOutcome applyRestore(MediaTrack* tr, const std::vector<FxOfflineOp>& ops)
// per-FX fragmentation this closes). The block is deliberately the drain's OWN
// and never the switch's — the FX point has to stay ABOVE the switch's.
//
// Closing is unconditional on every exit, the abort path included: an unbalanced
// block would swallow every later action into one point, which is far worse than
// [verify — DAW] whatever Undo_EndBlock2 does with a ReaProject* that has closed
// since Undo_BeginBlock2 took it.
// Closing is unconditional on every exit, the abort path included. Which of two
// undocumented models REAPER uses decides whether that is the safe call:
// under a GLOBAL block-nesting counter, leaving this one unbalanced would
// swallow every later action — in ANY project — into one point, far worse than
// calling Undo_EndBlock2 on a ReaProject* that closed since Undo_BeginBlock2
// took it. Under a PER-PROJECT counter, an unbalanced block on a now-dead
// project costs nothing, and the closing call against a stale pointer is the
// riskier of the two. Closing unconditionally is the safer bet under the
// global model and merely unnecessary under the per-project one, hence the
// choice. [verify — DAW] which model REAPER actually implements.
class FxParkUndoBlock {
public:
explicit FxParkUndoBlock(ReaProject* proj) : proj_(proj) { Undo_BeginBlock2(proj_); }