feat(persist): reload book+view on undo/redo via projectconfig hook (R-B)
BeginLoadProjectState(isUndo) requests a deferred reload the timer drains next tick, once REAPER has restored ext-state. Hook owns undo/redo; identity poll still owns open/tab-switch/save-as. Fixes copy-collapse over-count (verb-aware guard) and dangling undo point on unsaved-project bank ops.
This commit is contained in:
+26
-9
@@ -453,7 +453,9 @@ gaccel_register_t g_accelBankBanksFull{};
|
||||
// persists. This is an intentional divergence from persistViewState (above), which
|
||||
// DOES prompt Save-As on an unsaved project; do not "align" the two — a bank mutation
|
||||
// follows capture's quiet-persist idiom, a Design-View mutation follows the prompt idiom.
|
||||
void persistBook() { g_session->saveToActiveProject(); }
|
||||
// Returns whether a persist actually happened (false on an unsaved/no-active project),
|
||||
// so persistBankOp can skip its undo block when nothing was written.
|
||||
bool persistBook() { return g_session->saveToActiveProject(); }
|
||||
|
||||
// Persists a completed bank index verb (create/rename/reorder/delete/evacuate/
|
||||
// move/copy) as a SINGLE batched REAPER undo point (R-B) — one bank op = one Ctrl-Z.
|
||||
@@ -469,11 +471,22 @@ void persistBook() { g_session->saveToActiveProject(); }
|
||||
//
|
||||
// NO-OP GUARDRAIL: callers invoke this ONLY after the model mutation succeeded — a
|
||||
// rejected op (duplicate name, un-deletable pool, etc.) returns before reaching here,
|
||||
// so no dangling/empty undo point is ever opened.
|
||||
// so no dangling/empty undo point is ever opened for a rejected op.
|
||||
//
|
||||
// UNSAVED-PROJECT GUARDRAIL: on an unsaved / no-active project persistBook() no-ops
|
||||
// (nothing is written to ext state). We must still CLOSE the block we opened, but with
|
||||
// an EMPTY label and a zero flag so REAPER DISCARDS the point instead of recording a
|
||||
// no-effect undo entry — mirroring view.cpp's empty-plan close. The in-session model
|
||||
// change stands and persists on the user's next save; it just earns no undo point until
|
||||
// there is a project to persist into (undo of an unsaved bank op has nothing to roll
|
||||
// back to anyway). The Begin/End must still be balanced, hence the close-either-way.
|
||||
void persistBankOp(const char* label) {
|
||||
Undo_BeginBlock2(nullptr);
|
||||
persistBook();
|
||||
Undo_EndBlock2(nullptr, label, UNDO_STATE_MISCCFG);
|
||||
const bool persisted = persistBook();
|
||||
if (persisted)
|
||||
Undo_EndBlock2(nullptr, label, UNDO_STATE_MISCCFG);
|
||||
else
|
||||
Undo_EndBlock2(nullptr, "", 0); // no ext-state write -> discard the empty point
|
||||
}
|
||||
|
||||
// Prompts the user for a single line of text via REAPER's stock input dialog.
|
||||
@@ -713,11 +726,15 @@ void doBankTransferSelected(bool copy) {
|
||||
case TransferResult::RejectedSameBank: break;
|
||||
}
|
||||
}
|
||||
// No-op guardrail: if nothing actually changed the index (every selected sample was
|
||||
// absent, or all were pre-checked rejects), don't open an undo point. `collapsed`
|
||||
// counts a hash-collapse — that DID mutate the index (source entry removed on a
|
||||
// move, or dest already held the hash), so it belongs inside the undo point.
|
||||
if (ok > 0 || collapsed > 0) {
|
||||
// No-op guardrail — VERB-AWARE (a collapse means different things per verb):
|
||||
// * MOVE collapse: the source entry WAS removed (bank_book moveSample removes
|
||||
// unconditionally before the dest add collapses on hash), so the index DID
|
||||
// mutate — it counts toward opening an undo point.
|
||||
// * COPY collapse: the source is left intact AND the dest already held the hash,
|
||||
// so NOTHING changed — a true index no-op. It must NOT open an undo point.
|
||||
// Hence: copy counts only real gains (ok); move counts gains OR collapses.
|
||||
const bool mutated = copy ? (ok > 0) : (ok > 0 || collapsed > 0);
|
||||
if (mutated) {
|
||||
const std::string label =
|
||||
std::string("ReaSampler: ") + verb + " sample(s)";
|
||||
persistBankOp(label.c_str());
|
||||
|
||||
Reference in New Issue
Block a user