Cut core/capture and core/version comment bloat ~45% (comments only, zero code change)
This commit is contained in:
@@ -6,25 +6,16 @@
|
||||
|
||||
namespace reasampler::capture {
|
||||
|
||||
// The content-identity hashes (hashBytes / hashWavContent) moved to wav_codec
|
||||
// (Q-W3, audit §4e) — one pure owner of the RIFF chunk walk, shared with the
|
||||
// layout parse so hashing and decoding cannot desynchronize.
|
||||
|
||||
std::string normalizeSlashes(const std::string& path) {
|
||||
std::string out = path;
|
||||
for (char& c : out) {
|
||||
if (c == '\\') c = '/';
|
||||
}
|
||||
// Strip a single trailing slash so joins do not double up. Preserve a lone
|
||||
// "/" (root) — stripping it would turn root into empty.
|
||||
// Strip a trailing slash but preserve a lone "/" (root).
|
||||
if (out.size() > 1 && out.back() == '/') {
|
||||
out.pop_back();
|
||||
}
|
||||
#ifdef _WIN32
|
||||
// Windows paths are case-insensitive. Fold to lowercase so that two paths
|
||||
// that differ only in drive-letter or component casing compare equal (e.g.
|
||||
// "C:/Foo/BAR.wav" == "c:/foo/bar.wav"). On macOS/Linux, exact case is
|
||||
// preserved (the filesystem is case-sensitive; folding would be wrong).
|
||||
for (char& c : out) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
#endif
|
||||
return out;
|
||||
@@ -39,8 +30,7 @@ std::string sanitizeStem(const std::string& baseName) {
|
||||
c == '-';
|
||||
out.push_back(keep ? static_cast<char>(c) : '_');
|
||||
}
|
||||
// Collapse to a stable default if nothing usable survived (e.g. all spaces).
|
||||
// A stem of only separators ('.', '_', '-') is also unhelpful as a name.
|
||||
// Collapse to a stable default if nothing alnum survived.
|
||||
bool hasAlnum = false;
|
||||
for (unsigned char c : out) {
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
|
||||
@@ -66,21 +56,16 @@ BankPaths deriveBankPaths(const std::string& projectDir,
|
||||
}
|
||||
const std::string fileName = stem + ".wav";
|
||||
|
||||
// Precondition: the capture shell must resolve a non-empty project directory
|
||||
// before calling this function. An empty projectDir would produce a bare
|
||||
// relative "reasampler_bank" path — the silent default-location fallback this
|
||||
// tool explicitly forbids. Assert in debug; leave absoluteDir empty in release
|
||||
// so any caller that ignores the precondition fails loudly at the render/stat
|
||||
// step rather than silently writing to CWD.
|
||||
// Precondition: caller must resolve a non-empty project directory — an
|
||||
// empty one would otherwise fall back to a bare relative path (forbidden).
|
||||
// Assert in debug; leave absoluteDir empty in release so a caller that
|
||||
// ignores it fails at the render/stat step, not silently onto CWD.
|
||||
assert(!dir.empty() && "deriveBankPaths: projectDir must not be empty");
|
||||
|
||||
BankPaths p;
|
||||
p.fileStem = stem; // stem only — REAPER appends extension
|
||||
p.fileName = fileName;
|
||||
p.relativePath = std::string(kBankSubfolder) + "/" + fileName;
|
||||
// absoluteDir intentionally omits a trailing slash (RENDER_FILE wants the
|
||||
// directory itself; RENDER_PATTERN supplies the file name separately).
|
||||
// Empty when precondition is violated (dir empty) — caller must not proceed.
|
||||
p.absoluteDir = dir.empty() ? std::string{}
|
||||
: dir + "/" + kBankSubfolder;
|
||||
return p;
|
||||
@@ -88,15 +73,12 @@ BankPaths deriveBankPaths(const std::string& projectDir,
|
||||
|
||||
std::string bankRelativeForName(const std::string& fileName) {
|
||||
if (fileName.empty()) return {};
|
||||
// The SAME expression deriveBankPaths uses for relativePath, kept in one place so
|
||||
// the two spellings can never drift (Phase R spelling-consistency invariant).
|
||||
// Same expression deriveBankPaths uses, so the two spellings can't drift.
|
||||
return std::string(kBankSubfolder) + "/" + fileName;
|
||||
}
|
||||
|
||||
std::string resolveBankFile(const std::string& projectDir,
|
||||
const std::string& relativePath) {
|
||||
// No default-location fallback (CLAUDE.md invariant): an empty project dir or
|
||||
// relative path yields empty, not a bare relative path resolved against CWD.
|
||||
if (projectDir.empty() || relativePath.empty()) {
|
||||
return {};
|
||||
}
|
||||
@@ -109,10 +91,7 @@ std::string resolveBankFile(const std::string& projectDir,
|
||||
}
|
||||
|
||||
std::string projectDirOfRpp(const std::string& rppPath) {
|
||||
// An unsaved project reports an empty .rpp path; keep it empty so downstream
|
||||
// resolution refuses (no default-location fallback). Mirrors the former persist shell's
|
||||
// projectDirOf exactly: parent_path of the .rpp, then normalizeSlashes.
|
||||
if (rppPath.empty()) return {};
|
||||
if (rppPath.empty()) return {}; // unsaved project: keep empty, no fallback
|
||||
std::string dir = std::filesystem::path(rppPath).parent_path().string();
|
||||
return normalizeSlashes(dir);
|
||||
}
|
||||
@@ -128,9 +107,7 @@ BankRelocation deriveRelocationPlan(const std::string& oldProjectDir,
|
||||
|
||||
r.oldBankDir = oldDir + "/" + kBankSubfolder;
|
||||
r.newBankDir = newDir + "/" + kBankSubfolder;
|
||||
// A Save (in place) leaves the project dir unchanged — nothing to relocate.
|
||||
// Only a Save-As to a different directory needs the bank moved.
|
||||
r.needed = (oldDir != newDir);
|
||||
r.needed = (oldDir != newDir); // Save-in-place leaves the dir unchanged
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -139,42 +116,16 @@ ProjectTransition classifyProjectTransition(bool sameProjectObject,
|
||||
const std::string& lastPath,
|
||||
const std::string& currentGuid,
|
||||
const std::string& currentPath) {
|
||||
// 1. The GUID is the identity of record and is checked FIRST. A different
|
||||
// stored GUID means a genuinely different project is active — Load ITS index.
|
||||
// This catches the regression that pointer-primary classification missed:
|
||||
// REAPER RECYCLES ReaProject* addresses across close/open, so a reopened /
|
||||
// new project can reuse the previous project's address (sameProjectObject ==
|
||||
// true) while carrying a different stored GUID. Deciding on the pointer alone
|
||||
// then returned NoOp/SaveAsRelocate and the bank never reloaded. The GUID is
|
||||
// immune to address recycling, so it leads. Also covers new/unsaved<->saved
|
||||
// transitions (one GUID empty, the other not) and switching between two
|
||||
// distinct saved projects.
|
||||
// See capture_paths.h for the GUID-primary rationale and rule order.
|
||||
if (currentGuid != lastGuid) {
|
||||
return ProjectTransition::Load;
|
||||
}
|
||||
|
||||
// From here currentGuid == lastGuid (they are equal; both may be empty for
|
||||
// unsaved projects). The pointer now disambiguates the same-GUID case.
|
||||
|
||||
// 2. Same GUID but a DIFFERENT object is a forked sibling: Save-As copied our
|
||||
// GUID onto a distinct project object. Load its (own) index; never relocate.
|
||||
// Two unsaved projects (both GUIDs empty, distinct objects) also land here —
|
||||
// Load, so switching between them installs the right in-memory state.
|
||||
if (!sameProjectObject) {
|
||||
return ProjectTransition::Load;
|
||||
return ProjectTransition::Load; // forked sibling: same GUID, different object
|
||||
}
|
||||
|
||||
// 3. Same object AND same GUID with a NEW path is a genuine Save-As (the object
|
||||
// identity is proven and the record identity is unchanged — only the .rpp
|
||||
// moved). Also the first save of an unsaved project (both GUIDs empty, old
|
||||
// path empty): SaveAsRelocate is safe there because deriveRelocationPlan
|
||||
// no-ops on the empty old dir (empty-GUID safety preserved) while poll()
|
||||
// mints a GUID.
|
||||
if (currentPath != lastPath) {
|
||||
return ProjectTransition::SaveAsRelocate;
|
||||
}
|
||||
|
||||
// 4. Same object, same GUID, same path — Save in place / idle tick.
|
||||
return ProjectTransition::NoOp;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user