feat(runtime): commit dormant SetPosition activation

This commit is contained in:
Erik 2026-08-01 14:25:02 +02:00
parent 99f867f053
commit 5785a07b3e
13 changed files with 4674 additions and 111 deletions

View file

@ -707,6 +707,57 @@ public sealed class PlayerMovementController
internal bool IsRuntimeOwnedDormant => _publicationLifecycle
is PlayerMovementControllerPublicationLifecycle.RuntimeOwnedDormant;
internal bool IsRuntimePublished => _publicationLifecycle
is PlayerMovementControllerPublicationLifecycle.RuntimePublished;
private bool _dormantSetPositionGroundPhase;
internal void BeginDormantSetPositionGroundPhase()
{
if (!IsRuntimeOwnedDormant || _dormantSetPositionGroundPhase)
throw new InvalidOperationException(
"Dormant SetPosition ground phase requires one dormant Runtime owner.");
_dormantSetPositionGroundPhase = true;
}
internal void EndDormantSetPositionGroundPhase()
{
if (!_dormantSetPositionGroundPhase)
throw new InvalidOperationException(
"Dormant SetPosition ground phase is not active.");
_body.TransientState &= ~TransientStateFlags.Active;
_dormantSetPositionGroundPhase = false;
}
internal bool IsDormantSetPositionGroundPhaseActive =>
_dormantSetPositionGroundPhase;
internal void RefreshDormantRuntimePhysicsState(
PhysicsStateFlags state,
bool recalculateAcceleration)
{
if (!IsRuntimeOwnedDormant || _dormantSetPositionGroundPhase)
throw new InvalidOperationException(
"Only an idle dormant Runtime owner can refresh physics state.");
_body.State = state;
if (recalculateAcceleration)
_body.calc_acceleration();
}
internal void RefreshDormantRuntimeVector(
Vector3? velocity,
Vector3? omega)
{
if (!IsRuntimeOwnedDormant || _dormantSetPositionGroundPhase)
throw new InvalidOperationException(
"Only an idle dormant Runtime owner can refresh vector state.");
if (velocity is { } liveVelocity)
_body.set_velocity(liveVelocity);
if (omega is { } liveOmega)
_body.Omega = liveOmega;
_body.TransientState &= ~TransientStateFlags.Active;
}
internal void SealPublicationCandidate()
{
if (_publicationLifecycle
@ -738,7 +789,8 @@ public sealed class PlayerMovementController
{
if (_publicationLifecycle
is not PlayerMovementControllerPublicationLifecycle
.RuntimeOwnedDormant)
.RuntimeOwnedDormant
|| _dormantSetPositionGroundPhase)
{
throw new InvalidOperationException(
"Only a dormant Runtime-owned movement controller can be activated.");
@ -747,6 +799,30 @@ public sealed class PlayerMovementController
.RuntimePublished;
}
/// <summary>
/// Installs the already-committed Runtime SetPosition frame into the
/// controller's interpolation/cell sidecar without invoking the public
/// teleport path. The canonical body is written by Runtime first; this
/// method only makes the controller's private frame agree while it is
/// still dormant. It deliberately does not touch CellGraph, movement,
/// PositionManager, the object clock, or callbacks.
/// </summary>
internal void CommitRuntimeActivationFrame()
{
if (_publicationLifecycle
is not PlayerMovementControllerPublicationLifecycle
.RuntimeOwnedDormant
|| _dormantSetPositionGroundPhase)
{
throw new InvalidOperationException(
"Only a dormant Runtime-owned movement controller can accept its activation frame.");
}
_prevPhysicsPos = _body.Position;
_currPhysicsPos = _body.Position;
CellId = _body.CellPosition.ObjCellId;
}
internal void DiscardRuntimeCandidate()
{
if (_publicationLifecycle
@ -775,7 +851,8 @@ public sealed class PlayerMovementController
is PlayerMovementControllerPublicationLifecycle.StandalonePublished
or PlayerMovementControllerPublicationLifecycle
.CandidatePreparing
or PlayerMovementControllerPublicationLifecycle.RuntimePublished)
or PlayerMovementControllerPublicationLifecycle.RuntimePublished
|| IsRuntimeOwnedDormant && _dormantSetPositionGroundPhase)
{
return;
}
@ -807,6 +884,9 @@ public sealed class PlayerMovementController
if ((_body.State & PhysicsStateFlags.Static) != 0)
return;
if (IsRuntimeOwnedDormant && _dormantSetPositionGroundPhase)
return;
_objectClock.Activate();
_body.TransientState |= TransientStateFlags.Active;
}