feat(runtime): own deferred set-position residence
This commit is contained in:
parent
e84a388e6f
commit
4c02ac4259
18 changed files with 5557 additions and 34 deletions
|
|
@ -28,6 +28,7 @@ public readonly record struct RuntimeEntityObjectOwnershipSnapshot(
|
|||
int EquipmentOwnerCount,
|
||||
int PendingMoveCount,
|
||||
int StreamSubscriberCount,
|
||||
int PlacementStreamSubscriberCount,
|
||||
long StreamDispatchFailureCount,
|
||||
bool HasLastStreamDispatchFailure,
|
||||
int PendingDispatchCount,
|
||||
|
|
@ -51,6 +52,7 @@ public readonly record struct RuntimeEntityObjectOwnershipSnapshot(
|
|||
&& EquipmentOwnerCount == 0
|
||||
&& PendingMoveCount == 0
|
||||
&& StreamSubscriberCount == 0
|
||||
&& PlacementStreamSubscriberCount == 0
|
||||
&& PendingDispatchCount == 0
|
||||
&& !IsDispatching
|
||||
&& !IsSessionClearInProgress;
|
||||
|
|
@ -95,10 +97,14 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
|
||||
public RuntimeEntityObjectLifetime(
|
||||
uint firstLocalEntityId = RuntimeEntityDirectory.FirstLocalEntityId,
|
||||
TimeProvider? timeProvider = null)
|
||||
TimeProvider? timeProvider = null,
|
||||
IGameRuntimeClock? gameClock = null)
|
||||
{
|
||||
Entities = new RuntimeEntityDirectory(firstLocalEntityId);
|
||||
Physics = new RuntimePhysicsState(Entities, timeProvider: timeProvider);
|
||||
Physics = new RuntimePhysicsState(
|
||||
Entities,
|
||||
timeProvider: timeProvider,
|
||||
gameClock: gameClock);
|
||||
Objects = new ClientObjectTable();
|
||||
// AP-129 (Campaign P Slice P4 review fix, 2026-07-30): the physics
|
||||
// entry-restriction gate (ObjectInfo.CheckEntryRestrictions) resolves
|
||||
|
|
@ -111,44 +117,51 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
EntityView = views.Entities;
|
||||
InventoryView = views.Inventory;
|
||||
Events = new RuntimeEntityObjectEventStream(Entities, Objects);
|
||||
Physics.SetPosition.BindEventStream(Events);
|
||||
}
|
||||
|
||||
internal RuntimeEntityObjectLifetime(
|
||||
PhysicsDataCache physicsDataCache,
|
||||
uint firstLocalEntityId = RuntimeEntityDirectory.FirstLocalEntityId,
|
||||
TimeProvider? timeProvider = null)
|
||||
TimeProvider? timeProvider = null,
|
||||
IGameRuntimeClock? gameClock = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(physicsDataCache);
|
||||
Entities = new RuntimeEntityDirectory(firstLocalEntityId);
|
||||
Physics = new RuntimePhysicsState(
|
||||
Entities,
|
||||
physicsDataCache,
|
||||
timeProvider);
|
||||
timeProvider,
|
||||
gameClock);
|
||||
Objects = new ClientObjectTable();
|
||||
Physics.Engine.Objects = Objects;
|
||||
var views = new RuntimeEntityObjectViews(Entities, Objects);
|
||||
EntityView = views.Entities;
|
||||
InventoryView = views.Inventory;
|
||||
Events = new RuntimeEntityObjectEventStream(Entities, Objects);
|
||||
Physics.SetPosition.BindEventStream(Events);
|
||||
}
|
||||
|
||||
internal RuntimeEntityObjectLifetime(
|
||||
PhysicsEngine physicsEngine,
|
||||
uint firstLocalEntityId = RuntimeEntityDirectory.FirstLocalEntityId,
|
||||
TimeProvider? timeProvider = null)
|
||||
TimeProvider? timeProvider = null,
|
||||
IGameRuntimeClock? gameClock = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(physicsEngine);
|
||||
Entities = new RuntimeEntityDirectory(firstLocalEntityId);
|
||||
Physics = new RuntimePhysicsState(
|
||||
Entities,
|
||||
physicsEngine,
|
||||
timeProvider);
|
||||
timeProvider,
|
||||
gameClock);
|
||||
Objects = new ClientObjectTable();
|
||||
Physics.Engine.Objects = Objects;
|
||||
var views = new RuntimeEntityObjectViews(Entities, Objects);
|
||||
EntityView = views.Entities;
|
||||
InventoryView = views.Inventory;
|
||||
Events = new RuntimeEntityObjectEventStream(Entities, Objects);
|
||||
Physics.SetPosition.BindEventStream(Events);
|
||||
}
|
||||
|
||||
public RuntimeEntityDirectory Entities { get; }
|
||||
|
|
@ -176,6 +189,7 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
Objects.EquipmentOwnerCount,
|
||||
Objects.PendingMoveCount,
|
||||
Events.SubscriberCount,
|
||||
Events.PlacementSubscriberCount,
|
||||
Events.DispatchFailureCount,
|
||||
Events.LastDispatchFailure is not null,
|
||||
Events.PendingDispatchCount,
|
||||
|
|
@ -421,6 +435,10 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
{
|
||||
EnsureNotDisposed();
|
||||
ArgumentNullException.ThrowIfNull(canonical);
|
||||
RuntimePlacementCancellationReceipt cancellation =
|
||||
Physics.SetPosition.Forget(
|
||||
canonical,
|
||||
releasePreparedMover: true);
|
||||
Physics.RemoveSpatialProjection(canonical);
|
||||
Entities.SetRemoteMotion(canonical, null);
|
||||
Entities.SetRemoteMotionBindingInProgress(canonical, false);
|
||||
|
|
@ -432,6 +450,7 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
Entities.SetPhysicsBodyAcquisitionInProgress(canonical, false);
|
||||
Entities.SetHasPartArray(canonical, false);
|
||||
Entities.ReleaseLocalId(canonical);
|
||||
Physics.SetPosition.PublishCancellation(cancellation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -510,6 +529,8 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
|
||||
Entities.RefreshSnapshot(canonical, accepted);
|
||||
Entities.AdvancePositionAuthority(canonical);
|
||||
RuntimePlacementCancellationReceipt cancellation =
|
||||
Physics.SetPosition.Forget(canonical);
|
||||
Entities.SuspendObjectClock(canonical);
|
||||
Entities.SetFullCell(canonical, 0u, 0u);
|
||||
Entities.ParentAttachments.EndChildProjection(update.Guid);
|
||||
|
|
@ -520,7 +541,8 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
() => acknowledgeProjection?.Invoke(canonical),
|
||||
RuntimeEntityChange.Withdrawn,
|
||||
() => canonical.PositionAuthorityVersion == positionVersion
|
||||
&& canonical.SpatialAuthorityVersion == spatialVersion);
|
||||
&& canonical.SpatialAuthorityVersion == spatialVersion,
|
||||
cancellation);
|
||||
}
|
||||
|
||||
public bool TryApplyCreateParent(
|
||||
|
|
@ -596,6 +618,8 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
return false;
|
||||
}
|
||||
|
||||
RuntimePlacementCancellationReceipt cancellation =
|
||||
Physics.SetPosition.Forget(canonical);
|
||||
Entities.SuspendObjectClock(canonical);
|
||||
Entities.SetFullCell(canonical, 0u, 0u);
|
||||
ulong spatialVersion = canonical.SpatialAuthorityVersion;
|
||||
|
|
@ -605,7 +629,8 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
RuntimeEntityChange.Withdrawn,
|
||||
() => canonical.PositionAuthorityVersion
|
||||
== positionAuthorityVersion
|
||||
&& canonical.SpatialAuthorityVersion == spatialVersion);
|
||||
&& canonical.SpatialAuthorityVersion == spatialVersion,
|
||||
cancellation);
|
||||
}
|
||||
|
||||
public bool TryApplyMotion(
|
||||
|
|
@ -764,6 +789,9 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
};
|
||||
}
|
||||
|
||||
RuntimePlacementCancellationReceipt cancellation = acceptedPosition
|
||||
? Physics.SetPosition.Forget(canonical)
|
||||
: default;
|
||||
Entities.RefreshSnapshot(
|
||||
canonical,
|
||||
snapshot,
|
||||
|
|
@ -793,7 +821,8 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
? RuntimeEntityChange.Rebucketed
|
||||
: RuntimeEntityChange.Updated,
|
||||
() => canonical.PositionAuthorityVersion == positionVersion
|
||||
&& canonical.SpatialAuthorityVersion == spatialVersion);
|
||||
&& canonical.SpatialAuthorityVersion == spatialVersion,
|
||||
cancellation);
|
||||
}
|
||||
|
||||
public bool CommitRebucket(
|
||||
|
|
@ -915,8 +944,13 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
&& active.Incarnation == delete.InstanceSequence
|
||||
&& Entities.RemoveActive(active))
|
||||
{
|
||||
RuntimePlacementCancellationReceipt cancellation =
|
||||
Physics.SetPosition.Forget(
|
||||
active,
|
||||
releasePreparedMover: true);
|
||||
retiredCanonical = active;
|
||||
Entities.RetainTeardown(active);
|
||||
Physics.SetPosition.PublishCancellation(cancellation);
|
||||
PublishEntity(
|
||||
removeRetainedObject
|
||||
? RuntimeEntityChange.Deleted
|
||||
|
|
@ -985,10 +1019,12 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
return Array.Empty<RuntimeEntityRecord>();
|
||||
|
||||
_sessionClearInProgress = true;
|
||||
Physics.SetPosition.ResetSession();
|
||||
Entities.BeginSessionClear();
|
||||
RuntimeEntityRecord[] active = Entities.ActiveRecords.ToArray();
|
||||
foreach (RuntimeEntityRecord canonical in active)
|
||||
{
|
||||
Physics.SetPosition.Forget(canonical);
|
||||
if (!Entities.RemoveActive(canonical))
|
||||
continue;
|
||||
Entities.RetainTeardown(canonical);
|
||||
|
|
@ -1119,6 +1155,8 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
|
||||
Entities.RefreshSnapshot(canonical, accepted);
|
||||
Entities.AdvancePositionAuthority(canonical);
|
||||
RuntimePlacementCancellationReceipt cancellation =
|
||||
Physics.SetPosition.Forget(canonical);
|
||||
ulong positionVersion = canonical.PositionAuthorityVersion;
|
||||
ulong spatialVersion = canonical.SpatialAuthorityVersion;
|
||||
return AcknowledgeProjectionAndPublish(
|
||||
|
|
@ -1126,7 +1164,8 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
() => acknowledgeProjection?.Invoke(canonical),
|
||||
RuntimeEntityChange.Updated,
|
||||
() => canonical.PositionAuthorityVersion == positionVersion
|
||||
&& canonical.SpatialAuthorityVersion == spatialVersion);
|
||||
&& canonical.SpatialAuthorityVersion == spatialVersion,
|
||||
cancellation);
|
||||
}
|
||||
|
||||
private void PublishEntity(
|
||||
|
|
@ -1138,8 +1177,12 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
RuntimeEntityRecord canonical,
|
||||
Action acknowledgeProjection,
|
||||
RuntimeEntityChange change,
|
||||
Func<bool> matchesCommittedMutation)
|
||||
Func<bool> matchesCommittedMutation,
|
||||
RuntimePlacementCancellationReceipt cancellation = default)
|
||||
{
|
||||
Physics.SetPosition.PublishCancellation(cancellation);
|
||||
if (!IsExpectedCanonical(canonical, matchesCommittedMutation))
|
||||
return false;
|
||||
try
|
||||
{
|
||||
acknowledgeProjection();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue