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 PendingCollisionSetPositionDispatchCount,
int PendingShadowSetPositionDispatchCount, int PendingShadowSetPositionDispatchCount,
bool IsCollisionReportDispatching, bool IsCollisionReportDispatching,
int CollisionPrefixQuiescenceCount,
int PendingCollisionPrefixProjectionCount,
int CollisionAdmissionCount, int CollisionAdmissionCount,
int CollisionGenerationCount, int CollisionGenerationCount,
bool OwnsProductionDataCache, bool OwnsProductionDataCache,
@ -71,6 +73,8 @@ public readonly record struct RuntimePhysicsOwnershipSnapshot(
&& PendingCollisionSetPositionDispatchCount == 0 && PendingCollisionSetPositionDispatchCount == 0
&& PendingShadowSetPositionDispatchCount == 0 && PendingShadowSetPositionDispatchCount == 0
&& !IsCollisionReportDispatching && !IsCollisionReportDispatching
&& CollisionPrefixQuiescenceCount == 0
&& PendingCollisionPrefixProjectionCount == 0
&& CollisionAdmissionCount == 0 && CollisionAdmissionCount == 0
&& CollisionGenerationCount == 0 && CollisionGenerationCount == 0
&& OwnsProductionDataCache; && OwnsProductionDataCache;
@ -1169,6 +1173,8 @@ public sealed class RuntimePhysicsState : IDisposable
collisionReports.PendingSetPositionDispatchCount, collisionReports.PendingSetPositionDispatchCount,
Engine.ShadowObjects.PendingSetPositionDispatchCount, Engine.ShadowObjects.PendingSetPositionDispatchCount,
collisionReports.IsDispatching, collisionReports.IsDispatching,
setPosition.CollisionPrefixQuiescenceCount,
setPosition.PendingQuiescenceProjectionCount,
_collisionAdmissions.Count, _collisionAdmissions.Count,
_collisionGenerations.Count, _collisionGenerations.Count,
ReferenceEquals(Engine.DataCache, DataCache), ReferenceEquals(Engine.DataCache, DataCache),
@ -1901,6 +1907,64 @@ public sealed class RuntimePhysicsState : IDisposable
_spatialRoots.Clear(); _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( public RuntimeCollisionAdmission BeginCollisionAdmission(
uint landblockId) uint landblockId)
{ {
@ -2598,6 +2662,9 @@ public sealed class RuntimePhysicsState : IDisposable
private void AdvanceCollisionWorldAuthority() => private void AdvanceCollisionWorldAuthority() =>
_collisionWorldAuthority = checked(_collisionWorldAuthority + 1UL); _collisionWorldAuthority = checked(_collisionWorldAuthority + 1UL);
internal void AdvanceCollisionQuiescenceAuthority() =>
AdvanceCollisionWorldAuthority();
internal bool TrySealCollisionEvaluationAuthority( internal bool TrySealCollisionEvaluationAuthority(
in PhysicsSetPositionResult result, in PhysicsSetPositionResult result,
ulong expectedCollisionWorldAuthority, ulong expectedCollisionWorldAuthority,
@ -2639,7 +2706,8 @@ public sealed class RuntimePhysicsState : IDisposable
} }
foreach (uint prefix in prefixes) foreach (uint prefix in prefixes)
{ {
if (_collisionAdmissions.ContainsKey(prefix)) if (_collisionAdmissions.ContainsKey(prefix)
|| SetPosition.IsCollisionPrefixQuiescing(prefix))
return false; return false;
} }
@ -2680,6 +2748,8 @@ public sealed class RuntimePhysicsState : IDisposable
{ {
if (generation.LandblockId == 0u if (generation.LandblockId == 0u
|| _collisionAdmissions.ContainsKey(generation.LandblockId) || _collisionAdmissions.ContainsKey(generation.LandblockId)
|| SetPosition.IsCollisionPrefixQuiescing(
generation.LandblockId)
|| CollisionGenerationAuthority(generation.LandblockId) || CollisionGenerationAuthority(generation.LandblockId)
!= generation.Generation) != generation.Generation)
{ {
@ -2706,6 +2776,8 @@ public sealed class RuntimePhysicsState : IDisposable
{ {
if (generation.LandblockId == 0u if (generation.LandblockId == 0u
|| _collisionAdmissions.ContainsKey(generation.LandblockId) || _collisionAdmissions.ContainsKey(generation.LandblockId)
|| SetPosition.IsCollisionPrefixQuiescing(
generation.LandblockId)
|| CollisionGenerationAuthority(generation.LandblockId) || CollisionGenerationAuthority(generation.LandblockId)
!= generation.Generation) != generation.Generation)
{ {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff