Keep the extension's tick out of REAPER's own project load, and re-earn the park holds across one load
This commit is contained in:
@@ -1272,14 +1272,75 @@ static void testAStateLoadStopsTheDrainWhereItStandsRatherThanFinishingTheTrack(
|
||||
CHECK(q.stale());
|
||||
CHECK(!q.pending());
|
||||
|
||||
// ...and the stop belonged to that tick alone. The reloaded project's own drain writes.
|
||||
// ...and the stop belonged to that tick alone. The reloaded project's own drain writes —
|
||||
// but not before its holds are earned again: the abandon dropped them (it reached the
|
||||
// clock through the drain's own local, see FxReclaimQueue::run), so the re-park starts
|
||||
// its 3s from the first post-load tick rather than inheriting the pre-load observation.
|
||||
host.abandonAfterWrite = -1;
|
||||
q.adopt(derive(vm, {"{T1}", "{T2}"}));
|
||||
CHECK(q.run(host).writes == 0); // first post-load tick: the holds start here
|
||||
CHECK(!host.offlineAt("{T1}", 1));
|
||||
host.clock += kParkHoldMs;
|
||||
CHECK(q.run(host).writes == 2); // {T1}'s remaining slot, and {T2}'s whole chain
|
||||
CHECK(host.offlineAt("{T1}", 1));
|
||||
CHECK(host.offlineAt("{T2}", 0));
|
||||
}
|
||||
|
||||
static void testTheWholePostLoadReconvergenceIsOneSpanHoweverFarTheParkingGot() {
|
||||
// The acceptance property behind a Ctrl-Z landing anywhere in the drain: whatever
|
||||
// fraction of the parking had completed, everything the reloaded project owes rides
|
||||
// ONE span and costs ONE point. Two things carry it — the abandon dropping the holds,
|
||||
// so nothing writes on the tick that re-derives (the load's own wake), and the lazy
|
||||
// open being the drain's, so the many ticks that follow share one block.
|
||||
ViewModeModel vm = parkedDesignLeaves({{"{T1}", {"{FX-A}", "{FX-B}"}},
|
||||
{"{T2}", {"{FX-C}"}},
|
||||
{"{T3}", {"{FX-D}"}}});
|
||||
FakeHost host;
|
||||
host.chains["{T1}"] = onlineChain({"{FX-A}", "{FX-B}"});
|
||||
host.chains["{T2}"] = onlineChain({"{FX-C}"});
|
||||
host.chains["{T3}"] = onlineChain({"{FX-D}"});
|
||||
host.stepCostMs = 40.0; // over the offline budget: one track per tick, many ticks
|
||||
|
||||
UndoSpan span; // the switch's, still open when the undo arrives
|
||||
CHECK(span.begin(kProjA, "ReaSampler: activate Design view", 9));
|
||||
host.span = &span;
|
||||
|
||||
FxReclaimQueue q = queueOf(vm, {"{T1}", "{T2}", "{T3}"});
|
||||
q.run(host);
|
||||
host.clock += kParkHoldMs;
|
||||
host.reentrant = &q;
|
||||
host.abandonAfterWrite = 1; // Ctrl-Z one write in — the parking is part-done
|
||||
q.run(host);
|
||||
CHECK(!span.open()); // the terminator closed the switch's point over pre-load state
|
||||
host.reentrant = nullptr;
|
||||
host.abandonAfterWrite = -1;
|
||||
|
||||
// The reloaded model's reapply raises the wakeup and the queue re-derives.
|
||||
q.invalidate();
|
||||
q.adopt(derive(vm, {"{T1}", "{T2}", "{T3}"}));
|
||||
|
||||
int closes = 0;
|
||||
auto tick = [&]() {
|
||||
const ReclaimRunResult r = q.run(host);
|
||||
if (spanEndsAfter(r) && span.end()) ++closes;
|
||||
return r;
|
||||
};
|
||||
|
||||
CHECK(!tick().settled); // the holds start here, so this tick writes nothing at all
|
||||
CHECK(host.spanOpens == 0);
|
||||
CHECK(!span.open());
|
||||
CHECK(closes == 0);
|
||||
|
||||
host.clock += kParkHoldMs;
|
||||
int ticks = 0;
|
||||
while (!tick().settled && ++ticks < 20) {}
|
||||
CHECK(ticks >= 2); // it really did take several ticks to converge...
|
||||
CHECK(host.spanOpens == 1); // ...under ONE span, opened by the drain's first write
|
||||
CHECK(closes == 1); // ...closed exactly once, on the tick that settled
|
||||
CHECK(!span.open());
|
||||
CHECK(host.offlineAt("{T1}", 1) && host.offlineAt("{T2}", 0) && host.offlineAt("{T3}", 0));
|
||||
}
|
||||
|
||||
static void testARevertBetweenTicksLeavesTheLoopAsleepOnAStaleModel() {
|
||||
// File > Revert is the load that re-reads NOTHING: it keeps the same ReaProject, so the
|
||||
// session's identity poll answers NoOp, no reload follows and therefore no reapply
|
||||
@@ -1576,6 +1637,7 @@ int main() {
|
||||
testADrainNoSwitchOpenedMintsOnePointOfItsOwn();
|
||||
|
||||
testAStateLoadStopsTheDrainWhereItStandsRatherThanFinishingTheTrack();
|
||||
testTheWholePostLoadReconvergenceIsOneSpanHoweverFarTheParkingGot();
|
||||
testARevertBetweenTicksLeavesTheLoopAsleepOnAStaleModel();
|
||||
|
||||
testTheDirectionReadsOnlineWhileTheParksOwnOfflineWorkWaitsOutItsHold();
|
||||
|
||||
Reference in New Issue
Block a user