Design View: no undo block may open over the reclaim span, and a reapply closes none
Every opener ends the span first, so a tag fired mid-drain no longer hijacks the switch's point. One stated criterion governs both lane sites; no-op actions discard.
This commit is contained in:
+23
-4
@@ -27,6 +27,21 @@ bool transportBlocksModeSwitch(ReaProject* proj);
|
||||
// one-shot signal on a call that would be refused — see main.cpp's load glue.
|
||||
bool modeApplyInProgress();
|
||||
|
||||
// What one applyMode did.
|
||||
//
|
||||
// `wroteProjectState` counts REAPER writes ONLY — a driven flag, a lane parameter,
|
||||
// a parent's visibility. Model moves (a snapshot stored, a record's flag half spent,
|
||||
// the active mode set) are deliberately excluded: they reach disk through
|
||||
// persistViewState, which every caller runs OUTSIDE its undo block, so no point can
|
||||
// carry them and counting them would only mint an empty one. It is the answer a
|
||||
// caller holding its own block needs for the discard decision (design_view_actions'
|
||||
// ActionUndoBlock); the solo pair cannot affect it, since only a real switch drives
|
||||
// solo and a real switch mints regardless.
|
||||
struct ModeApplyResult {
|
||||
bool applied = false;
|
||||
bool wroteProjectState = false;
|
||||
};
|
||||
|
||||
// Captures each about-to-park track's prior flag values into `model`, caches/clears
|
||||
// the outgoing mode's solo state and replays the incoming mode's, runs planToggle,
|
||||
// applies the park/restore flag writes plus managed-lane and parent-visibility
|
||||
@@ -41,16 +56,20 @@ bool modeApplyInProgress();
|
||||
// A REAL switch therefore RETURNS WITH ITS UNDO BLOCK STILL OPEN (fx_reclaim's
|
||||
// UndoSpan): the reclaimer closes it once the parking has drained, which is what keeps
|
||||
// the switch and its FX writes ONE point rather than two. A reapply opens none, so a
|
||||
// caller that wants its own act undoable opens its own (design_view_actions does).
|
||||
// caller that wants its own act undoable opens its own (design_view_actions does) —
|
||||
// and, because REAPER's blocks are a depth counter, ENDS THE SPAN BEFORE IT OPENS
|
||||
// THAT BLOCK. A reapply never closes a span, precisely because it can be running
|
||||
// inside such a caller's block.
|
||||
//
|
||||
// Returns false (no mutation) if `targetModeId` isn't registered, if this is a real
|
||||
// switch (target != active) while the transport is running, if it is re-entered
|
||||
// `applied` is false (no mutation) if `targetModeId` isn't registered, if this is a
|
||||
// real switch (target != active) while the transport is running, if it is re-entered
|
||||
// (modeApplyInProgress), or if the project does not validate. A reapply (target ==
|
||||
// active) is never gated and never touches solo. `proj` == nullptr means the current
|
||||
// project, resolved ONCE and used for every call this apply makes.
|
||||
//
|
||||
// Either way — applied or refused — this drops the FX reclaimer's derived queue, which
|
||||
// is why callers may safely discard the return after mutating the model.
|
||||
bool applyMode(ViewModeModel& model, const std::string& targetModeId, ReaProject* proj);
|
||||
ModeApplyResult applyMode(ViewModeModel& model, const std::string& targetModeId,
|
||||
ReaProject* proj);
|
||||
|
||||
} // namespace reasampler
|
||||
|
||||
Reference in New Issue
Block a user