Docs: record the Design View mode-switch redesign in COMPLETED.md

This commit is contained in:
2026-08-21 14:50:22 -04:00
parent da8401239a
commit 4acde051b1
+46
View File
@@ -1660,3 +1660,49 @@ v2 blob keeps the behaviour it had rather than losing every FX state.
**Left open, filed to `docs/TODO.md`:** FX-GUID stability itself — whether
`TrackFX_GetFXGUID` survives a chain reorder while parked — is unverified in the DAW
(SWS issue #802 names a specific way it might not hold).
### Design View mode-switch redesign — FX off the switch path, one undo point
Four waves, merged to `dev` as `da84012`, that took the per-FX offline/online work
off the Design View mode switch's synchronous path and collapsed the switch's undo
footprint to a single point.
The first wave split the pure layer: park plans became flag-only, the FX work list
is now derived separately (new `src/core/view/fx_state.{h,cpp}` — `desiredFxState`,
`fxRestoreTargets`, `resolveFxWork`), the park record's two halves now release
independently (the flag half at restore, the FX half only once the reclaimer has
actually driven the chain back online), and a new `applied_state.{h,cpp}`
fingerprints what the last apply actually drove, for a reconcile pass to diff
against a reloaded model.
The second wave restructured the shell to match: FX writes were stripped out of the
mode switch itself, `src/shell/view/view.cpp` split into `view_park`, `view_lanes`,
`view_reconcile`, and `view_tracks`, and `view_fx_park.{h,cpp}` was deleted
outright. A track that reads park-shaped (flags only) but carries no park record is
now handed back visible with a named console report ("EXPOSE") rather than
silently adopted as a park or refused.
The third wave added the reclaimer: new `src/shell/view/fx_reclaim.{h,cpp}`, a
debounced (`kParkHoldMs`, 3s) and time-boxed (`kOnlineBudgetMs`/`kOfflineBudgetMs`
per tick) background convergence loop that offlines parked chains and restores
returning ones off the switch path. Each track moves atomically per step, the
derived work queue is owned by a generation-counted `FxReclaimQueue` so a mid-drain
invalidation is never applied over stale state, the offline direction (not online)
is gated off the transport, and a completed record's release is held in memory and
only made durable on the project's next save — never on the drain's own
initiative.
The fourth wave collapsed the undo footprint: a new `src/shell/undo/` module holds
the one REAPER undo-block opener, `UndoBlock`, which every extension-owned block in
the tree — thirteen call sites across `shell/actions`, `shell/capture`,
`shell/bank_ops`, and `shell/view` — now routes through, plus `undo_intercept`'s
interception of REAPER's own Undo/Redo dispatch (ids `40029`/`40030`), which ends
the FX reclaim span before REAPER runs the command so the switch's own undo point
mints first rather than being caught mid-drain.
**Left open:** `fxReclaimActivity()` — added in the fourth wave so a UI indicator
could paint the drain's direction — shipped with no caller; a separate,
not-yet-merged branch supplies one. `src/shell/view/CLAUDE.md` still carries a
`[verify — DAW]` note on whether a redo can re-strand a track (rebuilding the
pre-switch `view_state`, which carries no snapshot for a track that reads parked)
— unresolved.