feat(runtime): quiesce collision prefix replacements

This commit is contained in:
Erik 2026-08-01 16:05:46 +02:00
parent f05ed5c3cd
commit 99bf1751bb
3 changed files with 1897 additions and 40 deletions

View file

@ -35,6 +35,8 @@ public readonly record struct RuntimePhysicsOwnershipSnapshot(
int PendingCollisionSetPositionDispatchCount,
int PendingShadowSetPositionDispatchCount,
bool IsCollisionReportDispatching,
int CollisionPrefixQuiescenceCount,
int PendingCollisionPrefixProjectionCount,
int CollisionAdmissionCount,
int CollisionGenerationCount,
bool OwnsProductionDataCache,
@ -71,6 +73,8 @@ public readonly record struct RuntimePhysicsOwnershipSnapshot(
&& PendingCollisionSetPositionDispatchCount == 0
&& PendingShadowSetPositionDispatchCount == 0
&& !IsCollisionReportDispatching
&& CollisionPrefixQuiescenceCount == 0
&& PendingCollisionPrefixProjectionCount == 0
&& CollisionAdmissionCount == 0
&& CollisionGenerationCount == 0
&& OwnsProductionDataCache;
@ -1169,6 +1173,8 @@ public sealed class RuntimePhysicsState : IDisposable
collisionReports.PendingSetPositionDispatchCount,
Engine.ShadowObjects.PendingSetPositionDispatchCount,
collisionReports.IsDispatching,
setPosition.CollisionPrefixQuiescenceCount,
setPosition.PendingQuiescenceProjectionCount,
_collisionAdmissions.Count,
_collisionGenerations.Count,
ReferenceEquals(Engine.DataCache, DataCache),
@ -1901,6 +1907,64 @@ public sealed class RuntimePhysicsState : IDisposable
_spatialRoots.Clear();
}
internal RuntimeCollisionPrefixQuiescenceToken
BeginCollisionPrefixQuiescence(
uint landblockId,
ulong collisionGeneration,
bool includeOutdoorCells)
{
EnsureNotDisposed();
EnsureCollisionMutationThread();
uint canonical = CanonicalLandblock(landblockId);
if (canonical == 0u)
throw new ArgumentOutOfRangeException(nameof(landblockId));
return SetPosition.BeginCollisionPrefixQuiescence(
canonical,
collisionGeneration,
includeOutdoorCells);
}
internal bool TryAcquireCollisionPrefixMutationPermission(
in RuntimeCollisionPrefixQuiescenceToken token,
out RuntimeCollisionPrefixMutationPermission permission)
{
EnsureNotDisposed();
EnsureCollisionMutationThread();
return SetPosition.TryAcquireCollisionPrefixMutationPermission(
token,
out permission);
}
internal bool IsCollisionPrefixMutationPermissionCurrent(
in RuntimeCollisionPrefixMutationPermission permission)
{
EnsureNotDisposed();
EnsureCollisionMutationThread();
return SetPosition.IsCollisionPrefixMutationPermissionCurrent(
permission);
}
internal bool CancelCollisionPrefixQuiescence(
in RuntimeCollisionPrefixQuiescenceToken token,
ulong successorGeneration = 0UL,
bool successorReady = false)
{
EnsureNotDisposed();
EnsureCollisionMutationThread();
return SetPosition.CancelCollisionPrefixQuiescence(
token,
successorGeneration,
successorReady);
}
internal bool CompleteCollisionPrefixQuiescence(
in RuntimeCollisionPrefixMutationPermission permission)
{
EnsureNotDisposed();
EnsureCollisionMutationThread();
return SetPosition.CompleteCollisionPrefixQuiescence(permission);
}
public RuntimeCollisionAdmission BeginCollisionAdmission(
uint landblockId)
{
@ -2598,6 +2662,9 @@ public sealed class RuntimePhysicsState : IDisposable
private void AdvanceCollisionWorldAuthority() =>
_collisionWorldAuthority = checked(_collisionWorldAuthority + 1UL);
internal void AdvanceCollisionQuiescenceAuthority() =>
AdvanceCollisionWorldAuthority();
internal bool TrySealCollisionEvaluationAuthority(
in PhysicsSetPositionResult result,
ulong expectedCollisionWorldAuthority,
@ -2639,7 +2706,8 @@ public sealed class RuntimePhysicsState : IDisposable
}
foreach (uint prefix in prefixes)
{
if (_collisionAdmissions.ContainsKey(prefix))
if (_collisionAdmissions.ContainsKey(prefix)
|| SetPosition.IsCollisionPrefixQuiescing(prefix))
return false;
}
@ -2680,6 +2748,8 @@ public sealed class RuntimePhysicsState : IDisposable
{
if (generation.LandblockId == 0u
|| _collisionAdmissions.ContainsKey(generation.LandblockId)
|| SetPosition.IsCollisionPrefixQuiescing(
generation.LandblockId)
|| CollisionGenerationAuthority(generation.LandblockId)
!= generation.Generation)
{
@ -2706,6 +2776,8 @@ public sealed class RuntimePhysicsState : IDisposable
{
if (generation.LandblockId == 0u
|| _collisionAdmissions.ContainsKey(generation.LandblockId)
|| SetPosition.IsCollisionPrefixQuiescing(
generation.LandblockId)
|| CollisionGenerationAuthority(generation.LandblockId)
!= generation.Generation)
{

File diff suppressed because it is too large Load diff