feat(prune): R2 dry-run prune shell + persist wiring, report-only

Add ReaSamplerSession::pruneDryRun enumerating the resolved current bank
folder, feeding the R1 core, and returning a PruneReport (count/bytes/list).
New pure bankRelativeForName + buildPruneReport keep spelling and tally
testable. Register forever-stable BANK_PRUNE_FOLDER action, report-only. No deletion.
This commit is contained in:
2026-07-26 18:19:41 -04:00
parent 46176f3f04
commit c1473c42e1
10 changed files with 297 additions and 1 deletions
+38
View File
@@ -451,6 +451,10 @@ constexpr const char* kIdBankCopySel = "BANK_COPY_SELECTED";
constexpr const char* kIdBankRemoveSel = "BANK_REMOVE_SELECTED";
constexpr const char* kIdBankPoolFull = "BANK_POOL_FULLHEIGHT";
constexpr const char* kIdBankBanksFull = "BANK_BANKS_FULLHEIGHT";
// Phase R (Reclaim), R2: the FOREVER-STABLE "Prune bank folder" id. Registered NOW so
// in-DAW dry-run verification is possible; R2 behaviour is REPORT-ONLY (no deletion),
// and R3 extends the confirm-and-delete step behind this SAME id — never a throwaway id.
constexpr const char* kIdBankPruneFolder = "BANK_PRUNE_FOLDER";
int g_cmdBankCreate = 0;
int g_cmdBankRename = 0;
@@ -463,6 +467,7 @@ int g_cmdBankCopySel = 0;
int g_cmdBankRemoveSel = 0;
int g_cmdBankPoolFull = 0;
int g_cmdBankBanksFull = 0;
int g_cmdBankPruneFolder = 0;
gaccel_register_t g_accelBankCreate{};
gaccel_register_t g_accelBankRename{};
@@ -475,6 +480,7 @@ gaccel_register_t g_accelBankCopySel{};
gaccel_register_t g_accelBankRemoveSel{};
gaccel_register_t g_accelBankPoolFull{};
gaccel_register_t g_accelBankBanksFull{};
gaccel_register_t g_accelBankPruneFolder{};
// Persists the book after a bank mutation. Mirrors the CAPTURE path (main.cpp
// RunCapture), NOT the Design-View path: a bank change is held in-session and written
@@ -791,6 +797,31 @@ void doBankRemoveSelected() {
if (removed > 0) persistBankOp("ReaSampler: remove sample(s)");
}
// Prune bank folder — Phase R (Reclaim), R2: REPORT-ONLY dry run. Asks the session for
// the orphan set of the resolved CURRENT bank folder ((owned ∩ present) referenced,
// unioned across every bank) and prints the truthful reclaim report — count, reclaimable
// bytes, and the file list. DELETES NOTHING, writes no ext-state, opens no undo point
// (pruneDryRun is read-only across the persist seam). R3 extends this SAME action id to
// confirm-and-delete behind the dry-run guardrail; the report path here is what R3 wraps.
void doBankPruneFolder() {
const PruneReport report = g_session->pruneDryRun();
if (report.count == 0) {
ShowConsoleMsg("ReaSampler prune (dry run): no orphaned files to reclaim.\n");
return;
}
std::string msg = "ReaSampler prune (dry run): " + std::to_string(report.count) +
" orphaned file(s), " + std::to_string(report.totalBytes) +
" bytes reclaimable. (Dry run -- nothing deleted.)\n";
for (const std::string& rel : report.orphans) msg += " " + rel + "\n";
if (report.truncated) {
msg += " ... (" + std::to_string(report.count - report.orphans.size()) +
" more not shown)\n";
}
ShowConsoleMsg(msg.c_str());
}
} // namespace
// Persists a completed bank-index verb as a SINGLE batched REAPER undo point (R-B) —
@@ -851,6 +882,10 @@ void bankRegisterActions(reaper_plugin_info_t* rec, ReaSamplerSession* session)
"toggle pool full-height");
g_cmdBankBanksFull = registerAction(rec, kIdBankBanksFull, g_accelBankBanksFull,
"toggle banks full-height");
// Phase R, R2: the "Prune bank folder" action (report-only in this wave; R3 extends
// the confirm-and-delete step behind this SAME forever-stable id).
g_cmdBankPruneFolder = registerAction(rec, kIdBankPruneFolder, g_accelBankPruneFolder,
"prune bank folder");
}
bool bankHandleCommand(int command) {
@@ -867,6 +902,7 @@ bool bankHandleCommand(int command) {
if (command == g_cmdBankRemoveSel) { doBankRemoveSelected(); return true; }
if (command == g_cmdBankPoolFull) { bankPanelToggledPoolFullHeight(); return true; }
if (command == g_cmdBankBanksFull) { bankPanelToggledBanksFullHeight(); return true; }
if (command == g_cmdBankPruneFolder) { doBankPruneFolder(); return true; }
return false; // not ours — caller's hookcommand keeps looking
}
@@ -874,6 +910,8 @@ bool bankHandleCommand(int command) {
void bankUnregisterActions(reaper_plugin_info_t* rec) {
// Mirror-unregister with '-'-prefixed strings, reverse of registration order. Each
// '-command_id' re-presents the same interned channel-qualified id (channelIdFor).
rec->Register("-gaccel", (void*)&g_accelBankPruneFolder);
rec->Register("-command_id", (void*)channelIdFor(kIdBankPruneFolder));
rec->Register("-gaccel", (void*)&g_accelBankBanksFull);
rec->Register("-command_id", (void*)channelIdFor(kIdBankBanksFull));
rec->Register("-gaccel", (void*)&g_accelBankPoolFull);