One undo-block opener for the whole tree: fourteen sites route through it, and the reclaim span can no longer swallow a user's act
The drain refuses a tick inside a foreign block; applyMode wakes the reclaimer before it opens the span.
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "shell/persist/session.h" // flushViewState — the release's durable half
|
||||
#include "shell/undo/undo_block.h" // undoBlockOpen — the reverse of the nesting rule
|
||||
#include "shell/view/view.h" // modeApplyInProgress, transportBlocksModeSwitch
|
||||
#include "shell/view/view_park.h" // fxGuidString — the one FX-identity read
|
||||
#include "shell/view/view_tracks.h"
|
||||
@@ -233,12 +234,21 @@ void invalidateFxReclaim() {
|
||||
bool fxReclaimDrainInProgress() { return g_draining; }
|
||||
|
||||
void fxReclaimTick(ReaSamplerSession& session, ReaProject* proj) {
|
||||
// Neither guard may close the span: both name a caller that is still on the stack and
|
||||
// still owns it — the outer drain, or the applyMode that opened it. Both re-tick.
|
||||
// NO guard here may close the span: each names a caller that is still on the stack and
|
||||
// still owns it — the outer drain, or the applyMode that opened it. All re-tick.
|
||||
if (g_draining) return;
|
||||
// The model is mid-rewrite and its records are being consumed out from under any
|
||||
// plan derived from it. The apply invalidates on its way out, so nothing is lost.
|
||||
if (modeApplyInProgress()) return;
|
||||
// The MIRROR of the rule that no block may open over the span: an extension undo
|
||||
// block is open — a capture, a bank verb, an ingest — and its own message pump is how
|
||||
// this tick arrived. openSpan from in there would begin at depth 2, and that block's
|
||||
// close would then mint under the SPAN's label and destroy the user's own point.
|
||||
// Refused whole rather than written unspanned, which would instead absorb the FX
|
||||
// toggles into the user's act. Starves nothing: the wakeup, the derived queue and the
|
||||
// project pin are all untouched (this returns before beginTick), so the first tick
|
||||
// after the block closes drains exactly as if this one had never been due.
|
||||
if (undoBlockOpen()) return;
|
||||
DrainLatch latch;
|
||||
|
||||
// beginTick owns what a pin/project mismatch means. What is local to here: the model
|
||||
|
||||
Reference in New Issue
Block a user