D3: persist ViewModeModel in project ext state alongside bank

Add forever-stable "view_state" key under the "reasampler" namespace.
saveToActiveProject additionally serializes the ViewModeModel;
loadFromProject restores it on every load path, defaulting on an
absent/malformed key. Model state only — no visibility apply (D4).
This commit is contained in:
2026-07-22 20:56:04 -04:00
parent 2d040d6896
commit ae76653628
2 changed files with 55 additions and 0 deletions
+19
View File
@@ -20,6 +20,7 @@
#include <string>
#include "bank_model.h"
#include "view_mode_model.h"
namespace reasampler {
@@ -31,6 +32,12 @@ inline constexpr const char* kProjExtNamespace = "reasampler";
// serialized BankIndex). FOREVER-STABLE for the same reason.
inline constexpr const char* kProjExtIndexKey = "bank_index";
// 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.
// FOREVER-STABLE: changing it orphans every already-saved project's view state.
inline constexpr const char* kProjExtViewKey = "view_state";
// The ext-state key holding a GUID we mint per project to establish CONTENT-BASED
// project identity (REAPER exposes no stable per-project GUID). poll() uses it to
// tell a genuine Save-As (same GUID, new .rpp path) apart from a project switch
@@ -62,6 +69,13 @@ public:
BankIndex& bank() { return bank_; }
const BankIndex& bank() const { return bank_; }
// 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
// load — exactly as it treats the bank. D3 persists MODEL STATE only; applying
// visibility/processing (reapply-on-open) is D4's job, not this member's.
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
// to call when there is no active/saved project (it no-ops).
@@ -75,6 +89,11 @@ public:
private:
BankIndex bank_;
// The Design-View model. Default-constructed = Arrange + Design seeded, active
// = Arrange; loadFromProject leaves this default when a project has no stored
// view_state (older project), so an absent key is graceful, not a crash.
ViewModeModel view_;
// The project identity last observed by poll(), used to detect load/Save-As.
// Identity is the GUID we mint per project (kProjExtGuidKey), NOT the raw
// ReaProject* pointer — see the class comment for why. The .rpp path is