feat(runtime): atomically replace collision generations
This commit is contained in:
parent
99bf1751bb
commit
9b0f59bd1b
21 changed files with 2435 additions and 408 deletions
|
|
@ -336,7 +336,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
CommitPrepared(first.Physics, newer, prepared));
|
||||
|
||||
RuntimeCollisionAcknowledgement withdrawn =
|
||||
first.Physics.WithdrawCollision(0xA9B4FFFFu);
|
||||
CompleteWithdrawal(first.Physics, 0xA9B4FFFFu)
|
||||
.Acknowledgement;
|
||||
Assert.True(withdrawn.WasResident);
|
||||
Assert.True(withdrawn.Generation > completed.Generation);
|
||||
Assert.Equal(0, first.Physics.Engine.LandblockCount);
|
||||
|
|
@ -465,7 +466,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
uint owner = Assert.Single(SealPrepared(physics, admission, prepared));
|
||||
physics.Engine.ShadowObjects.UpdatePhysicsState(owner, 0x14u);
|
||||
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
Assert.Equal(15f, physics.Engine.SampleTerrainZ(1f, 1f));
|
||||
|
|
@ -561,6 +563,11 @@ public sealed class RuntimePhysicsStateTests
|
|||
Assert.True(sealSteps > ownerCount);
|
||||
Assert.True(workUnits > ownerCount);
|
||||
|
||||
Assert.False(physics.CommitCollisionGeneration(
|
||||
admission,
|
||||
prepared).Committed);
|
||||
_ = SealPrepared(physics, admission, prepared);
|
||||
|
||||
_ = GC.GetAllocatedBytesForCurrentThread();
|
||||
long before = GC.GetAllocatedBytesForCurrentThread();
|
||||
RuntimeCollisionGenerationCommit commit =
|
||||
|
|
@ -662,7 +669,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
}
|
||||
while (!seal.Completed);
|
||||
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
Assert.Equal(15f, physics.Engine.SampleTerrainZ(1f, 1f));
|
||||
|
|
@ -742,7 +750,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
break;
|
||||
}
|
||||
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
ShadowEntry[] entries = physics.Engine.ShadowObjects
|
||||
|
|
@ -841,7 +850,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
}
|
||||
while (!seal.Completed);
|
||||
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
ShadowEntry[] entries = physics.Engine.ShadowObjects
|
||||
|
|
@ -885,6 +895,10 @@ public sealed class RuntimePhysicsStateTests
|
|||
ShadowObjectRegistry shadowFacade = physics.Engine.ShadowObjects;
|
||||
int notifications = 0;
|
||||
physics.CollisionGenerationCommitted += _ => notifications++;
|
||||
Assert.False(physics.CommitCollisionGeneration(
|
||||
admission,
|
||||
prepared).Committed);
|
||||
_ = SealPrepared(physics, admission, prepared);
|
||||
_ = GC.GetAllocatedBytesForCurrentThread();
|
||||
long before = GC.GetAllocatedBytesForCurrentThread();
|
||||
RuntimeCollisionGenerationCommit commit =
|
||||
|
|
@ -1049,6 +1063,10 @@ public sealed class RuntimePhysicsStateTests
|
|||
PhysicsDataCache cacheFacade = physics.DataCache;
|
||||
CellGraph graphFacade = physics.DataCache.CellGraph;
|
||||
ShadowObjectRegistry shadowFacade = physics.Engine.ShadowObjects;
|
||||
Assert.False(physics.CommitCollisionGeneration(
|
||||
admission,
|
||||
prepared).Committed);
|
||||
_ = SealPrepared(physics, admission, prepared);
|
||||
_ = GC.GetAllocatedBytesForCurrentThread();
|
||||
long before = GC.GetAllocatedBytesForCurrentThread();
|
||||
RuntimeCollisionGenerationCommit commit =
|
||||
|
|
@ -1106,9 +1124,15 @@ public sealed class RuntimePhysicsStateTests
|
|||
_ = SealPrepared(physics, firstAdmission, first);
|
||||
_ = SealPrepared(physics, secondAdmission, second);
|
||||
|
||||
Assert.False(physics.CommitCollisionGeneration(
|
||||
firstAdmission,
|
||||
first).Committed);
|
||||
_ = SealPrepared(physics, firstAdmission, first);
|
||||
|
||||
_ = GC.GetAllocatedBytesForCurrentThread();
|
||||
long firstBefore = GC.GetAllocatedBytesForCurrentThread();
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
firstAdmission,
|
||||
first).Committed);
|
||||
long firstAllocated =
|
||||
|
|
@ -1118,10 +1142,15 @@ public sealed class RuntimePhysicsStateTests
|
|||
Assert.True(physics.Engine.IsLandblockTerrainResident(firstLandblock));
|
||||
Assert.False(physics.Engine.IsLandblockTerrainResident(secondLandblock));
|
||||
|
||||
_ = SealPrepared(physics, secondAdmission, second);
|
||||
Assert.False(physics.CommitCollisionGeneration(
|
||||
secondAdmission,
|
||||
second).Committed);
|
||||
_ = SealPrepared(physics, secondAdmission, second);
|
||||
_ = GC.GetAllocatedBytesForCurrentThread();
|
||||
long secondBefore = GC.GetAllocatedBytesForCurrentThread();
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
secondAdmission,
|
||||
second).Committed);
|
||||
long secondAllocated =
|
||||
|
|
@ -1172,7 +1201,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
_ = SealPrepared(physics, firstAdmission, first);
|
||||
_ = SealPrepared(physics, secondAdmission, second);
|
||||
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
firstAdmission,
|
||||
first).Committed);
|
||||
physics.Engine.ShadowObjects.UpdatePosition(
|
||||
|
|
@ -1185,7 +1215,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
seedCellId: 0x01010001u);
|
||||
|
||||
_ = SealPrepared(physics, secondAdmission, second);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
secondAdmission,
|
||||
second).Committed);
|
||||
Assert.Equal(12f, Assert.Single(
|
||||
|
|
@ -1256,11 +1287,13 @@ public sealed class RuntimePhysicsStateTests
|
|||
_ = SealPrepared(physics, northAdmission, northPrepared);
|
||||
_ = SealPrepared(physics, southAdmission, southPrepared);
|
||||
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
northAdmission,
|
||||
northPrepared).Committed);
|
||||
_ = SealPrepared(physics, southAdmission, southPrepared);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
southAdmission,
|
||||
southPrepared).Committed);
|
||||
Assert.True(physics.Engine.ShadowObjects.HasOwnerRowsInLandblock(
|
||||
|
|
@ -1394,7 +1427,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
|
||||
physics.Engine.UpdatePlayerCurrCell(secondCell);
|
||||
ObjCell oldRootCell = physics.DataCache.CellGraph.CurrCell!;
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
|
||||
|
|
@ -1454,7 +1488,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
destination,
|
||||
seedCellId: 0x02020001u);
|
||||
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
Assert.False(physics.Engine.ShadowObjects.HasOwnerRowsInLandblock(
|
||||
|
|
@ -1521,7 +1556,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
seedCellId: 0x02020001u,
|
||||
isStatic: false);
|
||||
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
ShadowEntry entry = Assert.Single(
|
||||
|
|
@ -1692,8 +1728,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
preparedThird,
|
||||
CollisionAssets(replacement));
|
||||
|
||||
Assert.True(physics.DemoteCollisionToTerrain(demoted).WasResident);
|
||||
Assert.True(physics.WithdrawCollision(withdrawn).WasResident);
|
||||
Assert.True(CompleteDemotion(physics, demoted).WasResident);
|
||||
Assert.True(CompleteWithdrawal(physics, withdrawn).WasResident);
|
||||
Assert.True(CommitPrepared(
|
||||
physics,
|
||||
third,
|
||||
|
|
@ -1745,7 +1781,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
}
|
||||
|
||||
_ = SealPrepared(physics, retiredAdmission, retiredPrepared);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
retiredAdmission,
|
||||
retiredPrepared).Committed);
|
||||
if (beginRebase)
|
||||
|
|
@ -1762,9 +1799,9 @@ public sealed class RuntimePhysicsStateTests
|
|||
}
|
||||
|
||||
if (withdraw)
|
||||
Assert.True(physics.WithdrawCollision(retired).WasResident);
|
||||
Assert.True(CompleteWithdrawal(physics, retired).WasResident);
|
||||
else
|
||||
Assert.True(physics.DemoteCollisionToTerrain(retired).WasResident);
|
||||
Assert.True(CompleteDemotion(physics, retired).WasResident);
|
||||
|
||||
Assert.True(CommitPrepared(
|
||||
physics,
|
||||
|
|
@ -1986,6 +2023,11 @@ public sealed class RuntimePhysicsStateTests
|
|||
while (!seal.Completed);
|
||||
Assert.Equal(ownerCount, worked);
|
||||
|
||||
Assert.False(physics.CommitCollisionGeneration(
|
||||
admission,
|
||||
prepared).Committed);
|
||||
_ = SealPrepared(physics, admission, prepared);
|
||||
|
||||
_ = GC.GetAllocatedBytesForCurrentThread();
|
||||
long before = GC.GetAllocatedBytesForCurrentThread();
|
||||
RuntimeCollisionGenerationCommit commit =
|
||||
|
|
@ -2050,7 +2092,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
survivingTarget,
|
||||
seedCellId: 0x02020001u,
|
||||
isStatic: false);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
survivingAdmission,
|
||||
surviving).Committed);
|
||||
Assert.Contains(
|
||||
|
|
@ -2097,7 +2140,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
0f,
|
||||
target,
|
||||
seedCellId: 0x01010001u);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
Assert.True(physics.Engine.ShadowObjects.HasOwnerRowsInLandblock(
|
||||
|
|
@ -2146,7 +2190,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
outside,
|
||||
seedCellId: 0x02020001u);
|
||||
physics.Engine.ShadowObjects.UpdatePhysicsState(ownerId, 0x55u);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
ShadowEntry entry = Assert.Single(
|
||||
|
|
@ -2217,7 +2262,7 @@ public sealed class RuntimePhysicsStateTests
|
|||
replacementAdmission,
|
||||
replacementPrepared);
|
||||
|
||||
Assert.True(physics.WithdrawCollision(retired).WasResident);
|
||||
Assert.True(CompleteWithdrawal(physics, retired).WasResident);
|
||||
Assert.False(physics.CommitCollisionGeneration(
|
||||
replacementAdmission,
|
||||
replacementPrepared).Committed);
|
||||
|
|
@ -2226,7 +2271,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
physics,
|
||||
replacementAdmission,
|
||||
replacementPrepared);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
replacementAdmission,
|
||||
replacementPrepared).Committed);
|
||||
Assert.False(physics.Engine.IsLandblockTerrainResident(retired));
|
||||
|
|
@ -2254,7 +2300,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
uint ordinal = index + 0x1000u;
|
||||
uint x = ordinal & 0xFFu;
|
||||
uint y = (ordinal >> 8) & 0xFFu;
|
||||
_ = physics.WithdrawCollision(
|
||||
_ = CompleteWithdrawal(
|
||||
physics,
|
||||
(x << 24) | (y << 16) | 0xFFFFu);
|
||||
}
|
||||
Assert.False(physics.CommitCollisionGeneration(
|
||||
|
|
@ -2272,7 +2319,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
Assert.True(++steps < 100_000);
|
||||
}
|
||||
while (!seal.Completed);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
}
|
||||
|
|
@ -2380,7 +2428,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
Assert.InRange(seal.WorkUnits, 0, 1);
|
||||
}
|
||||
while (!seal.Completed);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
Assert.Empty(physics.Engine.ShadowObjects.AllEntriesForDebug());
|
||||
|
|
@ -2448,7 +2497,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
seedCellId: 0x01010001u,
|
||||
isStatic: false);
|
||||
physics.Engine.ShadowObjects.Deregister(77u);
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
Assert.Empty(physics.Engine.ShadowObjects.AllEntriesForDebug());
|
||||
|
|
@ -2484,7 +2534,8 @@ public sealed class RuntimePhysicsStateTests
|
|||
seedCellId: 0x01010001u,
|
||||
isStatic: false);
|
||||
}
|
||||
Assert.True(physics.CommitCollisionGeneration(
|
||||
Assert.True(CompleteSealedCommit(
|
||||
physics,
|
||||
admission,
|
||||
prepared).Committed);
|
||||
Assert.Equal(
|
||||
|
|
@ -2903,7 +2954,55 @@ public sealed class RuntimePhysicsStateTests
|
|||
PreparedLandblockCollisionGeneration prepared)
|
||||
{
|
||||
_ = SealPrepared(physics, admission, prepared);
|
||||
return physics.CommitCollisionGeneration(admission, prepared);
|
||||
return CompleteSealedCommit(physics, admission, prepared);
|
||||
}
|
||||
|
||||
private static RuntimeCollisionGenerationCommit CompleteSealedCommit(
|
||||
RuntimePhysicsState physics,
|
||||
RuntimeCollisionAdmission admission,
|
||||
PreparedLandblockCollisionGeneration prepared)
|
||||
{
|
||||
for (int poll = 0; poll < 10_000; poll++)
|
||||
{
|
||||
RuntimeCollisionGenerationCommit commit =
|
||||
physics.CommitCollisionGeneration(admission, prepared);
|
||||
if (commit.Committed)
|
||||
return commit;
|
||||
if (!commit.EngineCommitted)
|
||||
_ = SealPrepared(physics, admission, prepared);
|
||||
}
|
||||
throw new InvalidOperationException(
|
||||
"Collision generation did not complete its Runtime mutation transaction.");
|
||||
}
|
||||
|
||||
private static RuntimeCollisionMutationResult CompleteDemotion(
|
||||
RuntimePhysicsState physics,
|
||||
uint landblockId)
|
||||
{
|
||||
for (int poll = 0; poll < 10_000; poll++)
|
||||
{
|
||||
RuntimeCollisionMutationResult result =
|
||||
physics.DemoteCollisionToTerrain(landblockId);
|
||||
if (result.Completed)
|
||||
return result;
|
||||
}
|
||||
throw new InvalidOperationException(
|
||||
"Collision demotion did not complete its Runtime mutation transaction.");
|
||||
}
|
||||
|
||||
private static RuntimeCollisionMutationResult CompleteWithdrawal(
|
||||
RuntimePhysicsState physics,
|
||||
uint landblockId)
|
||||
{
|
||||
for (int poll = 0; poll < 10_000; poll++)
|
||||
{
|
||||
RuntimeCollisionMutationResult result =
|
||||
physics.WithdrawCollision(landblockId);
|
||||
if (result.Completed)
|
||||
return result;
|
||||
}
|
||||
throw new InvalidOperationException(
|
||||
"Collision withdrawal did not complete its Runtime mutation transaction.");
|
||||
}
|
||||
|
||||
private static uint[] SealPrepared(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue