feat(persist): M4 bank persistence + Save-As relocation
Serialize BankIndex to project ext state ('reasampler'), reload on project
load, resolve paths project-relative. Save-As copies the bank to the new .rpp;
identity keyed off a minted GUID (not the recycled ReaProject*) so project
switches don't clobber banks. Pure classifyProjectTransition tested.
This commit is contained in:
+28
-6
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "bank_model.h"
|
||||
#include "capture.h"
|
||||
#include "persist.h"
|
||||
|
||||
// Persistent action-id prefix for the ReaSampler action family.
|
||||
// Every bindable action (capture / insert / slot / verify) mints its command id
|
||||
@@ -43,10 +44,20 @@ reaper_plugin_info_t* g_rec = nullptr; // REAPER's dispatch struct
|
||||
// (user keybindings key off it) — see the prefix note above.
|
||||
static int g_cmdCaptureMasterSpike = 0;
|
||||
|
||||
// In-memory bank for the spike. M4 replaces this with project ext-state persist;
|
||||
// for M3 the index lives only for the session, proving the capture->Sample->add
|
||||
// path end to end.
|
||||
static reasampler::BankIndex g_bank;
|
||||
// The persistence session (M4): owns the in-memory BankIndex and bridges it to
|
||||
// project ext state. A timer tick drives g_session.poll() to detect project
|
||||
// load / Save-As; capture adds Samples to g_session.bank(); after a capture we
|
||||
// serialize the bank back into the active project's ext state so it travels with
|
||||
// the .rpp. Replaces the M3 session-only g_bank.
|
||||
static reasampler::ReaSamplerSession g_session;
|
||||
|
||||
// The timer callback REAPER runs periodically (registered via "timer"). It only
|
||||
// forwards to the session poll — cheap per tick (reads the active project id and
|
||||
// its .rpp path, acts only on a change).
|
||||
static void OnTimer()
|
||||
{
|
||||
g_session.poll();
|
||||
}
|
||||
|
||||
// Runs the M3 spike: render the time-selection master mix, add the Sample, log.
|
||||
static void RunCaptureMasterSpike()
|
||||
@@ -76,9 +87,14 @@ static void RunCaptureMasterSpike()
|
||||
return;
|
||||
}
|
||||
|
||||
reasampler::AddResult added = g_bank.add(res.sample);
|
||||
reasampler::AddResult added = g_session.bank().add(res.sample);
|
||||
// Persist the updated bank into the active project's ext state so the capture
|
||||
// survives Save / close+reopen (M4). Non-destructive: writes only our own
|
||||
// ext-state key. No-ops on an unsaved project (nothing to store into yet).
|
||||
g_session.saveToActiveProject();
|
||||
|
||||
std::string log = "ReaSampler: " + res.message + "\n";
|
||||
log += " bank size now " + std::to_string(g_bank.size()) +
|
||||
log += " bank size now " + std::to_string(g_session.bank().size()) +
|
||||
(added == reasampler::AddResult::Added ? " (added)\n"
|
||||
: added == reasampler::AddResult::Collapsed ? " (collapsed on hash)\n"
|
||||
: " (rejected)\n");
|
||||
@@ -106,6 +122,7 @@ extern "C" REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT(
|
||||
// callback with the same strings prefixed '-' (per the contract).
|
||||
if (g_rec)
|
||||
{
|
||||
g_rec->Register("-timer", (void*)&OnTimer);
|
||||
g_rec->Register("-hookcommand", (void*)&OnHookCommand);
|
||||
g_rec->Register("-gaccel", (void*)&g_accelCaptureMaster);
|
||||
g_rec->Register("-command_id",
|
||||
@@ -139,6 +156,11 @@ extern "C" REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT(
|
||||
rec->Register("hookcommand", (void*)&OnHookCommand);
|
||||
}
|
||||
|
||||
// Drive project-load / Save-As detection (M4 persist). The timer polls the
|
||||
// active project each tick; on a project load it reloads the bank from ext
|
||||
// state, on a Save-As it relocates the bank folder under the new .rpp.
|
||||
rec->Register("timer", (void*)&OnTimer);
|
||||
|
||||
ShowConsoleMsg("ReaSampler loaded.\n");
|
||||
|
||||
return 1; // success — REAPER keeps us loaded
|
||||
|
||||
Reference in New Issue
Block a user