cb6b63cc88
REAPER may not expose the parent project pointer during plugin creation/setState, so the instrument would silently resolve no sample roots. Only that null-parent case now falls back to EnumProjects(-1); a resolved-but-unlisted or unsaved project still resolves nothing.
48 lines
2.3 KiB
C++
48 lines
2.3 KiB
C++
// sample_roots — where the instrument looks for a bank-relative sample: the directory of
|
|
// the project it LIVES IN, found by identity among the open projects, never the focused
|
|
// tab's. Pure: the shell enumerates REAPER's projects and reads files; this decides which
|
|
// project, which roots, and in what order.
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace reasampler::instrument::map {
|
|
|
|
// One enumerated project: its identity (an opaque ReaProject*, compared, never
|
|
// dereferenced) and its .rpp path, empty for a never-saved project.
|
|
struct ProjectTab {
|
|
const void* project = nullptr;
|
|
std::string rppPath;
|
|
};
|
|
|
|
// The directory of the project whose identity is `own`; empty when `own` is not among
|
|
// `open` or was never saved. Deliberately no fallback to any other project for a
|
|
// NON-NULL `own`: another project's bank folder can hold a same-named file, and playing
|
|
// it is the wrong-project bug this exists to close.
|
|
//
|
|
// `activeFallback` is used ONLY when `own` is null (REAPER may not expose
|
|
// getReaperParent(3) yet during plugin creation/setState) — then it stands in for `own`
|
|
// unchanged, so a still-null fallback (or one absent from `open`) resolves nothing exactly
|
|
// as a null `own` always did.
|
|
std::string ownProjectDir(const void* own, const std::vector<ProjectTab>& open,
|
|
const void* activeFallback = nullptr);
|
|
|
|
// The roots a bank-relative path is tried against, in order. Only the project directory
|
|
// today — the ordered list is the seam a later root (tried after it) extends. Empty when
|
|
// there is no project directory, which every caller treats as nothing to play.
|
|
std::vector<std::string> sampleRootCandidates(const std::string& projectDir);
|
|
|
|
using FileReader = std::function<std::vector<std::uint8_t>(const std::string& path)>;
|
|
|
|
// The bytes of `relativePath` resolved under the first root whose read yields any (a read
|
|
// that comes back empty falls through to the next root); empty when none does.
|
|
std::vector<std::uint8_t> readFromFirstRoot(const std::vector<std::string>& roots,
|
|
const std::string& relativePath,
|
|
const FileReader& read);
|
|
|
|
} // namespace reasampler::instrument::map
|