acdream/src/AcDream.App/Physics/DeferredLiveEntityMotionRuntimeBindings.cs
Erik aa90c64666 refactor(world): extract live entity network updates
Move Position, Vector, State, Movement, and equal-generation CreateObject routing out of GameWindow while preserving per-channel authority, ForcePosition acknowledgement, and motion-runtime ownership. Add adversarial authority and exact-wire coverage so reentrant updates and GUID reuse cannot publish stale state.
2026-07-21 19:11:49 +02:00

64 lines
2.2 KiB
C#

using AcDream.App.Physics;
using AcDream.App.Rendering;
using AcDream.Core.Net;
using AcDream.Core.Physics.Motion;
using AcDream.Core.World;
namespace AcDream.App.Physics;
/// <summary>
/// Narrow reverse seam for collaborators constructed before the live network
/// owner. It carries no state or identity: every call resolves the one bound
/// update-thread owner, and use before bind fails immediately.
/// </summary>
internal interface ILiveEntityMotionRuntimeBindings
{
(float Radius, float Height) GetSetupCylinder(uint serverGuid, WorldEntity entity);
bool RouteServerMoveTo(
MovementManager movement,
uint cellId,
WorldSession.EntityMotionUpdate update);
void StickToObjectFromWire(IPhysicsObjHost? host, uint targetGuid);
void ClearTargetForHiddenEntity(uint serverGuid);
IPhysicsObjHost? ResolvePhysicsHost(uint serverGuid);
}
internal sealed class DeferredLiveEntityMotionRuntimeBindings
: ILiveEntityMotionRuntimeBindings
{
private ILiveEntityMotionRuntimeBindings? _target;
public void Bind(ILiveEntityMotionRuntimeBindings target)
{
ArgumentNullException.ThrowIfNull(target);
if (_target is not null)
{
throw new InvalidOperationException(
"Live entity motion runtime bindings are already bound.");
}
_target = target;
}
private ILiveEntityMotionRuntimeBindings Target =>
_target ?? throw new InvalidOperationException(
"Live entity motion runtime bindings were used before binding.");
public (float Radius, float Height) GetSetupCylinder(
uint serverGuid,
WorldEntity entity) => Target.GetSetupCylinder(serverGuid, entity);
public bool RouteServerMoveTo(
MovementManager movement,
uint cellId,
WorldSession.EntityMotionUpdate update) =>
Target.RouteServerMoveTo(movement, cellId, update);
public void StickToObjectFromWire(IPhysicsObjHost? host, uint targetGuid) =>
Target.StickToObjectFromWire(host, targetGuid);
public void ClearTargetForHiddenEntity(uint serverGuid) =>
Target.ClearTargetForHiddenEntity(serverGuid);
public IPhysicsObjHost? ResolvePhysicsHost(uint serverGuid) =>
Target.ResolvePhysicsHost(serverGuid);
}