refactor(rendering): delete superseded visibility probes
Delete the callerless portal-BFS research graph and spent renderer probe families while retaining the production RetailFrameWalk path, terrain diagnostics, membership invariant, and walk transcript. Mutation evidence (all restored): 1. Restored PortalVisibilityBuilder type -> AppAssembly_ContainsNoSupersededPortalGraphTypes first failed Assert.Empty with AcDream.App.Rendering.PortalVisibilityBuilder. 2. Restored ACDREAM_PROBE_FACILITY_STAIRS -> ProductionSource_ContainsNoDeletedRendererProbe_AndRetainsWalkTranscriptProof first failed Assert.Empty on RenderingDiagnostics.cs. 3. Added a second RetailFrameWalk field -> WalkFrameOwners_AreUnique first failed Assert.Single with _frameWalk and _mutatedSecondFrameWalk. 4. Added OrderBy to OrderedStream -> OrderedWalkStream_HasNoCrossStreamReorder first failed Assert.DoesNotContain on OrderBy(. 5. Added IDatReaderWriter parameter -> FrameTimeWalkOwners_HaveNoRawDatDependency first failed Assert.Empty on RetailFrameWalk.MutatedRawDatParameter.
This commit is contained in:
parent
b77989c323
commit
bf53e2ad6e
82 changed files with 451 additions and 10108 deletions
|
|
@ -5,175 +5,24 @@ namespace AcDream.Core.Tests.Rendering;
|
|||
|
||||
public sealed class RenderingDiagnosticsTests
|
||||
{
|
||||
// Each flag-mutating test snapshots the IndoorAll state on entry and
|
||||
// restores it via try/finally. RenderingDiagnostics is a process-wide
|
||||
// static (env-var-initialized); without restoration a mutated state
|
||||
// leaks into other tests + into parallel test runs. Mirrors the
|
||||
// PhysicsDiagnosticsTests pattern at line 30-49.
|
||||
|
||||
[Fact]
|
||||
public void IndoorAll_True_TurnsAllFlagsOn()
|
||||
{
|
||||
bool initial = RenderingDiagnostics.IndoorAll;
|
||||
try
|
||||
{
|
||||
// Reset all flags off first to make the test deterministic
|
||||
// regardless of env-var state on the test runner.
|
||||
RenderingDiagnostics.ProbeIndoorWalkEnabled = false;
|
||||
RenderingDiagnostics.ProbeIndoorLookupEnabled = false;
|
||||
RenderingDiagnostics.ProbeIndoorUploadEnabled = false;
|
||||
RenderingDiagnostics.ProbeIndoorXformEnabled = false;
|
||||
RenderingDiagnostics.ProbeIndoorCullEnabled = false;
|
||||
|
||||
RenderingDiagnostics.IndoorAll = true;
|
||||
|
||||
Assert.True(RenderingDiagnostics.ProbeIndoorWalkEnabled);
|
||||
Assert.True(RenderingDiagnostics.ProbeIndoorLookupEnabled);
|
||||
Assert.True(RenderingDiagnostics.ProbeIndoorUploadEnabled);
|
||||
Assert.True(RenderingDiagnostics.ProbeIndoorXformEnabled);
|
||||
Assert.True(RenderingDiagnostics.ProbeIndoorCullEnabled);
|
||||
Assert.True(RenderingDiagnostics.IndoorAll);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderingDiagnostics.IndoorAll = initial;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IndoorAll_False_TurnsAllFlagsOff()
|
||||
{
|
||||
bool initial = RenderingDiagnostics.IndoorAll;
|
||||
try
|
||||
{
|
||||
RenderingDiagnostics.IndoorAll = true; // start from all-on
|
||||
RenderingDiagnostics.IndoorAll = false;
|
||||
|
||||
Assert.False(RenderingDiagnostics.ProbeIndoorWalkEnabled);
|
||||
Assert.False(RenderingDiagnostics.ProbeIndoorLookupEnabled);
|
||||
Assert.False(RenderingDiagnostics.ProbeIndoorUploadEnabled);
|
||||
Assert.False(RenderingDiagnostics.ProbeIndoorXformEnabled);
|
||||
Assert.False(RenderingDiagnostics.ProbeIndoorCullEnabled);
|
||||
Assert.False(RenderingDiagnostics.IndoorAll);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderingDiagnostics.IndoorAll = initial;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IndoorAll_OneOff_ReadsAsFalse()
|
||||
{
|
||||
bool initial = RenderingDiagnostics.IndoorAll;
|
||||
try
|
||||
{
|
||||
RenderingDiagnostics.IndoorAll = true;
|
||||
RenderingDiagnostics.ProbeIndoorCullEnabled = false; // flip one off
|
||||
Assert.False(RenderingDiagnostics.IndoorAll);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderingDiagnostics.IndoorAll = initial;
|
||||
}
|
||||
}
|
||||
[Theory]
|
||||
[InlineData(0x00000029ul, false)]
|
||||
[InlineData(0xA9B40029ul, false)]
|
||||
[InlineData(0x00000100ul, true)]
|
||||
[InlineData(0xA9B40105ul, true)]
|
||||
public void IsEnvCellId_DistinguishesOutdoorVsIndoorByLow16Bits(ulong id, bool expected)
|
||||
=> Assert.Equal(expected, RenderingDiagnostics.IsEnvCellId(id));
|
||||
|
||||
[Theory]
|
||||
[InlineData(0x00000029ul, false)] // outdoor cell 0x29 in 8x8 grid
|
||||
[InlineData(0xA9B40029ul, false)] // outdoor cell with landblock prefix
|
||||
[InlineData(0x00000100ul, true)] // indoor cell minimum
|
||||
[InlineData(0x00000105ul, true)] // typical Holtburg Inn interior
|
||||
[InlineData(0xA9B40105ul, true)] // indoor with landblock prefix
|
||||
[InlineData(0xA9B401FFul, true)] // indoor near top of range
|
||||
public void IsEnvCellId_DistinguishesOutdoorVsIndoorByLow16Bits(ulong id, bool expected)
|
||||
{
|
||||
Assert.Equal(expected, RenderingDiagnostics.IsEnvCellId(id));
|
||||
}
|
||||
|
||||
// ── Render inside/outside branch (retail RenderNormalMode is_player_outside) ──
|
||||
// The top-level render branch decides DrawInside vs DrawOutside. Retail
|
||||
// (SmartBox::RenderNormalMode 0x453aa0:92665) keys it on is_player_outside (the
|
||||
// PLAYER's cell, 0x451e80), NOT the camera cell. acdream previously branched on the
|
||||
// camera cell, so a chase camera lagging in a doorway while the player was already
|
||||
// outside took the DrawInside path and degenerated to a grey world + entities showing
|
||||
// through walls. These pin the player-keyed branch and loaded player-root requirement.
|
||||
|
||||
[Fact]
|
||||
public void ShouldRenderIndoor_PlayerOutside_CameraInside_ReturnsFalse()
|
||||
{
|
||||
// THE doorway-grey regression: the player stepped onto a landcell (0x...0031) but the
|
||||
// chase camera still resolves an interior EnvCell. Branch on the PLAYER → outdoor.
|
||||
Assert.False(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0xA9B40031u, renderRootResolved: true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldRenderIndoor_PlayerInside_CameraInside_ReturnsTrue()
|
||||
{
|
||||
Assert.True(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0xA9B40171u, renderRootResolved: true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldRenderIndoor_PlayerInside_RootNotLoaded_ReturnsFalse()
|
||||
{
|
||||
// Opposite lag (camera pulled outside while the player is inside): no viewer cell to
|
||||
// root DrawInside at → outdoor. Defensive; matches prior null-CameraCell behavior.
|
||||
Assert.False(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0xA9B40171u, renderRootResolved: false));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldRenderIndoor_PlayerOutside_CameraOutside_ReturnsFalse()
|
||||
{
|
||||
Assert.False(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0xA9B40031u, renderRootResolved: false));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldRenderIndoor_UnknownPlayerCell_TreatedAsOutside_ReturnsFalse()
|
||||
{
|
||||
// playerCellId == 0 (unresolved) → treat as outside (safe default: outdoor render).
|
||||
Assert.False(RenderingDiagnostics.ShouldRenderIndoor(playerCellId: 0u, renderRootResolved: true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProbePortalChurn_DefaultsFalse_WhenEnvUnset()
|
||||
{
|
||||
// Env var is absent in the test host, so the flag must default false (inert probe).
|
||||
Assert.False(AcDream.Core.Rendering.RenderingDiagnostics.ProbePortalChurnEnabled);
|
||||
}
|
||||
|
||||
// ── ACDREAM_DUMP_ENTITY parser (#119 decisive probe) ──────────────────
|
||||
|
||||
[Fact]
|
||||
public void ParseDumpEntityIds_NullOrEmpty_ReturnsEmptySet()
|
||||
{
|
||||
Assert.Empty(RenderingDiagnostics.ParseDumpEntityIds(null));
|
||||
Assert.Empty(RenderingDiagnostics.ParseDumpEntityIds(""));
|
||||
Assert.Empty(RenderingDiagnostics.ParseDumpEntityIds(" "));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseDumpEntityIds_CommaSeparatedWithPrefixes_ParsesAll()
|
||||
{
|
||||
var set = RenderingDiagnostics.ParseDumpEntityIds("0x020003F2,0x020005D8");
|
||||
Assert.Equal(2, set.Count);
|
||||
Assert.Contains(0x020003F2u, set);
|
||||
Assert.Contains(0x020005D8u, set);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseDumpEntityIds_NoPrefixMixedCaseAndWhitespace_Parses()
|
||||
{
|
||||
var set = RenderingDiagnostics.ParseDumpEntityIds(" 020003f2 , 0X020005D8 ");
|
||||
Assert.Equal(2, set.Count);
|
||||
Assert.Contains(0x020003F2u, set);
|
||||
Assert.Contains(0x020005D8u, set);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseDumpEntityIds_MalformedSegment_IgnoredNotFatal()
|
||||
{
|
||||
// A typo'd segment must not take the launch down — parse what's valid.
|
||||
var set = RenderingDiagnostics.ParseDumpEntityIds("0x020003F2,zzz,,0x");
|
||||
Assert.Single(set);
|
||||
Assert.Contains(0x020003F2u, set);
|
||||
}
|
||||
[InlineData(0xA9B40031u, true, false)]
|
||||
[InlineData(0xA9B40171u, true, true)]
|
||||
[InlineData(0xA9B40171u, false, false)]
|
||||
[InlineData(0u, true, false)]
|
||||
public void ShouldRenderIndoor_UsesPlayerCellAndResolvedRoot(
|
||||
uint playerCellId,
|
||||
bool renderRootResolved,
|
||||
bool expected)
|
||||
=> Assert.Equal(
|
||||
expected,
|
||||
RenderingDiagnostics.ShouldRenderIndoor(playerCellId, renderRootResolved));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,145 +0,0 @@
|
|||
// Phase A8 — visibility probe flag tests.
|
||||
// Phase U.2d (2026-05-30) — EmitVis formatter + cell-change gating tests.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using AcDream.Core.Rendering;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.Core.Tests.Rendering;
|
||||
|
||||
public class RenderingDiagnosticsVisibilityTests
|
||||
{
|
||||
// RenderingDiagnostics is a process-wide static (env-var-initialized) and
|
||||
// EmitVis keeps a private last-root-cell field. Both leak between tests +
|
||||
// parallel runs if not restored, and this codebase has documented
|
||||
// static-leak flakiness — so every test here snapshots ProbeVisibilityEnabled,
|
||||
// resets the cell tracker, and restores in finally. Mirrors the
|
||||
// RenderingDiagnosticsTests / PhysicsDiagnosticsTests pattern.
|
||||
|
||||
[Fact]
|
||||
public void ProbeVisibilityEnabled_CanBeToggled()
|
||||
{
|
||||
var prev = RenderingDiagnostics.ProbeVisibilityEnabled;
|
||||
try
|
||||
{
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = true;
|
||||
Assert.True(RenderingDiagnostics.ProbeVisibilityEnabled);
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = false;
|
||||
Assert.False(RenderingDiagnostics.ProbeVisibilityEnabled);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = prev;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProbeVisibilityEnabled_DefaultsToEnvVarPresence()
|
||||
{
|
||||
// The static initializer reads ACDREAM_PROBE_VIS == "1". Reconstruct the
|
||||
// documented default from the current env and assert the property's
|
||||
// *defined* default matches it. (We can't re-run the static initializer,
|
||||
// but the initial value is a pure function of the env var, so this pins
|
||||
// the documented contract without depending on the runner's env.)
|
||||
bool expected = Environment.GetEnvironmentVariable("ACDREAM_PROBE_VIS") == "1";
|
||||
|
||||
var prev = RenderingDiagnostics.ProbeVisibilityEnabled;
|
||||
try
|
||||
{
|
||||
RenderingDiagnostics.ResetVisibilityProbeForTests();
|
||||
// Drive the property to the env-derived default explicitly, then read
|
||||
// it back — this asserts the property faithfully stores the env value
|
||||
// (the same expression the field initializer uses).
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = expected;
|
||||
Assert.Equal(expected, RenderingDiagnostics.ProbeVisibilityEnabled);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = prev;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmitVis_NoOp_WhenProbeDisabled()
|
||||
{
|
||||
var prev = RenderingDiagnostics.ProbeVisibilityEnabled;
|
||||
var prevOut = Console.Out;
|
||||
try
|
||||
{
|
||||
RenderingDiagnostics.ResetVisibilityProbeForTests();
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = false;
|
||||
|
||||
using var sw = new StringWriter();
|
||||
Console.SetOut(sw);
|
||||
|
||||
RenderingDiagnostics.EmitVis(
|
||||
rootCellId: 0xA9B40105u,
|
||||
visibleCells: new uint[] { 0xA9B40105u, 0xA9B40164u },
|
||||
outsidePolyCount: 1,
|
||||
outsidePlaneCount: 4,
|
||||
perCellPlaneCounts: new Dictionary<uint, int> { [0xA9B40105u] = 0, [0xA9B40164u] = 4 },
|
||||
scissorFallbacks: 1);
|
||||
|
||||
Console.SetOut(prevOut);
|
||||
Assert.Equal(string.Empty, sw.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(prevOut);
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = prev;
|
||||
RenderingDiagnostics.ResetVisibilityProbeForTests();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmitVis_FiresOnceOnNewRoot_SuppressedOnUnchangedRoot()
|
||||
{
|
||||
var prev = RenderingDiagnostics.ProbeVisibilityEnabled;
|
||||
var prevOut = Console.Out;
|
||||
try
|
||||
{
|
||||
RenderingDiagnostics.ResetVisibilityProbeForTests();
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = true;
|
||||
|
||||
using var sw = new StringWriter();
|
||||
Console.SetOut(sw);
|
||||
|
||||
var cells = new uint[] { 0xA9B40105u, 0xA9B40164u };
|
||||
var perCell = new Dictionary<uint, int> { [0xA9B40105u] = 0, [0xA9B40164u] = 4 };
|
||||
|
||||
// First call on a fresh root → fires.
|
||||
RenderingDiagnostics.EmitVis(0xA9B40105u, cells, 1, 4, perCell, 0);
|
||||
// Same root again → suppressed (no-op).
|
||||
RenderingDiagnostics.EmitVis(0xA9B40105u, cells, 1, 4, perCell, 0);
|
||||
// New root → fires again.
|
||||
RenderingDiagnostics.EmitVis(0xA9B40164u, cells, 2, 8, perCell, 1);
|
||||
|
||||
Console.SetOut(prevOut);
|
||||
|
||||
string output = sw.ToString();
|
||||
string[] lines = output.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// Exactly two [vis] lines: one per distinct root transition.
|
||||
Assert.Equal(2, lines.Length);
|
||||
Assert.All(lines, l => Assert.StartsWith("[vis]", l.TrimStart()));
|
||||
Assert.Contains("root=0xA9B40105", lines[0]);
|
||||
Assert.Contains("root=0xA9B40164", lines[1]);
|
||||
|
||||
// Information-density spot checks on the first line.
|
||||
Assert.Contains("cells=2", lines[0]);
|
||||
Assert.Contains("0xA9B40105", lines[0]);
|
||||
Assert.Contains("0xA9B40164", lines[0]);
|
||||
Assert.Contains("polys=1", lines[0]);
|
||||
Assert.Contains("planes=4", lines[0]);
|
||||
Assert.Contains("fallbacks=0", lines[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(prevOut);
|
||||
RenderingDiagnostics.ProbeVisibilityEnabled = prev;
|
||||
RenderingDiagnostics.ResetVisibilityProbeForTests();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue