Ξ-W2-T1: the resample bake chain — instrument renders, extension banks, one click re-points and resets
This commit is contained in:
@@ -44,15 +44,45 @@ public:
|
||||
// project or when unconnected. Not RT-safe.
|
||||
std::string activeProjectDir();
|
||||
|
||||
// Writes THIS INSTANCE's usage record: the ONE sanctioned instrument-side ext-state
|
||||
// write. `usageKey` MUST carry the "rsusage_" prefix (ext_keys.h's usageKeyFor); any
|
||||
// other key is refused, enforcing the read-only-bank invariant structurally (banks/
|
||||
// view/tail/assign stay unwritable from the instrument). Returns true iff written
|
||||
// (the SetProjExtState return is checked). NOT RT-safe — publish sites are the
|
||||
// off-audio-thread reload path only. Deliberately does NOT mark the project dirty: a
|
||||
// usage change always rides a component-state change that already does.
|
||||
// The instrument's TWO sanctioned ext-state write surfaces, each accepting exactly one
|
||||
// key prefix and refusing every other key. That structural refusal is what keeps the
|
||||
// read-only-BANK invariant intact — banks/view/tail/assign stay unwritable from here —
|
||||
// and neither payload is bank state. Both return true iff the write landed (the
|
||||
// SetProjExtState return is checked) and neither is RT-safe: the call sites are the
|
||||
// off-audio-thread reload path and the editor's UI tick.
|
||||
//
|
||||
// Neither marks the project dirty. A usage change always rides a component-state change
|
||||
// that already does; a bake request is transient and is cleared in the same tick.
|
||||
|
||||
// THIS INSTANCE's usage record. `usageKey` MUST carry the "rsusage_" prefix
|
||||
// (ext_keys.h's usageKeyFor).
|
||||
bool writeUsageExtState(const std::string& usageKey, const std::string& value);
|
||||
|
||||
// THIS INSTANCE's resample-bake request. `bakeKey` MUST carry the "rsbake_" prefix
|
||||
// (ext_keys.h's bakeKeyFor). An empty value clears the key.
|
||||
bool writeBakeExtState(const std::string& bakeKey, const std::string& value);
|
||||
|
||||
// --- Extension action invocation (the bake crossing) ------------------------------
|
||||
//
|
||||
// `commandName` is the NamedCommandLookup spelling — the registered command_id string
|
||||
// with a leading underscore, which the registration string itself does not carry.
|
||||
|
||||
// Whether the extension is loaded AND has registered this action. Used to paint the
|
||||
// affordance: an unavailable action must read Disabled, never enabled-then-refusing.
|
||||
bool extensionActionAvailable(const std::string& commandName);
|
||||
|
||||
// Fires the action against THIS INSTANCE's own project tab (getReaperParent(3)), not
|
||||
// whichever tab is focused. Returns false when the action is unregistered — the
|
||||
// invocation itself reports nothing, so a caller learns the result from the state the
|
||||
// action wrote, never from here. Must NOT be called from a mouse handler: it runs the
|
||||
// extension's whole bake landing synchronously, and the action re-points this instance.
|
||||
bool invokeExtensionAction(const std::string& commandName);
|
||||
|
||||
// The effective project tempo (BPM, quarter notes per minute) at the edit cursor of
|
||||
// this instance's own project. 0.0 when unconnected or unresolvable — the caller
|
||||
// refuses rather than substituting a tempo (no hardcoded rates or tempos in src/).
|
||||
double projectTempoBpm();
|
||||
|
||||
// The canonical GUID string of the track hosting this FX instance (same rendering as
|
||||
// the extension's track_guid::guidString, so usage records compare byte-equal
|
||||
// against its live-FX enumeration). Empty when unconnected or no track context (the
|
||||
@@ -70,9 +100,14 @@ private:
|
||||
// EnumProjects(-1, projfnOut, sz) -> active project + its .rpp path. idx=-1 (current
|
||||
// tab) follows the active project, same convention as the persist shell.
|
||||
using EnumProjectsFn = void* (*)(int idx, char* projfnOut, int projfnOut_sz);
|
||||
// Used ONLY by writeUsageExtState (prefix-guarded) — see the read-only-bank note there.
|
||||
// Used ONLY by the two prefix-guarded writers — see the read-only-bank note there.
|
||||
using SetProjExtStateFn = int (*)(void* proj, const char* extname, const char* key,
|
||||
const char* value);
|
||||
using NamedCommandLookupFn = int (*)(const char* commandName);
|
||||
using MainOnCommandExFn = void (*)(int command, int flag, void* proj);
|
||||
using GetCursorPositionExFn = double (*)(void* proj);
|
||||
using TimeMapGetTimeSigAtTimeFn = void (*)(void* proj, double time, int* numOut,
|
||||
int* denomOut, double* tempoOut);
|
||||
// Opaque-pointer signatures so the header stays SDK-type-free; the GUID* is passed
|
||||
// straight through, never dereferenced here.
|
||||
using GetTrackGuidFn = void* (*)(void* tr);
|
||||
@@ -85,6 +120,19 @@ private:
|
||||
SetProjExtStateFn setProjExtState_ = nullptr;
|
||||
GetTrackGuidFn getTrackGuid_ = nullptr;
|
||||
GuidToStringFn guidToString_ = nullptr;
|
||||
NamedCommandLookupFn namedCommandLookup_ = nullptr;
|
||||
MainOnCommandExFn mainOnCommandEx_ = nullptr;
|
||||
GetCursorPositionExFn getCursorPositionEx_ = nullptr;
|
||||
TimeMapGetTimeSigAtTimeFn timeMapGetTimeSigAtTime_ = nullptr;
|
||||
|
||||
// The one prefix guard both public writers route through, so the two cannot diverge
|
||||
// in how strictly they refuse a key.
|
||||
bool writeGuarded(const std::string& key, const std::string& value,
|
||||
const char* requiredPrefix);
|
||||
// 0 when the action is not registered (the extension is absent or older). REAPER's
|
||||
// documented "not found" return is 0 by convention only — the header does not state
|
||||
// it — so every caller treats 0 as unavailable and never as a valid command id.
|
||||
int lookupCommand(const std::string& commandName);
|
||||
};
|
||||
|
||||
} // namespace reasampler::vst
|
||||
|
||||
Reference in New Issue
Block a user