view: assert the FX-park coalescing delay's debounce; correct four overclaiming doc/comment claims

Extracts parkReadyAt/parkIsReady as a tested pure fold per PLAN.md's phase
criterion; the rest is wording fixes — hitch bound, hazard width, forced-drain
scope, progressive CPU reclaim.
This commit is contained in:
2026-08-03 15:50:07 -04:00
parent 6e2128e937
commit 761125d0fe
4 changed files with 114 additions and 69 deletions
+33 -3
View File
@@ -4,9 +4,11 @@
// The properties under test: a mode switch leaves its per-FX offline work here,
// so a second switch arriving before the first drained must leave every track in
// the state the SECOND switch specifies — never the first's, never both replayed;
// a cancel must not strand the pre-park FX state it was the last record of; and
// the restore/park kind split must hold, restores detaching whole while parks
// stay queued across the ticks that apply them one FX at a time.
// a cancel must not strand the pre-park FX state it was the last record of; the
// restore/park kind split must hold, restores detaching whole while parks stay
// queued across the ticks that apply them one FX at a time; and the coalescing
// delay debounces from each enqueue's own time rather than firing once per the
// first.
#include "../src/shell/view/view_fx_park.h"
@@ -35,6 +37,32 @@ static const FxParkIntent* intentFor(const FxParkQueue& q, const std::string& gu
return nullptr;
}
// -- the coalescing gate ------------------------------------------------------
static void testCoalesceDebouncesFromEachEnqueuesOwnTimeNotTheFirst() {
double readyAt = parkReadyAt(0.0, 1.0);
CHECK(!parkIsReady(0.9, readyAt));
// A second enqueue arrives before the first's delay elapsed. A true debounce
// re-arms from THIS call's time; a one-shot would leave readyAt at 1.0 and
// this enqueue would have no effect.
readyAt = parkReadyAt(0.5, 1.0);
CHECK(!parkIsReady(1.0, readyAt)); // a one-shot would already be ready here
CHECK(parkIsReady(1.5, readyAt));
}
static void testRapidAToBToAStillCostsOneWaitFromTheLastFlip() {
// Three enqueues inside one delay window (A→B→A) still produce exactly one
// wait, measured from the LAST enqueue — not three separate timers and not
// one anchored to the first.
double readyAt = parkReadyAt(0.0, 1.0);
readyAt = parkReadyAt(0.3, 1.0);
readyAt = parkReadyAt(0.6, 1.0);
CHECK(!parkIsReady(1.5, readyAt));
CHECK(parkIsReady(1.6, readyAt));
}
// -- tests -------------------------------------------------------------------
static void testParkEnqueuesOneIntentCarryingNoOps() {
@@ -379,6 +407,8 @@ static void testAReEntrantParkCancelsOnlyWhatIsStillPending() {
}
int main() {
testCoalesceDebouncesFromEachEnqueuesOwnTimeNotTheFirst();
testRapidAToBToAStillCostsOneWaitFromTheLastFlip();
testParkEnqueuesOneIntentCarryingNoOps();
testParkReportsNothingCancelledWhenNoIntentWasPending();
testParkOnItsOwnPendingParkReportsNothingCancelled();