refactor(streaming): extract landblock physics publisher

Move streamed terrain/cell/building and static collision publication behind a focused update-thread owner. Preserve retail publication order while making replacement and retirement exact by logical landblock ownership, including current-cell rebasing and adjacent-seam isolation.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-21 21:13:22 +02:00
parent acb6b34d01
commit 3613d393e6
7 changed files with 1538 additions and 546 deletions

View file

@ -151,4 +151,36 @@ public class PhysicsEngineResidencyTests
entry => entry.EntityId == dynamicId);
Assert.Equal(1, engine.ShadowObjects.RetainedRegistrationCount);
}
[Fact]
public void RemoveLandblock_RemovesOnlyItsCachedBuildings()
{
const uint landblockId = 0xA9B4FFFFu;
const uint retiredBuildingCell = 0xA9B40001u;
const uint adjacentBuildingCell = 0xAAB40001u;
var cache = new PhysicsDataCache();
var engine = new PhysicsEngine { DataCache = cache };
cache.RegisterBuildingForTest(
retiredBuildingCell,
Building(Matrix4x4.Identity));
cache.RegisterBuildingForTest(
adjacentBuildingCell,
Building(Matrix4x4.CreateTranslation(192f, 0f, 0f)));
engine.RemoveLandblock(landblockId);
Assert.Null(cache.GetBuilding(retiredBuildingCell));
Assert.NotNull(cache.GetBuilding(adjacentBuildingCell));
}
private static BuildingPhysics Building(Matrix4x4 transform)
{
Matrix4x4.Invert(transform, out Matrix4x4 inverse);
return new BuildingPhysics
{
WorldTransform = transform,
InverseWorldTransform = inverse,
Portals = Array.Empty<BldPortalInfo>(),
};
}
}

View file

@ -56,6 +56,21 @@ public class CellGraphTests
Assert.Null(g.GetVisible(0xA9B40014u));
}
[Fact]
public void RemoveLandblock_ClearsCurrentCellForRetiredPrefixOnly()
{
var g = new CellGraph();
var current = Env(0xA9B40174u);
g.Add(current);
g.CurrCell = current;
g.RemoveLandblock(0xAAB40000u);
Assert.Same(current, g.CurrCell);
g.RemoveLandblock(0xA9B40000u);
Assert.Null(g.CurrCell);
}
[Fact]
public void RemoveEnvCellsForLandblock_PreservesTerrain()
{
@ -69,6 +84,21 @@ public class CellGraphTests
Assert.IsType<LandCell>(g.GetVisible(0xA9B40014u));
}
[Fact]
public void RemoveEnvCellsForLandblock_ClearsOnlyMatchingIndoorCurrentCell()
{
var g = new CellGraph();
var current = Env(0xA9B40174u);
g.Add(current);
g.CurrCell = current;
g.RemoveEnvCellsForLandblock(0xAAB4FFFFu);
Assert.Same(current, g.CurrCell);
g.RemoveEnvCellsForLandblock(0xA9B4FFFFu);
Assert.Null(g.CurrCell);
}
[Fact]
public void Neighbor_ResolvesPortalOtherCellId()
{