feat(headless): observe canonical placement receipts
This commit is contained in:
parent
74c9b155bd
commit
378ca95a67
5 changed files with 445 additions and 23 deletions
|
|
@ -0,0 +1,76 @@
|
|||
using AcDream.Runtime;
|
||||
using AcDream.Runtime.Entities;
|
||||
using AcDream.Runtime.Physics;
|
||||
using AcDream.Runtime.World;
|
||||
|
||||
namespace AcDream.Headless.Hosting;
|
||||
|
||||
/// <summary>
|
||||
/// Validation-only no-window observer for canonical Runtime SetPosition
|
||||
/// receipts. A headless host has no graphical sidecar to move or hide, so a
|
||||
/// valid receipt is acknowledged without re-running placement or mutating
|
||||
/// Runtime's body, controller, shadows, clocks, or worksets.
|
||||
/// </summary>
|
||||
internal sealed class HeadlessRuntimePlacementProjectionSink
|
||||
: IRuntimePlacementProjectionSink
|
||||
{
|
||||
private readonly GameRuntime _runtime;
|
||||
|
||||
internal HeadlessRuntimePlacementProjectionSink(GameRuntime runtime)
|
||||
{
|
||||
_runtime = runtime ?? throw new ArgumentNullException(nameof(runtime));
|
||||
}
|
||||
|
||||
public bool TryApply(
|
||||
in RuntimePlacementProjectionSnapshot projection)
|
||||
{
|
||||
if (projection.Kind is RuntimePlacementProjectionKind.Discard)
|
||||
{
|
||||
// Discard cancels only an unacknowledged observation. It is valid
|
||||
// even after its entity/session authority has been superseded.
|
||||
return true;
|
||||
}
|
||||
|
||||
RuntimePlacementProjectionToken token = projection.Token;
|
||||
RuntimeEntityDirectory directory = _runtime.EntityObjects.Entities;
|
||||
if (!token.IsValid
|
||||
|| token.SessionLifetimeVersion
|
||||
!= directory.SessionLifetimeVersion
|
||||
|| !directory.TryGetByLocalId(
|
||||
token.Entity.LocalEntityId,
|
||||
out RuntimeEntityRecord record)
|
||||
|| !directory.IsCurrent(record)
|
||||
|| record.Key != token.Entity
|
||||
|| !HasValidPortalShape(token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (projection.Kind is RuntimePlacementProjectionKind.Withdraw)
|
||||
return true;
|
||||
if (projection.Kind is not RuntimePlacementProjectionKind.Place)
|
||||
return false;
|
||||
|
||||
return record.PositionAuthorityVersion
|
||||
== token.PositionAuthorityVersion
|
||||
&& record.SpatialAuthorityVersion
|
||||
== token.SpatialAuthorityVersion
|
||||
&& record.PlacementCommitVersion
|
||||
== token.PlacementCommitVersion
|
||||
&& record.FullCellId == token.ExactCellId
|
||||
&& _runtime.TransitOwner.IsCurrentPlacementAuthority(
|
||||
token.Portal,
|
||||
token.ExactCellId);
|
||||
}
|
||||
|
||||
private static bool HasValidPortalShape(
|
||||
in RuntimePlacementProjectionToken token)
|
||||
{
|
||||
RuntimePortalPlacementAuthority portal = token.Portal;
|
||||
if (!portal.Present)
|
||||
return portal.IsEmpty;
|
||||
|
||||
return portal.IsValid
|
||||
&& portal.Projection.DestinationCell == token.ExactCellId;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue