feat(runtime): publish dormant local physics ownership
This commit is contained in:
parent
442cb8f97b
commit
22651c823d
10 changed files with 1617 additions and 25 deletions
|
|
@ -27,6 +27,7 @@ public sealed class RuntimeLocalPlayerMovementState
|
|||
{
|
||||
private PlayerMovementController? _controller;
|
||||
private PlayerMovementController? _preparingMotionOwner;
|
||||
private RuntimeLocalPlayerPhysicsPublicationState? _physicsPublication;
|
||||
private bool _autoRunActive;
|
||||
private bool _hasCommandInput;
|
||||
private MovementInput _commandInput;
|
||||
|
|
@ -41,7 +42,9 @@ public sealed class RuntimeLocalPlayerMovementState
|
|||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
if (ReferenceEquals(_controller, value))
|
||||
return;
|
||||
_controller?.RetireRuntimePublication();
|
||||
_controller = value;
|
||||
ControllerOwnershipEpoch++;
|
||||
Interlocked.Increment(ref _revision);
|
||||
}
|
||||
}
|
||||
|
|
@ -50,8 +53,13 @@ public sealed class RuntimeLocalPlayerMovementState
|
|||
public bool HasCommandInput => _hasCommandInput;
|
||||
public MovementInput CommandInput => _commandInput;
|
||||
public long Revision => Interlocked.Read(ref _revision);
|
||||
public ulong ControllerOwnershipEpoch { get; private set; }
|
||||
public IRuntimeMovementView View => this;
|
||||
|
||||
internal RuntimeLocalPlayerPhysicsPublicationState PhysicsPublication =>
|
||||
_physicsPublication ?? throw new InvalidOperationException(
|
||||
"The Runtime local-player physics publication owner is not bound.");
|
||||
|
||||
MotionInterpreter? IRuntimeLocalPlayerMotionSource.Motion =>
|
||||
_preparingMotionOwner?.Motion ?? _controller?.Motion;
|
||||
|
||||
|
|
@ -236,6 +244,7 @@ public sealed class RuntimeLocalPlayerMovementState
|
|||
public void ResetSession()
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
_physicsPublication?.ResetSession();
|
||||
bool changed =
|
||||
_autoRunActive
|
||||
|| _hasCommandInput
|
||||
|
|
@ -244,7 +253,12 @@ public sealed class RuntimeLocalPlayerMovementState
|
|||
_autoRunActive = false;
|
||||
_hasCommandInput = false;
|
||||
_commandInput = default;
|
||||
_controller = null;
|
||||
if (_controller is not null)
|
||||
{
|
||||
_controller.RetireRuntimePublication();
|
||||
_controller = null;
|
||||
ControllerOwnershipEpoch++;
|
||||
}
|
||||
_preparingMotionOwner = null;
|
||||
if (changed)
|
||||
Interlocked.Increment(ref _revision);
|
||||
|
|
@ -257,7 +271,9 @@ public sealed class RuntimeLocalPlayerMovementState
|
|||
_preparingMotionOwner is not null,
|
||||
_autoRunActive,
|
||||
_hasCommandInput,
|
||||
Revision);
|
||||
Revision,
|
||||
ControllerOwnershipEpoch,
|
||||
_physicsPublication?.CaptureOwnership() ?? default);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
@ -266,12 +282,46 @@ public sealed class RuntimeLocalPlayerMovementState
|
|||
_autoRunActive = false;
|
||||
_hasCommandInput = false;
|
||||
_commandInput = default;
|
||||
_controller = null;
|
||||
_physicsPublication?.Dispose();
|
||||
if (_controller is not null)
|
||||
{
|
||||
_controller.RetireRuntimePublication();
|
||||
_controller = null;
|
||||
ControllerOwnershipEpoch++;
|
||||
}
|
||||
_preparingMotionOwner = null;
|
||||
Interlocked.Increment(ref _revision);
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
internal void AttachPhysicsPublication(
|
||||
RuntimeLocalPlayerPhysicsPublicationState publication)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
ArgumentNullException.ThrowIfNull(publication);
|
||||
if (_physicsPublication is not null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"The Runtime local-player physics publication owner is already bound.");
|
||||
}
|
||||
_physicsPublication = publication;
|
||||
}
|
||||
|
||||
internal bool CanCommitRuntimeOwnedController(
|
||||
ulong expectedEpoch,
|
||||
PlayerMovementController? expectedController) =>
|
||||
!_disposed
|
||||
&& ControllerOwnershipEpoch == expectedEpoch
|
||||
&& ReferenceEquals(_controller, expectedController);
|
||||
|
||||
internal void CommitRuntimeOwnedController(PlayerMovementController controller)
|
||||
{
|
||||
_controller?.RetireRuntimePublication();
|
||||
_controller = controller;
|
||||
ControllerOwnershipEpoch++;
|
||||
Interlocked.Increment(ref _revision);
|
||||
}
|
||||
|
||||
private void EndMotionPreparation(PlayerMovementController controller)
|
||||
{
|
||||
// Terminal disposal clears the unpublished construction seam. A
|
||||
|
|
@ -310,12 +360,15 @@ public readonly record struct RuntimeLocalMovementOwnershipSnapshot(
|
|||
bool HasPreparingMotionOwner,
|
||||
bool AutoRunActive,
|
||||
bool HasCommandInput,
|
||||
long Revision)
|
||||
long Revision,
|
||||
ulong ControllerOwnershipEpoch,
|
||||
RuntimeLocalPlayerPhysicsPublicationOwnershipSnapshot PhysicsPublication)
|
||||
{
|
||||
public bool IsConverged =>
|
||||
IsDisposed
|
||||
&& !HasController
|
||||
&& !HasPreparingMotionOwner
|
||||
&& !AutoRunActive
|
||||
&& !HasCommandInput;
|
||||
&& !HasCommandInput
|
||||
&& PhysicsPublication.IsConverged;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue