feat(persist): persist BankBook under banks key, retire legacy bank_index, route capture to active bank (B2)
This commit is contained in:
+42
-15
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "bank_book.h"
|
||||
#include "bank_model.h"
|
||||
#include "view_mode_model.h"
|
||||
|
||||
@@ -28,10 +29,21 @@ namespace reasampler {
|
||||
// shipped: changing it orphans every already-saved project's index.
|
||||
inline constexpr const char* kProjExtNamespace = "reasampler";
|
||||
|
||||
// The ext-state key the index JSON is stored under (one key holds the whole
|
||||
// serialized BankIndex). FOREVER-STABLE for the same reason.
|
||||
// The RETIRED legacy ext-state key: pre-multi-bank projects stored the whole
|
||||
// serialized BankIndex here (single bank). Phase B2 no longer WRITES it — on save
|
||||
// the key is cleared (SetProjExtState with "" deletes it) and the book is written
|
||||
// under kProjExtBanksKey instead. It is still READ once, on load of a legacy
|
||||
// project, to migrate its single index into the pool (BankBook's parse-time
|
||||
// promotion). FOREVER-STABLE as a read key for that migration path.
|
||||
inline constexpr const char* kProjExtIndexKey = "bank_index";
|
||||
|
||||
// The multi-bank ext-state key (Phase B): one key holds the whole serialized
|
||||
// BankBook — the pool folded in as bank-zero plus every named bank, each with its
|
||||
// own BankIndex, ordinals, and the active-bank id. AUTHORITATIVE going forward;
|
||||
// supersedes kProjExtIndexKey. FOREVER-STABLE once shipped: changing it orphans
|
||||
// every already-saved project's banks.
|
||||
inline constexpr const char* kProjExtBanksKey = "banks";
|
||||
|
||||
// The ext-state key the Design-View ViewModeModel JSON is stored under (one key
|
||||
// holds the whole serialized model: modes + membership + show-both + snapshots +
|
||||
// active mode). Distinct from kProjExtIndexKey — one namespace, two keys.
|
||||
@@ -45,8 +57,9 @@ inline constexpr const char* kProjExtViewKey = "view_state";
|
||||
// it strands the identity of every already-saved project. See persist.cpp.
|
||||
inline constexpr const char* kProjExtGuidKey = "project_guid";
|
||||
|
||||
// Owns the session's BankIndex and drives persistence against the active REAPER
|
||||
// project. One instance lives for the extension's lifetime (main.cpp). It tracks
|
||||
// Owns the session's BankBook (Phase B: pool + named banks) and drives persistence
|
||||
// against the active REAPER project. One instance lives for the extension's
|
||||
// lifetime (main.cpp). It tracks
|
||||
// the project identity it last saw so the timer tick can detect a project load
|
||||
// (a different project became active) and a Save-As (SAME project, path changed):
|
||||
//
|
||||
@@ -62,16 +75,28 @@ inline constexpr const char* kProjExtGuidKey = "project_guid";
|
||||
// W12 defect that stopped the bank reloading); the pointer catches forks (Save-As
|
||||
// copies our GUID onto a distinct object — the W10 defect that clobbered a bank).
|
||||
//
|
||||
// The bank itself is exposed for the capture/action layer to mutate; persist
|
||||
// The book itself is exposed for the capture/action layer to mutate; persist
|
||||
// only reads it on save and replaces it on load.
|
||||
class ReaSamplerSession {
|
||||
public:
|
||||
ReaSamplerSession() = default;
|
||||
|
||||
// The in-memory bank. The action/capture layer adds captures here; persist
|
||||
// serializes it on save and replaces it on project load.
|
||||
BankIndex& bank() { return bank_; }
|
||||
const BankIndex& bank() const { return bank_; }
|
||||
// The multi-bank book (Phase B): the pool + named banks, each wrapping a
|
||||
// BankIndex, plus the active-bank id. The action layer (B3) creates / renames /
|
||||
// reorders / deletes banks and moves samples here; the panel (B4) reads it;
|
||||
// persist serializes it under the `banks` key on save and replaces it on load.
|
||||
BankBook& book() { return book_; }
|
||||
const BankBook& book() const { return book_; }
|
||||
|
||||
// The capture add-target: the ACTIVE bank's BankIndex (defaults to the pool).
|
||||
// The capture path adds a captured Sample through this seam, so a capture lands
|
||||
// in whichever bank is active — the single behavioural change B2 wires in over
|
||||
// M7/M8 (the capture backends are untouched; only the target index moved). The
|
||||
// panel/insert readers that displayed the single index continue to read it here
|
||||
// unchanged; today it resolves to the pool (default active), matching prior
|
||||
// single-bank behaviour, until B3/B4 let the user switch the active bank.
|
||||
BankIndex& bank() { return book_.activeIndex(); }
|
||||
const BankIndex& bank() const { return book_.activeIndex(); }
|
||||
|
||||
// The in-memory Design-View model. The view/action layer mutates it (tag,
|
||||
// toggle, snapshot); persist serializes it on save and replaces it on project
|
||||
@@ -80,8 +105,9 @@ public:
|
||||
ViewModeModel& view() { return view_; }
|
||||
const ViewModeModel& view() const { return view_; }
|
||||
|
||||
// Serialize the current bank to the active project's ext state (namespace
|
||||
// "reasampler"). Non-destructive beyond writing our own ext-state key. Safe
|
||||
// Serialize the current book (under the `banks` key) and view model to the active
|
||||
// project's ext state (namespace "reasampler"), and clear the retired legacy
|
||||
// `bank_index` key. Non-destructive beyond writing our own ext-state keys. Safe
|
||||
// to call when there is no active/saved project (it no-ops).
|
||||
void saveToActiveProject();
|
||||
|
||||
@@ -103,7 +129,7 @@ public:
|
||||
bool consumeLoadSignal();
|
||||
|
||||
private:
|
||||
BankIndex bank_;
|
||||
BankBook book_;
|
||||
|
||||
// The Design-View model. Default-constructed = Arrange + Design seeded, active
|
||||
// = Arrange; loadFromProject leaves this default when a project has no stored
|
||||
@@ -124,9 +150,10 @@ private:
|
||||
bool primed_ = false; // false until the first poll() observes state
|
||||
bool loadPending_ = false; // raised by loadFromProject; drained by consumeLoadSignal
|
||||
|
||||
// Load the index from the given project's ext state and resolve bank paths
|
||||
// against projectDir. Replaces the in-memory bank. projectDir empty -> clears
|
||||
// the bank (unsaved project has no resolvable bank).
|
||||
// Load the book from the given project's ext state (the `banks` key, else the
|
||||
// legacy `bank_index` key migrated into the pool) and resolve bank paths against
|
||||
// projectDir at read time. Replaces the in-memory book. projectDir empty -> the
|
||||
// book is reset to empty (unsaved project has no resolvable banks).
|
||||
void loadFromProject(void* proj, const std::string& projectDir);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user