Cut shell/actions, bank_ops, app comment bloat ~48% (comments only, zero code change)

This commit is contained in:
2026-07-29 20:49:31 -04:00
parent 1f24c4b095
commit 58c6d49261
19 changed files with 514 additions and 1074 deletions
+27 -56
View File
@@ -1,7 +1,5 @@
// instrument_drop_win — the REAPER shell for S17 drop-and-load. See instrument_drop_win.h.
//
// Compiled into the reaper_reasampler MODULE. Includes reaper_plugin_functions.h WITHOUT
// REAPERAPI_IMPLEMENT (main.cpp owns the pointers; here they are extern via the WANT list).
// instrument_drop_win.cpp — see instrument_drop_win.h. main.cpp owns the API
// pointers; this TU gets them extern via the WANT list.
#include "shell/actions/instrument_drop_win.h"
@@ -35,32 +33,24 @@ using wire::infoNamesFxHotspot;
namespace {
// Write `bytes` to a fresh uniquely-named .vstpreset in the OS temp dir and return its path;
// returns an empty path on any failure. The .vstpreset extension is load-bearing —
// TrackFX_SetPreset's full-path form is documented for .vstpreset files (VST3). The file is
// transient: the caller deletes it right after the SetPreset call.
// Writes `bytes` to a fresh uniquely-named .vstpreset in the OS temp dir; empty path
// on any failure. The .vstpreset extension is load-bearing — TrackFX_SetPreset's
// full-path form is documented for .vstpreset files (VST3). Transient: the caller
// deletes it right after the SetPreset call.
//
// The temp filename embeds the process ID so two concurrent REAPER instances (e.g. stable +
// beta) cannot collide in the shared OS temp dir, and one instance's cleanup cannot
// accidentally delete another's in-flight file.
//
// Non-throwing: every std::filesystem call uses the error_code overload. The whole body is
// wrapped in try/catch to guarantee no exception crosses the REAPER C callback boundary
// (the same discipline the prune shell uses — see prune_fs.cpp's non-throwing scan comment).
//
// Returns the path object (not a narrow string) so the caller can:
// (a) pass path.u8string() to TrackFX_SetPreset — UTF-8 on MSVC, not ACP-converted,
// so a temp dir with accented or CJK user-name bytes is handled correctly;
// (b) delete via the retained path object — not via re-parsing the narrow string —
// so the cleanup cannot leak if the conversion above were to round-trip incorrectly.
// Non-throwing: every std::filesystem call uses the error_code overload, and the
// whole body is try/catch-wrapped so no exception crosses the REAPER callback
// boundary. Returns the path object (not a narrow string) so the caller can pass
// path.u8string() to TrackFX_SetPreset (UTF-8, not ACP-converted) and delete via the
// same retained path — never a re-parsed narrow string.
std::filesystem::path writeTempPreset(const std::vector<std::uint8_t>& bytes) {
try {
static std::atomic<unsigned> counter{0};
std::error_code ec;
const std::filesystem::path dir = std::filesystem::temp_directory_path(ec);
if (ec) return {};
// PID in the name keeps files from distinct REAPER instances distinct in the shared
// temp dir — prevents cross-instance collisions and spurious post-apply deletions.
// PID in the name: two concurrent REAPER instances (stable + beta) cannot
// collide in the shared temp dir.
const std::string name =
"reasampler_drop_" + std::to_string(GetCurrentProcessId()) +
"_" + std::to_string(counter.fetch_add(1)) + ".vstpreset";
@@ -85,10 +75,8 @@ std::filesystem::path writeTempPreset(const std::vector<std::uint8_t>& bytes) {
FxDropTarget resolveFxDropTarget(int screenX, int screenY) {
FxDropTarget out;
char info[256] = {0};
// GetThingFromPoint returns the track under the point (may be null for a non-track thing)
// and fills `info` with what was hit. A non-empty info OR a non-null track means the point
// is over REAPER's own UI; a null track with an empty info means the pointer has left
// REAPER entirely (over another app / the desktop) — the OsDrag boundary.
// A non-empty info OR a non-null track means the point is over REAPER's own UI;
// a null track with empty info means the pointer has left REAPER entirely.
MediaTrack* track = GetThingFromPoint(screenX, screenY, info, sizeof(info));
out.track = track;
out.overReaperUi = (track != nullptr) || (info[0] != '\0');
@@ -101,46 +89,32 @@ FxDropTarget resolveFxDropTarget(int screenX, int screenY) {
bool loadInstrumentOntoTrack(MediaTrack* track, const std::vector<std::uint8_t>& presetBytes) {
if (!track || presetBytes.empty()) return false;
// Materialize the .vstpreset FIRST so an I/O failure leaves the track untouched (no FX
// added yet — nothing to roll back).
// Materialize the .vstpreset FIRST so an I/O failure leaves the track untouched
// (no FX added yet — nothing to roll back).
const std::filesystem::path presetPath = writeTempPreset(presetBytes);
if (presetPath.empty()) return false;
// The CHANNEL-correct FX name: "VST3:ReaSampler 9000" on stable, "VST3:ReaSampler 9000
// beta" on beta. Sourcing it from app_version::vstPluginName() (the same accessor the VST
// factory display name derives from) keeps the pairing invariant intact — a beta extension
// drops the beta VST, a stable extension the stable VST — with no literal to drift. (The
// preset's class ID forks by the same channel bit inside buildInstrumentDropPreset.)
// Channel-correct FX name ("VST3:ReaSampler 9000[ beta]") sourced from the same
// accessor the VST factory display name derives from, so the pairing invariant
// (beta extension <-> beta VST) has no literal to drift.
const std::string fxName = "VST3:" + vstPluginName();
// Negative `instantiate` => always create a NEW instance (verified in the header). recFX
// = false: a normal track FX chain instance, not a record/monitoring FX.
// Negative `instantiate` => always create a NEW instance. recFX = false: a
// normal track FX chain instance, not a record/monitoring FX.
const int fxIndex = TrackFX_AddByName(track, fxName.c_str(), /*recFX=*/false,
/*instantiate=*/-1);
bool ok = fxIndex >= 0;
// Apply the dragged capture's component state through the DOCUMENTED channel: a full
// .vstpreset path handed to TrackFX_SetPreset (SDK: "Full paths to .vstpreset files are
// also supported for VST3 plug-ins"). REAPER parses the Steinberg container and feeds the
// 'Comp' chunk to the instance's setState — the same bytes the instrument's own
// serializer produced (instrument_drop::buildInstrumentDropPreset ->
// sample_map::serializeComponentState). Unlike the former "vst_chunk" named-config-parm
// write, a failure here is REPORTED (false), not silently ignored.
//
// u8string() gives UTF-8 bytes on MSVC (not ACP-converted), so a temp dir under an
// accented or CJK user-name is handled correctly by REAPER's path APIs.
// u8string() gives UTF-8 bytes on MSVC (not ACP-converted), so a temp dir under
// an accented or CJK user-name is handled correctly by REAPER's path APIs.
if (ok) ok = TrackFX_SetPreset(track, fxIndex, presetPath.u8string().c_str());
// The preset file is transient regardless of outcome; delete via the retained path object
// (not a re-parsed narrow string) so cleanup cannot leak even if the UTF-8 conversion
// round-trip were incorrect.
std::error_code ec;
std::filesystem::remove(presetPath, ec);
std::filesystem::remove(presetPath, ec); // transient regardless of outcome
// All-or-nothing: if the preset apply fails, remove the FX instance we just
// added so the track is left exactly as it was.
if (!ok && fxIndex >= 0) {
// All-or-nothing: if the preset apply fails, remove the empty FX instance we just
// added so the track is left exactly as it was. TrackFX_Delete signature (verified
// in reaper_plugin_functions.h:7236): bool TrackFX_Delete(MediaTrack*, int fx).
TrackFX_Delete(track, fxIndex);
}
return ok;
@@ -149,11 +123,8 @@ bool loadInstrumentOntoTrack(MediaTrack* track, const std::vector<std::uint8_t>&
bool performInstrumentDrop(MediaTrack* track, const std::vector<std::uint8_t>& presetBytes) {
if (!track || presetBytes.empty()) return false;
// One undo point for the whole gesture (mirrors the bank-verb undo discipline). Both the
// FX add and the state apply are REAPER-undoable, so Ctrl-Z removes the instance cleanly.
Undo_BeginBlock2(nullptr);
const bool ok = loadInstrumentOntoTrack(track, presetBytes);
// The undo label reflects the placement-of-the-player framing (not a capture, not an insert).
Undo_EndBlock2(nullptr, "ReaSampler: drop capture onto FX chain", -1);
return ok;
}