Cut shell/instrument comment bloat ~34% (comments only, zero code change)

This commit is contained in:
2026-07-29 20:48:43 -04:00
parent 1f24c4b095
commit d4d29146c7
19 changed files with 1131 additions and 1769 deletions
+38 -62
View File
@@ -5,41 +5,33 @@
#include <vector>
#include "core/instrument/map/bridge_marshal.h"
#include "core/wire/ext_state_read.h" // readProjExtStateGrowing (T2-04 grow-loop policy)
#include "core/capture/capture_paths.h" // projectDirOfRpp (shared M4 project-dir derivation)
#include "core/wire/ext_state_read.h" // readProjExtStateGrowing (grow-loop policy)
#include "core/capture/capture_paths.h" // projectDirOfRpp (shared project-dir derivation)
#include "ext_keys.h" // kProjExtNamespace (shared wire contract)
// The VST3 base types must be included before REAPER's VST3 interface header, which
// uses FUnknown / CStringA / uint32 / DECLARE_CLASS_IID / PLUGIN_API from
// pluginterfaces/base — all in namespace Steinberg.
// VST3 base types must be included before REAPER's VST3 interface header, which uses
// unqualified Steinberg types (FUnknown, CStringA, uint32, DECLARE_CLASS_IID, PLUGIN_API).
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/ftypes.h"
// REAPER's VST3-side bridge interface (vendored). IReaperHostApplication is what REAPER
// passes (as an IHostApplication) to IComponent::initialize; it exposes getReaperApi
// (resolve-by-name) and getReaperParent (host context). The header uses UNQUALIFIED
// Steinberg types (FUnknown, CStringA, uint32, FUID, DECLARE_CLASS_IID, PLUGIN_API), so
// it must be pulled into the Steinberg namespace — the same way REAPER's own VST3
// examples include it.
// REAPER's VST3-side bridge interface (vendored): IReaperHostApplication is the
// IHostApplication REAPER passes to IComponent::initialize, exposing getReaperApi
// (resolve-by-name) and getReaperParent (host context). Pulled into namespace Steinberg
// (the header's unqualified types), the same way REAPER's own VST3 examples include it.
namespace Steinberg {
#include "reaper_vst3_interfaces.h"
} // namespace Steinberg
// DECLARE_CLASS_IID in the REAPER header only DECLARES IReaperHostApplication::iid; some
// TU must DEFINE it. We do it here — this is the only place that queries for the
// interface (FUnknownPtr uses the iid), so the definition lives with its sole use.
// DECLARE_CLASS_IID in the REAPER header only declares the iid; this is the only TU that
// queries for the interface, so the DEFINE lives with its sole use.
DEF_CLASS_IID(Steinberg::IReaperHostApplication)
// The ext-state namespace is the SHARED wire contract between the extension (writer)
// and this instrument (reader); it lives in ext_keys.h (pure, REAPER-free) —
// reasampler::kProjExtNamespace() — so the two artifacts read one symbol and cannot
// drift. Channel-derived (Phase V, V4): the accessor returns "reasampler" (stable) or
// "reasampler_beta" (beta), matching whatever the extension wrote. The S1 spike
// duplicated it locally; that duplication is retired.
// The ext-state namespace is the shared wire contract with the extension — ext_keys.h's
// kProjExtNamespace() (pure, REAPER-free), channel-derived so both artifacts read one
// symbol and cannot drift.
namespace reasampler::vst {
// Real-namespace-home using-declarations (Q-W6: the namespaces.h shim is retired).
using capture::projectDirOfRpp;
using instrument::map::decodeGetProjExtState;
@@ -53,27 +45,24 @@ bool ReaperBridge::connect(Steinberg::FUnknown* context) {
hostApp_ = nullptr;
if (!context) return false;
// Query the host context for REAPER's bridge interface. In a non-REAPER host this
// query fails and we stay unconnected — the instrument still loads.
// In a non-REAPER host this query fails and we stay unconnected — the instrument
// still loads.
Steinberg::FUnknownPtr<Steinberg::IReaperHostApplication> reaper(context);
if (!reaper) return false;
hostApp_ = reaper.get();
// Resolve the ext-state functions by name. getReaperApi returns the same function
// pointers the extension resolves via rec->GetFunc; a null return means the symbol
// is unavailable (very old REAPER) — degrade gracefully.
// getReaperApi returns the same function pointers the extension resolves via
// rec->GetFunc; a null return means the symbol is unavailable (very old REAPER).
getProjExtState_ = reinterpret_cast<GetProjExtStateFn>(
reaper->getReaperApi("GetProjExtState"));
enumProjExtState_ = reinterpret_cast<EnumProjExtStateFn>(
reaper->getReaperApi("EnumProjExtState"));
// EnumProjects(-1, ...) yields the active project AND its .rpp path — the same call
// the persist shell (ext_state_io.cpp) uses, so the instrument derives the project
// directory identically.
// EnumProjects(-1, ...) yields the active project + its .rpp path — same convention
// the persist shell uses, so the instrument derives the project directory identically.
enumProjects_ = reinterpret_cast<EnumProjectsFn>(
reaper->getReaperApi("EnumProjects"));
// pS-usage: the (prefix-guarded) usage publish write + the track-identity pair the
// usage record stamps. All degrade to null gracefully — an old REAPER just never
// publishes usage (the extension then protects by bank references only).
// The (prefix-guarded) usage publish write + the track-identity pair it stamps. All
// degrade to null gracefully — an old REAPER never publishes usage.
setProjExtState_ = reinterpret_cast<SetProjExtStateFn>(
reaper->getReaperApi("SetProjExtState"));
getTrackGuid_ = reinterpret_cast<GetTrackGuidFn>(
@@ -87,23 +76,16 @@ bool ReaperBridge::connect(Steinberg::FUnknown* context) {
std::optional<std::string> ReaperBridge::readReasamplerExtState(const std::string& key) {
if (!getProjExtState_ || !hostApp_) return std::nullopt;
// Fetch the host project (getReaperParent(3) — project). Reads that live "reasampler"
// ext-state against the ACTIVE project the instrument was instantiated in, so it
// follows project switches for free (D6).
// getReaperParent(3) reads the live "reasampler" ext-state against the active project
// the instrument was instantiated in, so it follows project switches for free. A null
// project is legitimate (REAPER treats it as the current project) — pass it through
// rather than bailing; a fruitless read still yields nullopt to the caller.
auto* reaper = static_cast<Steinberg::IReaperHostApplication*>(hostApp_);
void* proj = reaper->getReaperParent(3);
// A null project is legitimate (e.g. instantiated before a project context exists);
// REAPER treats null as the current project for these calls, so we pass it through
// rather than bailing — but if the read yields nothing the caller sees nullopt.
// GetProjExtState writes into a caller buffer; the bank blob can be large (many
// samples), so grow the buffer until the value fits rather than risk a silent
// truncation. The retry policy is the SHARED pure wire::readProjExtStateGrowing
// (T2-04 — one loop for the
// extension's persist/usage reads and this bridge read; the rules cannot drift):
// absent (rv <= 0) and the >16 MB ceiling both fold to nullopt here, and a
// complete value still runs through decodeGetProjExtState (the stale/empty-buffer
// guard) exactly as before.
// The bank blob can be large, so grow the buffer until it fits rather than risk a
// silent truncation. The shared wire::readProjExtStateGrowing loop keeps this bridge
// read and the extension's persist/usage reads from drifting.
const auto read = wire::readProjExtStateGrowing(
[&](char* buf, int cap) {
return getProjExtState_(proj, kProjExtNamespace(), key.c_str(), buf, cap);
@@ -116,24 +98,21 @@ std::optional<std::string> ReaperBridge::readReasamplerExtState(const std::strin
bool ReaperBridge::writeUsageExtState(const std::string& usageKey,
const std::string& value) {
if (!setProjExtState_ || !hostApp_) return false;
// STRUCTURAL read-only-bank guard: this module writes usage keys and nothing else.
// A non-"rsusage_" key is a programming error upstream — refuse rather than widen
// the instrument's write surface (banks/view/tail/assign stay extension-owned).
// Read-only-bank guard: this module writes usage keys and nothing else. A non-
// "rsusage_" key is refused rather than widening the instrument's write surface
// (banks/view/tail/assign stay extension-owned).
const std::string prefix = kProjExtUsageKeyPrefix;
if (usageKey.compare(0, prefix.size(), prefix) != 0) return false;
auto* reaper = static_cast<Steinberg::IReaperHostApplication*>(hostApp_);
void* proj = reaper->getReaperParent(3); // null = current project (same as reads)
// SetProjExtState returns "the size of the state for this extname" (SDK ~6288) —
// after storing our non-empty value the namespace state is necessarily > 0, so a
// <= 0 return means the write did not land. Reported to the caller (the publish
// path retries on the next reload tick); a silently-dropped record would leave the
// instance's holds unprotected.
// SetProjExtState returns the size of the extname's state — after storing a
// non-empty value that's necessarily > 0, so <= 0 means the write did not land (the
// publish path retries next reload tick; a silent drop would leave holds unprotected).
const int rv =
setProjExtState_(proj, kProjExtNamespace(), usageKey.c_str(), value.c_str());
// Deliberately NO MarkProjectDirty: a usage change always accompanies a component-
// state change that already dirties the project; an idempotent load-time republish
// must not flag an untouched project as modified.
// Deliberately NO MarkProjectDirty: a usage change always rides a component-state
// change that already dirties the project.
return rv > 0;
}
@@ -151,11 +130,8 @@ std::string ReaperBridge::currentTrackGuid() {
std::string ReaperBridge::activeProjectDir() {
if (!enumProjects_) return {};
// idx=-1 is the current project tab; the out-buffer receives the full .rpp path,
// EMPTY for a never-saved project. Same call + convention as the persist shell; the pure
// projectDirOfRpp turns the .rpp path into the project directory (parent, forward-
// slashed) and keeps an unsaved project's empty path empty (no default-location
// fallback — the tool's invariant).
// idx=-1 is the current project tab; the out-buffer is empty for a never-saved
// project. projectDirOfRpp keeps that empty (no default-location fallback).
std::vector<char> buf(4096, '\0');
enumProjects_(-1, buf.data(), static_cast<int>(buf.size()));
return projectDirOfRpp(std::string(buf.data()));