The retail frame walk's world model now materializes from production landblock-build owners through the legal IDatReaderWriter seam, with zero frame wiring (FW3.2 roots the frame): - WalkCellFactory: WalkCell built in the SAME pass as LoadedCell (EnvCellLandblockBuild.BuildVisibilityCell) from the raw portal Flags/polygons/planes/stab lists already parsed there; stored as LoadedCell.Walk, committed atomically with the cell. The fixture-pinned decodes (inverse-0x2 portal side, 0xFFFF->0xFFFFFFFF exit widening) live here. - WalkBuildingFactory + WalkBuildingRegistry: the production WalkBuilding build (drawing BSP with PORT nodes, degrade ladder, portal sides/stab lists, sort center, model frame) from the SAME LandBlockInfo the streaming build already fetches, under the factory's existing DAT lock - closing the gap where BuildingLoader drops every walk field at load. - WalkLandscapeAssembler: the retail 51x51 viewer-centred grid (mid_radius 25) fed incrementally from landblock publish/retire; per-block z-slab (heightTable[max]+200 / [min]-1) computed worker-side in LandblockBuildFactory from the heights already in hand. O(1) SetViewer on same-block frames. - WalkProductionFrameContext: the walk's frame contexts over CellVisibility + WalkBuildingRegistry with a generic inverse-view-projection ray caster (rays feed cross products only - scale-free) and the znear=0.1 CY plane. - Publication: LandblockRenderPublisher owns both walk registries, publishing in the same AdvanceCompleteOne step as BuildingRegistry and retiring in RemoveBuildingRegistry - same commit, same retirement, no new ticket stage. Conformance: ALL TEN oracle fixtures replay identically through the PRODUCTION builders (WalkProductionWorldConformanceTests) - same signatures as the test adapter, first run. Known gap documented for FW3.2: far-tier landblocks carry no EnvCell transaction, so their z-slab never reaches the assembler. Suites: full Release build 0 warnings; Walk lane 186/1 skip; hermetic 6,738/0 (+24); RuntimeDatAccessArchitectureTests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
75 lines
2.6 KiB
C#
75 lines
2.6 KiB
C#
using System.Numerics;
|
|
using AcDream.App.Rendering.Walk;
|
|
|
|
namespace AcDream.App.Tests.Rendering.Walk;
|
|
|
|
/// <summary>Campaign FW3.1 — hermetic (no DAT) coverage of the walk's
|
|
/// production building registry: landblock-keyed publish/retire and the
|
|
/// O(1) reverse index <see cref="WalkProductionFrameContext"/> relies on.</summary>
|
|
public sealed class WalkBuildingRegistryTests
|
|
{
|
|
private static WalkBuildingFactory.Entry Entry(uint positionCellId) =>
|
|
new(new WalkBuilding { PositionCellId = positionCellId }, Matrix4x4.Identity, Matrix4x4.Identity);
|
|
|
|
[Fact]
|
|
public void Publish_MakesBuildingsFindableByLandblockAndByReference()
|
|
{
|
|
var registry = new WalkBuildingRegistry();
|
|
WalkBuildingFactory.Entry entry = Entry(0xA9B40001u);
|
|
|
|
registry.Publish(0xA9B4FFFFu, new[] { entry });
|
|
|
|
Assert.Same(entry, Assert.Single(registry.GetBuildings(0xA9B40100u)));
|
|
Assert.True(registry.TryGetEntry(entry.Building, out var found));
|
|
Assert.Same(entry, found);
|
|
Assert.Equal(1, registry.LandblockCount);
|
|
}
|
|
|
|
[Fact]
|
|
public void Publish_ReplacesThePreviousLandblockAndDropsItsReverseIndexEntries()
|
|
{
|
|
var registry = new WalkBuildingRegistry();
|
|
WalkBuildingFactory.Entry first = Entry(0xA9B40001u);
|
|
WalkBuildingFactory.Entry second = Entry(0xA9B40002u);
|
|
registry.Publish(0xA9B4FFFFu, new[] { first });
|
|
|
|
registry.Publish(0xA9B4FFFFu, new[] { second });
|
|
|
|
Assert.Same(second, Assert.Single(registry.GetBuildings(0xA9B4FFFFu)));
|
|
Assert.False(registry.TryGetEntry(first.Building, out _));
|
|
Assert.True(registry.TryGetEntry(second.Building, out _));
|
|
Assert.Equal(1, registry.LandblockCount);
|
|
}
|
|
|
|
[Fact]
|
|
public void Retire_RemovesTheLandblockAndItsReverseIndexEntries()
|
|
{
|
|
var registry = new WalkBuildingRegistry();
|
|
WalkBuildingFactory.Entry entry = Entry(0xA9B40001u);
|
|
registry.Publish(0xA9B4FFFFu, new[] { entry });
|
|
|
|
registry.Retire(0xA9B40100u); // any id sharing the landblock prefix
|
|
|
|
Assert.Empty(registry.GetBuildings(0xA9B4FFFFu));
|
|
Assert.False(registry.TryGetEntry(entry.Building, out _));
|
|
Assert.Equal(0, registry.LandblockCount);
|
|
}
|
|
|
|
[Fact]
|
|
public void Retire_UnknownLandblockIsANoOp()
|
|
{
|
|
var registry = new WalkBuildingRegistry();
|
|
|
|
registry.Retire(0xA9B4FFFFu);
|
|
|
|
Assert.Equal(0, registry.LandblockCount);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetBuildings_UnpublishedLandblockReturnsEmpty()
|
|
{
|
|
var registry = new WalkBuildingRegistry();
|
|
|
|
Assert.Empty(registry.GetBuildings(0xA9B4FFFFu));
|
|
}
|
|
}
|