feat(S9/S8): bank-generation change-detection + instrument-side assignment reader

Extension stamps a monotonic bank_generation counter, bumped at content
mutations; the VST3 instrument polls it off-thread on an editor timer and
consumes assignment requests, refreshing playback hands-free.
This commit is contained in:
2026-07-26 23:46:06 -04:00
parent 725f3e7d3c
commit 66d47fb410
21 changed files with 838 additions and 36 deletions
+7 -4
View File
@@ -2059,7 +2059,10 @@ void doDeleteBank(const std::string& bankId) {
// r == 6 (Yes) falls through to a plain delete (drops members).
}
if (!book()->deleteBank(bankId)) return;
persistBankOp("ReaSampler: delete bank");
// S9: bump when the bank held samples (either the Yes-drop path or the No-evacuate-then-
// delete path moved/dropped members) — both change what a live instance could play. An
// empty-bank delete is purely organizational, no bump.
persistBankOp("ReaSampler: delete bank", /*bumpGeneration=*/members > 0);
// shownBankId is reconciled by the next fingerprint pass. If no named banks remain,
// nudge focus to the pool so the selection has a valid home.
if (namedBanks().empty()) g_panel.focusedRegion = Region::Pool;
@@ -2071,7 +2074,7 @@ void doEvacuateBank(const std::string& bankId) {
const Bank* bk = book()->bank(bankId);
if (!bk || bk->isPool()) return;
if (!book()->evacuate(bankId)) return;
persistBankOp("ReaSampler: evacuate bank");
persistBankOp("ReaSampler: evacuate bank", /*bumpGeneration=*/true); // S9: membership changed
invalidatePanel();
}
@@ -2115,7 +2118,7 @@ void transferSamples(const std::vector<std::string>& sampleIds,
if (!mutated) return; // nothing changed — no persist, no undo point
const char* label = copy ? "ReaSampler: copy sample(s)" : "ReaSampler: move sample(s)";
persistBankOp(label);
persistBankOp(label, /*bumpGeneration=*/true); // S9: bank membership changed
// The selection indexed into the source; after a move those indices are stale, so
// clear it (the fingerprint pass will also clear, but do it now for immediacy).
g_panel.selection = Selection{};
@@ -2140,7 +2143,7 @@ void removeSamples(const std::vector<std::string>& sampleIds,
++removed;
if (removed == 0) return; // nothing changed — no persist, no undo point
persistBankOp("ReaSampler: remove sample(s)");
persistBankOp("ReaSampler: remove sample(s)", /*bumpGeneration=*/true); // S9: sample dropped
// The selection indexed into the source; after a remove those indices are stale, so
// clear it (the fingerprint pass will also clear, but do it now for immediacy).
g_panel.selection = Selection{};