refactor(runtime): extract the live object frame
This commit is contained in:
parent
99a3e819c4
commit
4e4aac2c5a
27 changed files with 1217 additions and 371 deletions
|
|
@ -1,5 +1,7 @@
|
|||
using System.Numerics;
|
||||
using AcDream.App.Rendering;
|
||||
using AcDream.App.World;
|
||||
using AcDream.Content;
|
||||
using AcDream.Core.Net;
|
||||
using AcDream.Core.Net.Messages;
|
||||
using AcDream.Core.Physics;
|
||||
|
|
@ -9,6 +11,29 @@ using RemoteMotion = AcDream.App.Physics.RemoteMotion;
|
|||
|
||||
namespace AcDream.App.Physics;
|
||||
|
||||
internal interface IProjectileSetupResolver
|
||||
{
|
||||
Setup? Resolve(uint setupId);
|
||||
}
|
||||
|
||||
internal sealed class DatProjectileSetupResolver : IProjectileSetupResolver
|
||||
{
|
||||
private readonly IDatReaderWriter _dats;
|
||||
private readonly object _datLock;
|
||||
|
||||
public DatProjectileSetupResolver(IDatReaderWriter dats, object datLock)
|
||||
{
|
||||
_dats = dats ?? throw new ArgumentNullException(nameof(dats));
|
||||
_datLock = datLock ?? throw new ArgumentNullException(nameof(datLock));
|
||||
}
|
||||
|
||||
public Setup? Resolve(uint setupId)
|
||||
{
|
||||
lock (_datLock)
|
||||
return _dats.Get<Setup>(setupId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update-thread presentation owner for live retail missiles. Logical identity,
|
||||
/// generation, accepted network state, and teardown remain owned by
|
||||
|
|
@ -56,26 +81,26 @@ internal sealed class ProjectileController
|
|||
private readonly LiveEntityRuntime _liveEntities;
|
||||
private readonly ProjectilePhysicsStepper _stepper;
|
||||
private readonly ShadowObjectRegistry _shadows;
|
||||
private readonly Func<uint, Setup?> _setupResolver;
|
||||
private readonly Action<WorldEntity> _publishRootPose;
|
||||
private readonly Func<(int X, int Y)> _liveCenterProvider;
|
||||
private readonly IProjectileSetupResolver? _setupResolver;
|
||||
private readonly IEntityRootPosePublisher? _rootPoses;
|
||||
private readonly LiveWorldOriginState? _origin;
|
||||
private readonly List<LiveEntityRecord> _spatialProjectileSnapshot = new();
|
||||
private double _lastFiniteGameTime;
|
||||
|
||||
internal ProjectileController(
|
||||
LiveEntityRuntime liveEntities,
|
||||
PhysicsEngine physicsEngine,
|
||||
Func<uint, Setup?>? setupResolver = null,
|
||||
Action<WorldEntity>? publishRootPose = null,
|
||||
Func<(int X, int Y)>? liveCenterProvider = null)
|
||||
IProjectileSetupResolver? setupResolver = null,
|
||||
IEntityRootPosePublisher? rootPoses = null,
|
||||
LiveWorldOriginState? origin = null)
|
||||
{
|
||||
_liveEntities = liveEntities ?? throw new ArgumentNullException(nameof(liveEntities));
|
||||
ArgumentNullException.ThrowIfNull(physicsEngine);
|
||||
_stepper = new ProjectilePhysicsStepper(physicsEngine);
|
||||
_shadows = physicsEngine.ShadowObjects;
|
||||
_setupResolver = setupResolver ?? (_ => null);
|
||||
_publishRootPose = publishRootPose ?? (_ => { });
|
||||
_liveCenterProvider = liveCenterProvider ?? (() => (0, 0));
|
||||
_setupResolver = setupResolver;
|
||||
_rootPoses = rootPoses;
|
||||
_origin = origin;
|
||||
_liveEntities.ProjectionVisibilityChanged += OnProjectionVisibilityChanged;
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +347,7 @@ internal sealed class ProjectileController
|
|||
{
|
||||
SuspendOutsideWorld(runtime, entity.Id);
|
||||
}
|
||||
_publishRootPose(entity);
|
||||
_rootPoses?.UpdateRoot(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -472,7 +497,7 @@ internal sealed class ProjectileController
|
|||
// A newer State packet can make an already materialized object a
|
||||
// missile. TryBind adopts an existing MovementManager body so the
|
||||
// live record still represents retail's one CPhysicsObj.
|
||||
Setup? setup = _setupResolver(entity.SourceGfxObjOrSetupId);
|
||||
Setup? setup = _setupResolver?.Resolve(entity.SourceGfxObjOrSetupId);
|
||||
if (setup is null)
|
||||
{
|
||||
DiagnosticSink?.Invoke(
|
||||
|
|
@ -617,7 +642,7 @@ internal sealed class ProjectileController
|
|||
{
|
||||
SuspendOutsideWorld(runtime, entity.Id);
|
||||
}
|
||||
_publishRootPose(entity);
|
||||
_rootPoses?.UpdateRoot(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -712,7 +737,7 @@ internal sealed class ProjectileController
|
|||
record.FullCellId,
|
||||
liveCenterX,
|
||||
liveCenterY);
|
||||
_publishRootPose(entity);
|
||||
_rootPoses?.UpdateRoot(entity);
|
||||
}
|
||||
|
||||
if (IsHidden(record))
|
||||
|
|
@ -909,7 +934,7 @@ internal sealed class ProjectileController
|
|||
current.FullCellId,
|
||||
liveCenterX,
|
||||
liveCenterY);
|
||||
_publishRootPose(entity);
|
||||
_rootPoses?.UpdateRoot(entity);
|
||||
if (!IsCurrentQuantumIdentity(step))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -966,7 +991,8 @@ internal sealed class ProjectileController
|
|||
// not lazily on the next simulated quantum: a zero-velocity or
|
||||
// newly ordinary retained projectile may have no later projectile
|
||||
// step from which to repair its shadow membership.
|
||||
(int liveCenterX, int liveCenterY) = _liveCenterProvider();
|
||||
int liveCenterX = _origin?.CenterX ?? 0;
|
||||
int liveCenterY = _origin?.CenterY ?? 0;
|
||||
ShadowPositionSynchronizer.Sync(
|
||||
_shadows,
|
||||
entity.Id,
|
||||
|
|
@ -975,7 +1001,7 @@ internal sealed class ProjectileController
|
|||
record.FullCellId,
|
||||
liveCenterX,
|
||||
liveCenterY);
|
||||
_publishRootPose(entity);
|
||||
_rootPoses?.UpdateRoot(entity);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue