Cut shell/capture comment bloat ~33% (comments only, zero code change)
This commit is contained in:
@@ -1,34 +1,27 @@
|
||||
// insert.cpp — REAPER-facing placement shell (M6). See insert.h.
|
||||
// insert.cpp — REAPER-facing placement shell. See insert.h.
|
||||
//
|
||||
// Compiled into the reaper_reasampler MODULE. Includes reaper_plugin_functions.h
|
||||
// Compiled into the reaper_reasampler module. Includes reaper_plugin_functions.h
|
||||
// WITHOUT REAPERAPI_IMPLEMENT — main.cpp owns the API pointers; here they are
|
||||
// extern (CLAUDE.md §contract).
|
||||
// extern.
|
||||
//
|
||||
// THIS IS THE INTENDED PLACEMENT PATH. Unlike capture / bank_panel (which never
|
||||
// touch the arrange), insert deliberately adds items to the arrange — that is its
|
||||
// whole job (CONTEXT.md §load-bearing principle). It runs ONLY from its own action.
|
||||
// Unlike capture / bank_panel (which never touch the arrange), insert deliberately
|
||||
// adds items to the arrange — that is its whole job. Runs only from its own action.
|
||||
//
|
||||
// FLAGGED RUNTIME ASSUMPTIONS (semantics the header does not fully specify — must
|
||||
// be DAW-verified by Daniel post-merge; see the handoff):
|
||||
// A. InsertMedia base mode 0 ("add to current track") targets the track that is
|
||||
// currently the ONLY selected track. The header names the base target but does
|
||||
// not spell out how "current track" resolves at runtime. We force exactly one
|
||||
// selected track via SetOnlyTrackSelected before each InsertMedia call, which
|
||||
// is the most defensible interpretation; if REAPER uses a different notion of
|
||||
// "current" (e.g. last-focused, not last-selected), DAW-verify and adjust.
|
||||
// B. InsertMedia mode 0 inserts AT THE EDIT CURSOR. Placement at the edit cursor
|
||||
// is REAPER's documented convention for base modes 0/1 (the header does not
|
||||
// spell out an explicit "at edit cursor" bit). Flagged for DAW-verification.
|
||||
// C. InsertMedia ADVANCES the edit cursor to the end of the inserted media. We
|
||||
// reset the cursor to the snapshot position before EACH track's insert, so
|
||||
// assumption C's truth or falsity is irrelevant: we own the cursor reset.
|
||||
// D. SetEditCurPos(time, false, false) moves the cursor without scrolling the view
|
||||
// and without seeking the transport. The header lists the args as
|
||||
// (time, moveview, seekplay) — moveview=false and seekplay=false are the
|
||||
// non-disruptive choice; flagged in case the DAW shows otherwise.
|
||||
// E. SetOnlyTrackSelected deselects all tracks and selects exactly one. The header
|
||||
// doc-comment says "Set exactly one track selected, deselect all others" —
|
||||
// this is the strongest confirmation we have; flagged for DAW-verification.
|
||||
// Runtime assumptions the SDK header doesn't fully spell out (flagged, not yet
|
||||
// DAW-verified):
|
||||
// A. InsertMedia mode 0 ("add to current track") is assumed to target the sole
|
||||
// selected track — the header doesn't spell out how "current" resolves, so we
|
||||
// force exactly one selection via SetOnlyTrackSelected before each call. If
|
||||
// REAPER means last-focused rather than last-selected, this needs revisiting.
|
||||
// B. Mode 0 is assumed to insert at the edit cursor (REAPER's documented
|
||||
// convention for base modes 0/1; the header has no explicit "at cursor" bit).
|
||||
// C. InsertMedia may advance the cursor to the end of the inserted media; we
|
||||
// reset to the snapshot position before each track's insert, so this doesn't
|
||||
// matter either way.
|
||||
// D. SetEditCurPos(time, false, false) — moveview=false, seekplay=false — is
|
||||
// assumed to move the cursor without scrolling the view or the transport.
|
||||
// E. SetOnlyTrackSelected deselects all tracks and selects exactly one (per its
|
||||
// header doc-comment — the strongest confirmation we have here).
|
||||
|
||||
#include "shell/capture/insert.h"
|
||||
|
||||
@@ -57,7 +50,6 @@
|
||||
|
||||
namespace reasampler {
|
||||
|
||||
// Real-namespace-home using-declarations (Q-W6: the namespaces.h shim is retired).
|
||||
using capture::computeInsertMode;
|
||||
using capture::normalizeSlashes;
|
||||
using capture::resolveBankFile;
|
||||
@@ -67,11 +59,10 @@ namespace {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// The current project's directory (mirrors bank_panel/capture/persist). The bank
|
||||
// index stores relative paths; resolving a bank file needs the current .rpp dir.
|
||||
// FOLLOW-UP (already noted in panel_bank_ops.cpp): a shared "current project dir"
|
||||
// REAPER helper is a clean small refactor now that a fourth consumer exists — out
|
||||
// of scope for M6.
|
||||
// Mirrors bank_panel/capture/persist's own derivation; the bank index stores
|
||||
// relative paths, so resolving a file needs the current .rpp dir. A shared "current
|
||||
// project dir" helper would be a clean small refactor now that a fourth consumer
|
||||
// exists (also noted in panel_bank_ops.cpp) — out of scope here.
|
||||
std::string currentProjectDir() {
|
||||
std::vector<char> buf(4096, '\0');
|
||||
EnumProjects(-1, buf.data(), static_cast<int>(buf.size()));
|
||||
@@ -80,9 +71,8 @@ std::string currentProjectDir() {
|
||||
return normalizeSlashes(fs::path(rpp).parent_path().string());
|
||||
}
|
||||
|
||||
// Snapshot the user's currently-selected track set (ignores master, matches
|
||||
// CountSelectedTracks / GetSelectedTrack which both skip master). Returns the
|
||||
// tracks in selection order so we can restore the original state afterward.
|
||||
// Snapshot of the currently-selected track set (master is skipped, matching
|
||||
// CountSelectedTracks/GetSelectedTrack), in selection order, for restore later.
|
||||
std::vector<MediaTrack*> snapshotSelectedTracks() {
|
||||
const int n = CountSelectedTracks(nullptr); // nullptr = active project
|
||||
std::vector<MediaTrack*> tracks;
|
||||
@@ -92,12 +82,10 @@ std::vector<MediaTrack*> snapshotSelectedTracks() {
|
||||
return tracks;
|
||||
}
|
||||
|
||||
// Restore a previously-snapshotted track selection: deselect all (by setting the
|
||||
// first track alone) then re-select the full set. If the snapshot is empty we
|
||||
// leave all tracks deselected; no-op guard handles a completely empty project.
|
||||
// Restores a snapshotted selection: deselect all via the first track, then
|
||||
// re-select the rest. Empty snapshot -> no-op (guards an empty project).
|
||||
void restoreSelectedTracks(const std::vector<MediaTrack*>& tracks) {
|
||||
if (tracks.empty()) return;
|
||||
// Deselect all via the first track, then re-add the rest.
|
||||
SetOnlyTrackSelected(tracks[0]);
|
||||
for (size_t i = 1; i < tracks.size(); ++i)
|
||||
SetTrackSelected(tracks[i], true);
|
||||
@@ -109,9 +97,8 @@ InsertResult runInsert(ReaSamplerSession* session, const InsertRequest& request)
|
||||
InsertResult result;
|
||||
if (!session) { result.status = InsertStatus::NoSelection; return result; }
|
||||
|
||||
// WHO to target: the user's currently-selected track set. No-op (with a clear
|
||||
// console message) when nothing is selected — inserting without a target track
|
||||
// would create an unintended new track or behave unpredictably.
|
||||
// WHO: the user's selected track set. No-op when nothing is selected — inserting
|
||||
// without a target track would create an unintended track or behave unpredictably.
|
||||
const std::vector<MediaTrack*> selectedTracks = snapshotSelectedTracks();
|
||||
if (selectedTracks.empty()) {
|
||||
ShowConsoleMsg("ReaSampler insert: select a track first.\n");
|
||||
@@ -119,22 +106,20 @@ InsertResult runInsert(ReaSamplerSession* session, const InsertRequest& request)
|
||||
return result;
|
||||
}
|
||||
|
||||
// WHAT to place: the single focused sample from the panel. Multi-select is
|
||||
// deprioritized; take the first (or only) selected id. An empty panel selection
|
||||
// is a no-op — nothing to place.
|
||||
// WHAT: the single focused sample from the panel; multi-select is deprioritized,
|
||||
// so take the first id. Empty selection -> no-op.
|
||||
const std::vector<std::string> ids = bankPanelSelectedSampleIds();
|
||||
if (ids.empty()) { result.status = InsertStatus::NoSelection; return result; }
|
||||
const std::string& id = ids.front(); // focused / first selected — single sample
|
||||
|
||||
// WHERE the bank lives on disk. An unsaved project has no resolvable bank dir;
|
||||
// insert is a no-op rather than resolving against CWD (CLAUDE.md invariant).
|
||||
// WHERE: an unsaved project has no resolvable bank dir; no-op rather than
|
||||
// resolving against CWD.
|
||||
const std::string projectDir = currentProjectDir();
|
||||
if (projectDir.empty()) { result.status = InsertStatus::NoProject; return result; }
|
||||
|
||||
// Resolve the id against the bank the SELECTION came from — under B4's vertical
|
||||
// split the selection may live in the pool or a shown named bank, which is NOT
|
||||
// necessarily the active/capture-target bank. Fall back to the active bank when
|
||||
// the source id names no bank (defensive).
|
||||
// Resolve against the bank the selection came from — it may be the pool or a
|
||||
// shown named bank, not necessarily the active/capture-target bank. Fall back to
|
||||
// the active bank when the source id names no bank (defensive).
|
||||
const std::string srcBankId = bankPanelSelectedSourceBankId();
|
||||
const BankModel* srcIndex = session->book().index(srcBankId);
|
||||
const BankModel& bank = srcIndex ? *srcIndex : session->bank();
|
||||
@@ -153,16 +138,14 @@ InsertResult runInsert(ReaSamplerSession* session, const InsertRequest& request)
|
||||
// position for each track insert (and after the whole operation).
|
||||
const double cursorPos = GetCursorPosition();
|
||||
|
||||
// Wrap the whole placement (all tracks + selection/cursor save-restore) in ONE
|
||||
// undo block so a single undo removes every item and restores the state before
|
||||
// the action. Opened before the first InsertMedia, closed after the restore,
|
||||
// unconditionally — the block is always balanced.
|
||||
// One undo block around the whole placement (all tracks + selection/cursor
|
||||
// restore) so a single undo removes every item and restores prior state. Always
|
||||
// balanced — opened before the first insert, closed after the restore.
|
||||
Undo_BeginBlock2(nullptr);
|
||||
|
||||
// Insert onto EACH selected track at the SAME edit-cursor position (assumption B).
|
||||
// For each track: isolate it as the only selection so InsertMedia mode 0 targets
|
||||
// it unambiguously (assumption A + E), reset the cursor to the snapshot position
|
||||
// (assumption C cursor advance is irrelevant — we own the reset), then insert.
|
||||
// Insert onto each selected track at the same cursor position (assumption B): per
|
||||
// track, isolate it as the only selection (A + E), reset the cursor (C is
|
||||
// irrelevant since we own the reset), then insert.
|
||||
for (MediaTrack* track : selectedTracks) {
|
||||
SetOnlyTrackSelected(track); // assumption A + E
|
||||
SetEditCurPos(cursorPos, false, false); // assumption D
|
||||
@@ -170,14 +153,12 @@ InsertResult runInsert(ReaSamplerSession* session, const InsertRequest& request)
|
||||
++result.inserted;
|
||||
}
|
||||
|
||||
// Restore the user's original track selection and cursor position so the action
|
||||
// is non-destructive to their DAW state (non-negotiable per the brief).
|
||||
// Restore the original selection + cursor — non-destructive to the user's DAW state.
|
||||
restoreSelectedTracks(selectedTracks);
|
||||
SetEditCurPos(cursorPos, false, false);
|
||||
|
||||
// Label reflects the count and the conform choice so the undo history reads
|
||||
// clearly ("ReaSampler: insert on 2 tracks" etc.). extraflags -1 = UNDO_STATE_ALL
|
||||
// (superset: tracks, items, envelope points, project state).
|
||||
// Label reflects count + conform choice for a clear undo history. extraflags -1 =
|
||||
// UNDO_STATE_ALL (tracks, items, envelope points, project state).
|
||||
const std::string label =
|
||||
"ReaSampler: insert on " + std::to_string(result.inserted) +
|
||||
(result.inserted == 1 ? " track" : " tracks") +
|
||||
|
||||
Reference in New Issue
Block a user