feat(S9/S8): bank-generation change-detection + instrument-side assignment reader
Extension stamps a monotonic bank_generation counter, bumped at content mutations; the VST3 instrument polls it off-thread on an editor timer and consumes assignment requests, refreshing playback hands-free.
This commit is contained in:
@@ -7,9 +7,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "bank_sync.h" // parseBankGeneration (S9 dirty-guard over the per-paint refresh)
|
||||
#include "editor_geometry.h" // Rect (shared with embed_strip)
|
||||
#include "embed_strip.h" // the pure strip layout + hit-test
|
||||
#include "ext_keys.h" // kProjExtBanksKey
|
||||
#include "ext_keys.h" // kProjExtBanksKey / kProjExtBankGenKey
|
||||
#include "reaper_bridge.h"
|
||||
#include "reasampler_processor.h"
|
||||
|
||||
@@ -91,6 +92,36 @@ void ReaSamplerEmbed::refresh() {
|
||||
if (selectedZone_ >= static_cast<int>(map_.zones.size())) selectedZone_ = -1;
|
||||
}
|
||||
|
||||
void ReaSamplerEmbed::maybeRefresh() {
|
||||
if (!processor_) { refresh(); return; } // clears state; cheap
|
||||
|
||||
// The performance map is a cheap in-process accessor (mutex + copy), and the editor may
|
||||
// have edited zones with NO bank-content change — always re-snapshot it so a zone edit
|
||||
// reflects immediately.
|
||||
map_ = processor_->performanceMap();
|
||||
if (selectedZone_ >= static_cast<int>(map_.zones.size())) selectedZone_ = -1;
|
||||
|
||||
// The EXPENSIVE part is the bank-blob bridge read (samples_). Gate it on the S9 bank-
|
||||
// generation stamp (a small ext-state read): only re-read the bank when the generation
|
||||
// changed since the last paint (a recapture / ingest / remove), or on the first paint
|
||||
// (lastSeenBankGeneration_ == -1). A pre-S9 project reads generation 0; the first paint
|
||||
// folds it and subsequent idle paints skip the bank read entirely.
|
||||
std::int64_t currentGen = lastSeenBankGeneration_;
|
||||
if (auto rawGen =
|
||||
processor_->bridge().readReasamplerExtState(reasampler::kProjExtBankGenKey)) {
|
||||
currentGen = parseBankGeneration(*rawGen);
|
||||
} else if (lastSeenBankGeneration_ < 0) {
|
||||
currentGen = 0; // unprimed + no stamp (pre-S9): treat as generation 0 for the first read
|
||||
}
|
||||
|
||||
if (lastSeenBankGeneration_ < 0 || currentGen != lastSeenBankGeneration_) {
|
||||
auto banks =
|
||||
processor_->bridge().readReasamplerExtState(reasampler::kProjExtBanksKey);
|
||||
samples_ = banks ? listSamples(*banks) : std::vector<SampleChoice>{};
|
||||
lastSeenBankGeneration_ = currentGen;
|
||||
}
|
||||
}
|
||||
|
||||
TPtrInt ReaSamplerEmbed::embed_message(int msg, TPtrInt parm2, TPtrInt parm3) {
|
||||
switch (msg) {
|
||||
case REAPER_FXEMBED_WM_IS_SUPPORTED:
|
||||
@@ -141,8 +172,10 @@ bool ReaSamplerEmbed::paint(TPtrInt bitmap, TPtrInt drawInfo) {
|
||||
if (w <= 0 || h <= 0) return false;
|
||||
|
||||
// Re-read live state each paint (UI thread) so the strip reflects keymap edits + bank
|
||||
// changes without its own timer — REAPER repaints the embed surface on its cadence.
|
||||
refresh();
|
||||
// changes without its own timer — REAPER repaints the embed surface on its cadence. S9
|
||||
// dirty-guard: maybeRefresh does the EXPENSIVE bank-blob read only when the bank generation
|
||||
// changed (the flagged S6 follow-up), always refreshing the cheap performance map.
|
||||
maybeRefresh();
|
||||
|
||||
// REAPER hands us its own bitmap sized to the embed area; draw directly into it (unlike
|
||||
// the editor, which owns a LICE_SysBitmap and BitBlt's). Origin is the bitmap's (0,0).
|
||||
|
||||
Reference in New Issue
Block a user