fix(physics): activate collision generations atomically

This commit is contained in:
Erik 2026-07-31 15:19:25 +02:00
parent 3e0f3b6206
commit be94bc9b06
18 changed files with 1402 additions and 80 deletions

View file

@ -88,6 +88,11 @@ public sealed class LandblockPhysicsPublisherTests
Assert.Equal(1, diagnostics.CellSurfaceCount);
Assert.Equal(1, diagnostics.PortalPlaneCount);
Assert.Equal(1, diagnostics.BuildingCount);
Assert.Null(fixture.Cache.CellGraph.GetVisible(envCellId));
Assert.Empty(fixture.Cache.BuildingIds);
fixture.Publisher.CompletePublication(receipt);
Assert.NotNull(fixture.Cache.CellGraph.GetVisible(envCellId));
BuildingPhysics building = Assert.Single(
fixture.Cache.BuildingIds.Select(id => fixture.Cache.GetBuilding(id)!));
@ -502,6 +507,11 @@ public sealed class LandblockPhysicsPublisherTests
LandblockPhysicsPublication secondReceipt = Begin(
fixture.Publisher,
Build(FirstLandblock, [moved]));
ShadowEntry duringPreparation = Assert.Single(
fixture.Engine.ShadowObjects.AllEntriesForDebug());
Assert.Equal(
first.Position + new Vector3(0f, 0f, 0.6f),
duringPreparation.Position);
fixture.Publisher.CompletePublication(secondReceipt);
Assert.Equal(1, fixture.Engine.LandblockCount);
@ -513,6 +523,27 @@ public sealed class LandblockPhysicsPublisherTests
Assert.Equal(2, fixture.Publisher.Diagnostics.CompleteCount);
}
[Fact]
public void CancelledPublicationDisposesOnlyItsPrivateCollisionGeneration()
{
var fixture = Fixture();
Publish(fixture.Publisher, Build(FirstLandblock));
Assert.True(fixture.Engine.IsLandblockTerrainResident(FirstLandblock));
LandblockPhysicsPublication pending = Begin(
fixture.Publisher,
Build(AdjacentLandblock));
Assert.False(pending.PreparedGeneration.IsDisposed);
pending.Dispose();
Assert.True(pending.PreparedGeneration.IsDisposed);
Assert.True(fixture.Engine.IsLandblockTerrainResident(FirstLandblock));
Assert.False(fixture.Engine.IsLandblockTerrainResident(AdjacentLandblock));
Assert.Throws<ObjectDisposedException>(() =>
fixture.Publisher.CompletePublication(pending));
}
[Fact]
public void NearReapply_RemovesOmittedStaticAcrossSeamAndPreservesNeighborOwner()
{
@ -760,6 +791,17 @@ public sealed class LandblockPhysicsPublisherTests
Assert.DoesNotContain("ShadowObjects.RefloodLandblock", source, StringComparison.Ordinal);
Assert.DoesNotContain("_physicsEngine.DemoteLandblockToTerrain", source, StringComparison.Ordinal);
Assert.DoesNotContain("_physicsEngine.RemoveLandblock", source, StringComparison.Ordinal);
string publisherSource = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Streaming",
"LandblockPhysicsPublisher.cs"));
Assert.DoesNotContain("_physicsDataCache.RemoveCellsForLandblock", publisherSource, StringComparison.Ordinal);
Assert.DoesNotContain("_physicsDataCache.RemoveBuildingsForLandblock", publisherSource, StringComparison.Ordinal);
Assert.DoesNotContain("_physicsEngine.ShadowObjects.Reflood", publisherSource, StringComparison.Ordinal);
Assert.Contains("CommitCollisionGeneration(", publisherSource, StringComparison.Ordinal);
}
private static void Publish(