Q-W1 pt2: core/shell/app relocation + sub-namespaces; one concrete ui::Rect (LTRB fork retired); slot_map split from bank_book; BankIndex→BankModel; 59/59 green

This commit is contained in:
2026-07-28 20:48:56 -04:00
parent 67a41728f3
commit 847936f813
222 changed files with 2247 additions and 2079 deletions
+44 -43
View File
@@ -1,4 +1,4 @@
// Standalone tests for reasampler::vst::embed_strip — no VST3, no REAPER, no framework.
// Standalone tests for reasampler::instrument::ui::embed_strip — no VST3, no REAPER, no framework.
// Same fast assert loop as the sibling pure tests (editor_geometry et al.): assert the
// embedded TCP/MCP strip's layout math + zone hit-testing + level fill directly.
//
@@ -9,11 +9,12 @@
// on overlap, missing on uncovered keys and off-band, and rejecting a null/empty list;
// levelFillRect clamping 0..1 and its endpoints.
#include "../src/vst/embed_strip.h"
#include "../src/core/instrument/ui/embed_strip.h"
#include <cstdio>
using namespace reasampler::vst;
using namespace reasampler;
using namespace reasampler::instrument::ui;
static int g_fail = 0;
#define CHECK(cond) do { if(!(cond)) { \
@@ -24,34 +25,34 @@ static int g_fail = 0;
static void testLayoutNormalArea() {
// A comfortable inline strip: keymap band on top, thin level band pinned to the bottom.
const EmbedLayout L = layoutEmbed(300, 40);
CHECK(L.keymap.left == 0 && L.keymap.top == 0 && L.keymap.right == 300);
CHECK(L.levelBand.left == 0 && L.levelBand.right == 300);
CHECK(L.keymap.x == 0 && L.keymap.y == 0 && L.keymap.right() == 300);
CHECK(L.levelBand.x == 0 && L.levelBand.right() == 300);
// Level band is the fixed height at the very bottom; keymap fills the rest, contiguous.
CHECK(L.levelBand.height() == kEmbedLevelBandHeight);
CHECK(L.levelBand.bottom == 40);
CHECK(L.keymap.bottom == L.levelBand.top);
CHECK(L.keymap.height() == 40 - kEmbedLevelBandHeight);
CHECK(L.levelBand.height == kEmbedLevelBandHeight);
CHECK(L.levelBand.bottom() == 40);
CHECK(L.keymap.bottom() == L.levelBand.y);
CHECK(L.keymap.height == 40 - kEmbedLevelBandHeight);
}
static void testLayoutTinyAreaKeepsKeymap() {
// A very short area: the level band must yield so the keymap keeps its minimum, and no
// rect inverts.
const EmbedLayout L = layoutEmbed(300, 8);
CHECK(L.keymap.height() >= 0);
CHECK(L.levelBand.height() >= 0);
CHECK(L.keymap.bottom == L.levelBand.top);
CHECK(L.levelBand.bottom == 8);
CHECK(L.keymap.height >= 0);
CHECK(L.levelBand.height >= 0);
CHECK(L.keymap.bottom() == L.levelBand.y);
CHECK(L.levelBand.bottom() == 8);
// The keymap is not starved below its floor when the area allows it.
CHECK(L.keymap.height() >= kEmbedKeymapMinHeight || 8 < kEmbedKeymapMinHeight);
CHECK(L.keymap.height >= kEmbedKeymapMinHeight || 8 < kEmbedKeymapMinHeight);
}
static void testLayoutZeroArea() {
const EmbedLayout L = layoutEmbed(0, 0);
CHECK(L.keymap.width() <= 0 && L.keymap.height() <= 0);
CHECK(L.levelBand.width() <= 0 && L.levelBand.height() <= 0);
CHECK(L.keymap.width <= 0 && L.keymap.height <= 0);
CHECK(L.levelBand.width <= 0 && L.levelBand.height <= 0);
// Negative dimensions clamp to a zero-area, non-inverted rect.
const EmbedLayout N = layoutEmbed(-50, -50);
CHECK(N.keymap.right >= N.keymap.left && N.keymap.bottom >= N.keymap.top);
CHECK(N.keymap.right() >= N.keymap.x && N.keymap.bottom() >= N.keymap.y);
}
// --- zoneSegmentRect ----------------------------------------------------------
@@ -60,9 +61,9 @@ static void testZoneSegmentFullSpan() {
// A zone covering the whole keyboard spans the entire keymap band width.
const EmbedLayout L = layoutEmbed(256, 40);
const Rect r = zoneSegmentRect(L, 0, 127);
CHECK(r.left == L.keymap.left);
CHECK(r.right == L.keymap.right);
CHECK(r.top == L.keymap.top && r.bottom == L.keymap.bottom);
CHECK(r.x == L.keymap.x);
CHECK(r.right() == L.keymap.right());
CHECK(r.y == L.keymap.y && r.bottom() == L.keymap.bottom());
}
static void testAdjacentZonesTileSeamlessly() {
@@ -71,10 +72,10 @@ static void testAdjacentZonesTileSeamlessly() {
const EmbedLayout L = layoutEmbed(256, 40);
const Rect lo = zoneSegmentRect(L, 0, 59);
const Rect hi = zoneSegmentRect(L, 60, 127);
CHECK(lo.left == L.keymap.left);
CHECK(hi.right == L.keymap.right);
CHECK(lo.right == hi.left); // seamless tile — the load-bearing assertion
CHECK(lo.right == L.keymap.left + 60 * 2); // 60 keys * 2px
CHECK(lo.x == L.keymap.x);
CHECK(hi.right() == L.keymap.right());
CHECK(lo.right() == hi.x); // seamless tile — the load-bearing assertion
CHECK(lo.right() == L.keymap.x + 60 * 2); // 60 keys * 2px
}
static void testZoneSegmentClampsBadNotes() {
@@ -82,9 +83,9 @@ static void testZoneSegmentClampsBadNotes() {
// Out-of-range notes clamp into the band; an inverted zone (low > high) collapses to a
// zero-or-positive-width rect, never inverts.
const Rect over = zoneSegmentRect(L, -10, 200);
CHECK(over.left == L.keymap.left && over.right == L.keymap.right);
CHECK(over.x == L.keymap.x && over.right() == L.keymap.right());
const Rect inv = zoneSegmentRect(L, 100, 20);
CHECK(inv.right >= inv.left);
CHECK(inv.right() >= inv.x);
}
// --- zoneAtPoint --------------------------------------------------------------
@@ -95,31 +96,31 @@ static void testZoneAtPointHits() {
// A point inside the low zone's segment resolves to zone 0; inside the high zone, 1.
const Rect lo = zoneSegmentRect(L, 0, 59);
const Rect hi = zoneSegmentRect(L, 60, 127);
const int yMid = (L.keymap.top + L.keymap.bottom) / 2;
CHECK(zoneAtPoint(L, zones, 2, lo.left + 1, yMid) == 0);
CHECK(zoneAtPoint(L, zones, 2, hi.right - 1, yMid) == 1);
const int yMid = (L.keymap.y + L.keymap.bottom()) / 2;
CHECK(zoneAtPoint(L, zones, 2, lo.x + 1, yMid) == 0);
CHECK(zoneAtPoint(L, zones, 2, hi.right() - 1, yMid) == 1);
}
static void testZoneAtPointFirstMatchOnOverlap() {
const EmbedLayout L = layoutEmbed(256, 40);
// Two overlapping zones; the FIRST in order must win the contested keys.
const EmbedZone zones[2] = {{0, 127}, {40, 80}};
const int yMid = (L.keymap.top + L.keymap.bottom) / 2;
const int yMid = (L.keymap.y + L.keymap.bottom()) / 2;
const Rect contested = zoneSegmentRect(L, 40, 80);
CHECK(zoneAtPoint(L, zones, 2, contested.left + 1, yMid) == 0); // zone 0 wins
CHECK(zoneAtPoint(L, zones, 2, contested.x + 1, yMid) == 0); // zone 0 wins
}
static void testZoneAtPointMisses() {
const EmbedLayout L = layoutEmbed(256, 40);
const EmbedZone zones[1] = {{60, 72}}; // a narrow zone; most keys uncovered
const int yMid = (L.keymap.top + L.keymap.bottom) / 2;
const int yMid = (L.keymap.y + L.keymap.bottom()) / 2;
// A key left of the zone is uncovered -> -1.
CHECK(zoneAtPoint(L, zones, 1, L.keymap.left + 1, yMid) == -1);
CHECK(zoneAtPoint(L, zones, 1, L.keymap.x + 1, yMid) == -1);
// A point in the level band (below the keymap) is off the keymap -> -1.
CHECK(zoneAtPoint(L, zones, 1, L.levelBand.left + 4, L.levelBand.top) == -1);
CHECK(zoneAtPoint(L, zones, 1, L.levelBand.x + 4, L.levelBand.y) == -1);
// Empty / null list -> -1.
CHECK(zoneAtPoint(L, zones, 0, L.keymap.left + 1, yMid) == -1);
CHECK(zoneAtPoint(L, nullptr, 3, L.keymap.left + 1, yMid) == -1);
CHECK(zoneAtPoint(L, zones, 0, L.keymap.x + 1, yMid) == -1);
CHECK(zoneAtPoint(L, nullptr, 3, L.keymap.x + 1, yMid) == -1);
}
// --- levelFillRect ------------------------------------------------------------
@@ -127,16 +128,16 @@ static void testZoneAtPointMisses() {
static void testLevelFillClamps() {
const EmbedLayout L = layoutEmbed(200, 40);
// Zero / negative -> empty.
CHECK(levelFillRect(L, 0.0).width() <= 0);
CHECK(levelFillRect(L, -1.0).width() <= 0);
CHECK(levelFillRect(L, 0.0).width <= 0);
CHECK(levelFillRect(L, -1.0).width <= 0);
// Full / over-full -> the whole band width.
CHECK(levelFillRect(L, 1.0).width() == L.levelBand.width());
CHECK(levelFillRect(L, 5.0).width() == L.levelBand.width());
CHECK(levelFillRect(L, 1.0).width == L.levelBand.width);
CHECK(levelFillRect(L, 5.0).width == L.levelBand.width);
// Half -> ~half the band, pinned to the band's left and vertical extent.
const Rect half = levelFillRect(L, 0.5);
CHECK(half.left == L.levelBand.left);
CHECK(half.top == L.levelBand.top && half.bottom == L.levelBand.bottom);
CHECK(half.width() == L.levelBand.width() / 2);
CHECK(half.x == L.levelBand.x);
CHECK(half.y == L.levelBand.y && half.bottom() == L.levelBand.bottom());
CHECK(half.width == L.levelBand.width / 2);
}
int main() {