using AcDream.App.Streaming; namespace AcDream.App.Tests.Streaming; public sealed class WorldRevealReadinessBarrierTests { private sealed class State { public bool RenderReady; /// /// Radius-aware override, so a test can distinguish "the Near /// sub-window is published" from "the whole Far window is published". /// public Func? RenderReadyByRadius; public bool SpawnCellReady; public bool TerrainReady; public bool CompositeReady; public bool Unhydratable; public int Invalidations; public int Preparations; public uint PreparedCell; public int PreparedRadius = -1; public int RenderNearRadius = -1; public int RenderFarRadius = -1; public int TerrainRadius = -1; /// /// The live streaming window the barrier derives from. Mutable so a /// test can prove the radii are re-read per evaluation rather than /// captured at construction (#280 T6 / P6). /// public StreamingRevealWindow Window { get; set; } = new(NearRadius: 1, FarRadius: 1); public WorldRevealReadinessBarrier Build() => new( revealWindow: () => Window, isRenderNeighborhoodReady: (cell, nearRadius, farRadius) => { RenderNearRadius = nearRadius; RenderFarRadius = farRadius; return RenderReadyByRadius?.Invoke(nearRadius, farRadius) ?? RenderReady; }, isSpawnCellReady: _ => SpawnCellReady, isTerrainNeighborhoodReady: (cell, radius) => { TerrainRadius = radius; return TerrainReady; }, areCompositeTexturesReady: () => CompositeReady, prepareCompositeTextures: (cell, radius) => { Preparations++; PreparedCell = cell; PreparedRadius = radius; }, invalidateCompositeTextures: () => Invalidations++, isSpawnClaimUnhydratable: _ => Unhydratable); } [Fact] public void Begin_InvalidatesPriorDestinationTextureReadiness() { var state = new State(); var barrier = state.Build(); barrier.Begin(); Assert.Equal(1, state.Invalidations); } /// /// #280: the outdoor gate is DERIVED from the live streaming window, never /// a constant. Every assertion below references the fake window's own /// input โ€” a test asserting a literal radius would reproduce the exact /// defect class this slice removes. /// [Theory] [InlineData(3, 8)] [InlineData(5, 15)] [InlineData(4, 12)] public void OutdoorRequiredWindow_IsTheLiveStreamingWindow( int nearRadius, int farRadius) { const uint outdoorCell = 0x11340021u; var window = new StreamingRevealWindow(nearRadius, farRadius); var state = new State { Window = window }; var barrier = state.Build(); Assert.False(barrier.IsReady(outdoorCell)); Assert.Equal(window.FarRadius, state.RenderFarRadius); Assert.Equal(window.NearRadius, state.RenderNearRadius); Assert.Equal(window.FarRadius, barrier.RequiredRenderRadius(outdoorCell)); Assert.Equal(window, barrier.RequiredWindow(outdoorCell)); } [Theory] [InlineData(3, 8)] [InlineData(5, 15)] public void IndoorRequiredWindow_IsZeroRegardlessOfTheStreamingWindow( int nearRadius, int farRadius) { const uint indoorCell = 0x11340100u; var state = new State { Window = new StreamingRevealWindow(nearRadius, farRadius), }; var barrier = state.Build(); Assert.Equal( new StreamingRevealWindow(0, 0), barrier.RequiredWindow(indoorCell)); Assert.Equal(0, barrier.RequiredRenderRadius(indoorCell)); } /// /// P6: the radii are runtime mutable through Settings, and retail re-arms /// the blocking prefetch at the NEW radius mid-hold /// (SmartBox::set_mid_radius @0x00453180). A window captured at /// construction would only misbehave when someone opens Settings during a /// portal, so it must be proven live. /// [Fact] public void RequiredWindow_IsRereadOnEveryEvaluationWithoutReconstruction() { const uint outdoorCell = 0x11340021u; var state = new State { Window = new StreamingRevealWindow(3, 8) }; var barrier = state.Build(); barrier.Evaluate(outdoorCell); Assert.Equal(8, state.RenderFarRadius); state.Window = new StreamingRevealWindow(5, 15); WorldRevealReadinessSnapshot second = barrier.Evaluate(outdoorCell); Assert.Equal(state.Window.FarRadius, state.RenderFarRadius); Assert.Equal(state.Window.NearRadius, state.RenderNearRadius); Assert.Equal(state.Window.FarRadius, second.RequiredRenderRadius); Assert.Equal(state.Window.NearRadius, second.RequiredNearRadius); } [Fact] public void OutdoorReveal_JoinsRenderTexturesAndTerrainOverTheDerivedWindow() { const uint outdoorCell = 0x11340021u; var state = new State { Window = new StreamingRevealWindow(4, 12) }; var barrier = state.Build(); Assert.False(barrier.IsReady(outdoorCell)); Assert.Equal(state.Window.FarRadius, state.RenderFarRadius); state.RenderReady = true; barrier.Prepare(outdoorCell); Assert.Equal(1, state.Preparations); Assert.Equal(outdoorCell, state.PreparedCell); // D3: the composite domain is entity-scoped and Far-tier builds carry // no entities, so composites warm over the NEAR radius only. Assert.Equal(state.Window.NearRadius, state.PreparedRadius); state.CompositeReady = true; Assert.False(barrier.IsReady(outdoorCell)); state.TerrainReady = true; Assert.True(barrier.IsReady(outdoorCell)); Assert.Equal(state.Window.FarRadius, state.TerrainRadius); } [Fact] public void IndoorReveal_UsesCenterRenderAndExactEnvCellPhysics() { const uint indoorCell = 0x11340100u; var state = new State { Window = new StreamingRevealWindow(4, 12), RenderReady = true, CompositeReady = true, TerrainReady = true, }; var barrier = state.Build(); barrier.Prepare(indoorCell); Assert.Equal(0, state.PreparedRadius); Assert.False(barrier.IsReady(indoorCell)); Assert.Equal(-1, state.TerrainRadius); state.SpawnCellReady = true; Assert.True(barrier.IsReady(indoorCell)); Assert.Equal(0, state.RenderNearRadius); Assert.Equal(0, state.RenderFarRadius); } [Fact] public void Prepare_WaitsForStaticMeshPublication() { var state = new State(); var barrier = state.Build(); barrier.Prepare(0x11340021u); Assert.Equal(0, state.Preparations); } /// /// The composite warmup TRIGGER is scoped to the composite DOMAIN. #280 /// widened the reveal gate to the whole Far window but left the domain at /// NearRadius; leaving the trigger on the gate would serialise every /// composite upload behind the last outer-ring landblock and lengthen the /// hold by the whole warmup duration for no readiness benefit. /// [Fact] public void Prepare_StartsWarmupOnceTheNearSubWindowIsPublished() { const uint outdoorCell = 0x11340021u; var state = new State { Window = new StreamingRevealWindow(4, 12), // Published out to the Near radius only โ€” the Far ring is still // streaming, which is the normal state for most of the hold. RenderReadyByRadius = (_, farRadius) => farRadius <= 4, }; var barrier = state.Build(); barrier.Prepare(outdoorCell); Assert.Equal(1, state.Preparations); Assert.Equal(state.Window.NearRadius, state.PreparedRadius); Assert.Equal(state.Window.NearRadius, state.RenderFarRadius); // ...and the gate itself has NOT opened: it still measures the whole // derived window, and composites are not ready yet either. Assert.False(barrier.IsReady(outdoorCell)); Assert.Equal(state.Window.FarRadius, state.RenderFarRadius); } /// /// The Near sub-window is a real precondition, not a formality: an /// unpublished destination neighbourhood still blocks warmup. /// [Fact] public void Prepare_StillWaitsWhenTheNearSubWindowIsIncomplete() { var state = new State { Window = new StreamingRevealWindow(4, 12), RenderReadyByRadius = (_, _) => false, }; state.Build().Prepare(0x11340021u); Assert.Equal(0, state.Preparations); } [Fact] public void ImpossibleClaim_CrossesExistingLoudRecoveryPath() { var state = new State { Unhydratable = true }; var barrier = state.Build(); barrier.Prepare(0x113401FFu); Assert.True(barrier.IsReady(0x113401FFu)); Assert.Equal(0, state.Preparations); Assert.Equal(-1, state.RenderFarRadius); } [Fact] public void Evaluate_ExposesTheCanonicalOutdoorDecisionWithoutRepeatingDomains() { const uint outdoorCell = 0x11340021u; var state = new State { Window = new StreamingRevealWindow(4, 12), RenderReady = true, CompositeReady = true, TerrainReady = true, }; WorldRevealReadinessSnapshot snapshot = state.Build().Evaluate(outdoorCell); Assert.Equal(outdoorCell, snapshot.DestinationCell); Assert.False(snapshot.IsIndoor); Assert.Equal(state.Window.FarRadius, snapshot.RequiredRenderRadius); Assert.Equal(state.Window.NearRadius, snapshot.RequiredNearRadius); Assert.True(snapshot.IsRenderNeighborhoodReady); Assert.True(snapshot.AreCompositeTexturesReady); Assert.True(snapshot.IsCollisionReady); Assert.True(snapshot.IsReady); Assert.Equal(-1, state.PreparedRadius); } [Fact] public void Evaluate_ShortCircuitsDownstreamDomainsUntilRenderPublication() { var state = new State { CompositeReady = true, TerrainReady = true, SpawnCellReady = true, }; WorldRevealReadinessSnapshot snapshot = state.Build().Evaluate(0x11340100u); Assert.False(snapshot.IsRenderNeighborhoodReady); Assert.False(snapshot.AreCompositeTexturesReady); Assert.False(snapshot.IsCollisionReady); Assert.False(snapshot.IsReady); Assert.Equal(-1, state.TerrainRadius); } /// /// The near arm demands Near-tier publication and can therefore never /// exceed the outer arm. A misconfigured window must clamp rather than /// hand IsRenderNeighborhoodResident an argument it rejects. /// [Fact] public void RequiredWindow_ClampsANearRadiusThatExceedsTheFarRadius() { var state = new State { Window = new StreamingRevealWindow(9, 4) }; var barrier = state.Build(); Assert.Equal( new StreamingRevealWindow(4, 4), barrier.RequiredWindow(0x11340021u)); } /// /// D5: the probe reproduces the pre-fix gate on the same binary so the /// connected route's A/B pair is a real comparison. It is a measurement /// override, never a user-facing prefetch knob (ยง3, T11). /// [Fact] public void RevealRadiusOverride_ReplacesTheDerivedWindowAndClampsTheNearArm() { var window = new StreamingRevealWindow(4, 12); Assert.Equal( window, StreamingDiagnostics.ApplyRevealRadiusOverride(window, null)); Assert.Equal( new StreamingRevealWindow(1, 1), StreamingDiagnostics.ApplyRevealRadiusOverride(window, 1)); Assert.Equal( new StreamingRevealWindow(4, 25), StreamingDiagnostics.ApplyRevealRadiusOverride(window, 25)); } /// /// The probe's parser floor is 1, not 0. A zero override makes /// RequiredWindow return far = 0 for an OUTDOOR destination, which /// Runtime's invalid-readiness-shape invariant rejects on every /// acknowledgement โ€” i.e. the probe would hang the exact A/B route it /// exists to measure. Reject it where it is read, not where it detonates. /// [Theory] [InlineData(null, null)] [InlineData("", null)] [InlineData("nonsense", null)] [InlineData("0", null)] [InlineData("-1", null)] [InlineData("1", 1)] [InlineData("12", 12)] public void RevealRadiusOverride_ParserRefusesRadiiRuntimeWouldReject( string? raw, int? expected) => Assert.Equal(expected, StreamingDiagnostics.ParseRadius(raw)); }