feat(version): V4 beta-in-isolation channel via -DREASAMPLER_CHANNEL
Compile-time channel flag forks a fully isolated reaper_reasampler_beta (namespace, command-id prefix, action names, dock ident, -beta render) from one auditable app_version definition. Stable identity byte-unchanged.
This commit is contained in:
+84
-9
@@ -1,24 +1,99 @@
|
||||
// app_version.cpp — implementation of the pure version-identity core (Phase V, V1).
|
||||
// See app_version.h for the contract. The version STRING itself comes from
|
||||
// version_generated.h (produced by CMake configure_file from the one REASAMPLER_VERSION
|
||||
// variable) — this TU just re-exports it and owns the pure parse/compare/classify logic.
|
||||
// app_version.cpp — implementation of the pure version-identity core (Phase V, V1 + V4).
|
||||
// See app_version.h for the contract. The version STRING and the channel bit both come
|
||||
// from version_generated.h (produced by CMake configure_file from the one
|
||||
// REASAMPLER_VERSION variable + the REASAMPLER_CHANNEL flag) — this TU re-exports them and
|
||||
// owns every pure derivation: the channel-qualified identity strings (V4) and the
|
||||
// parse/compare/classify logic (V1). No #ifdef forks leak beyond this file; the shells
|
||||
// consume the accessors below, so channel identity is one auditable definition.
|
||||
|
||||
#include "app_version.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "version_generated.h" // REASAMPLER_VERSION_STRING — configure_file'd from CMake
|
||||
#include "version_generated.h" // REASAMPLER_VERSION_STRING + REASAMPLER_CHANNEL_IS_BETA
|
||||
|
||||
namespace reasampler {
|
||||
|
||||
namespace {
|
||||
// The one channel predicate every derivation below branches on — the single point the
|
||||
// configure_file'd bit enters the pure module. constexpr so the branches fold at compile
|
||||
// time; the accessors still return by const ref for a stable shared instance.
|
||||
constexpr bool kIsBeta = (REASAMPLER_CHANNEL_IS_BETA != 0);
|
||||
} // namespace
|
||||
|
||||
Channel channel() { return kIsBeta ? Channel::Beta : Channel::Stable; }
|
||||
|
||||
bool isBeta() { return kIsBeta; }
|
||||
|
||||
const std::string& appVersion() {
|
||||
// Function-local static: initialized once from the compile-time string, returned by
|
||||
// const ref so callers share the one authoritative instance. The macro is the exact
|
||||
// CMake value, leading zero and all.
|
||||
static const std::string kVersion = REASAMPLER_VERSION_STRING;
|
||||
// The user-visible render. Stable: EXACTLY the CMake string (leading zero and all).
|
||||
// Beta: the same numeric string plus a plain "-beta" suffix (V2). Function-local
|
||||
// static so callers share one authoritative instance.
|
||||
static const std::string kVersion =
|
||||
kIsBeta ? std::string(REASAMPLER_VERSION_STRING) + "-beta"
|
||||
: std::string(REASAMPLER_VERSION_STRING);
|
||||
return kVersion;
|
||||
}
|
||||
|
||||
const std::string& stampVersion() {
|
||||
// The ext-state stamp value — the NUMERIC TRIPLE ONLY, IDENTICAL on both channels.
|
||||
// No "-beta" suffix: it must parse as Stamped on read-back (a suffixed stamp classifies
|
||||
// as Unknown), and stable's stamp stays byte-identical regardless of the channel build.
|
||||
// The channel is carried by extStateNamespace(), never baked into the stamp.
|
||||
static const std::string kStamp = REASAMPLER_VERSION_STRING;
|
||||
return kStamp;
|
||||
}
|
||||
|
||||
const std::string& extStateNamespace() {
|
||||
// Stable "reasampler" is byte-identical to the pre-V4 build; beta is isolated.
|
||||
// FOREVER-STABLE per channel.
|
||||
static const std::string kNs = kIsBeta ? "reasampler_beta" : "reasampler";
|
||||
return kNs;
|
||||
}
|
||||
|
||||
const std::string& commandIdPrefix() {
|
||||
// Stable prefix is byte-identical to every shipped command id; beta is a distinct
|
||||
// forever-family. FOREVER-STABLE per channel.
|
||||
static const std::string kPrefix =
|
||||
kIsBeta ? "CEREBELLUM_REASAMPLER_BETA_" : "CEREBELLUM_REASAMPLER_";
|
||||
return kPrefix;
|
||||
}
|
||||
|
||||
const std::string& actionDisplayPrefix() {
|
||||
// Actions-list legibility: two channels must be distinguishable by name. Trailing
|
||||
// space so callers append the action phrase directly.
|
||||
static const std::string kDisp = kIsBeta ? "ReaSampler beta: " : "ReaSampler: ";
|
||||
return kDisp;
|
||||
}
|
||||
|
||||
const std::string& binaryName() {
|
||||
static const std::string kName =
|
||||
kIsBeta ? "reaper_reasampler_beta" : "reaper_reasampler";
|
||||
return kName;
|
||||
}
|
||||
|
||||
const std::string& dockTitle() {
|
||||
static const std::string kTitle =
|
||||
kIsBeta ? "ReaSampler Bank beta" : "ReaSampler Bank";
|
||||
return kTitle;
|
||||
}
|
||||
|
||||
const std::string& dockIdent() {
|
||||
// Persisted dock-position ident — FOREVER-STABLE per channel (changing it strands the
|
||||
// saved dock slot). Beta qualified so the two panels do not fight over one slot.
|
||||
static const std::string kIdent =
|
||||
kIsBeta ? "reasampler_bank_panel_beta" : "reasampler_bank_panel";
|
||||
return kIdent;
|
||||
}
|
||||
|
||||
std::string channelCommandId(const std::string& suffix) {
|
||||
return commandIdPrefix() + suffix;
|
||||
}
|
||||
|
||||
std::string channelActionName(const std::string& phrase) {
|
||||
return actionDisplayPrefix() + phrase;
|
||||
}
|
||||
|
||||
std::optional<Version> parseVersion(const std::string& s) {
|
||||
// Split on '.' into exactly three non-empty all-digit components. No sign, no
|
||||
// whitespace, no trailing garbage. Leading zeros are allowed (0.9.01 parses to
|
||||
|
||||
Reference in New Issue
Block a user