feat(app): observe canonical placement receipts

This commit is contained in:
Erik 2026-08-01 15:22:52 +02:00
parent 378ca95a67
commit f05ed5c3cd
14 changed files with 545 additions and 31 deletions

View file

@ -27,6 +27,8 @@ internal sealed class RetailLiveFrameCoordinator : IRetailLiveFramePhase
private readonly ILiveSpatialReconcilePhase _spatialReconciler;
private readonly IWorldGenerationAvailability _availability;
private readonly IRenderProjectionSyncPhase? _renderProjectionSync;
private readonly IRuntimePlacementProjectionRetryPhase?
_placementProjectionRetry;
public RetailLiveFrameCoordinator(
ILiveObjectFramePhase objects,
@ -35,7 +37,8 @@ internal sealed class RetailLiveFrameCoordinator : IRetailLiveFramePhase
IPostNetworkCommandFramePhase localPlayer,
ILiveSpatialReconcilePhase spatialReconciler,
IWorldGenerationAvailability? availability = null,
IRenderProjectionSyncPhase? renderProjectionSync = null)
IRenderProjectionSyncPhase? renderProjectionSync = null,
IRuntimePlacementProjectionRetryPhase? placementProjectionRetry = null)
{
_objects = objects ?? throw new ArgumentNullException(nameof(objects));
_worldState = worldState ?? throw new ArgumentNullException(nameof(worldState));
@ -45,6 +48,7 @@ internal sealed class RetailLiveFrameCoordinator : IRetailLiveFramePhase
?? throw new ArgumentNullException(nameof(spatialReconciler));
_availability = availability ?? AlwaysAvailableWorldGeneration.Instance;
_renderProjectionSync = renderProjectionSync;
_placementProjectionRetry = placementProjectionRetry;
}
public void Tick(float deltaSeconds)
@ -53,7 +57,14 @@ internal sealed class RetailLiveFrameCoordinator : IRetailLiveFramePhase
if (_availability.IsWorldAvailable)
_objects.Tick(frameDelta);
using (_worldState.BeginMutationBatch())
{
_session.Tick();
// Streaming publication precedes this coordinator, while inbound
// network dispatch completes immediately above. A graphical
// receipt that previously lacked its destination backend can now
// retry against both readiness edges on the update thread.
_placementProjectionRetry?.RetryPending();
}
_localPlayer.RunPostNetworkCommandPhase();
if (_availability.IsWorldAvailable)
_spatialReconciler.Reconcile();

View file

@ -14,9 +14,9 @@ namespace AcDream.App.World;
/// and renderer/VFX visibility projections. Runtime physics, shadows, body
/// state, clocks, and worksets were committed before this sink is invoked.
///
/// This adapter deliberately owns no subscription: production composition
/// activates the shared observer only after both graphical and no-window hosts
/// implement the same presentation-only contract.
/// This adapter deliberately owns no subscription. The exact graphical
/// session route owns the shared Runtime observer and its generation-scoped
/// update-thread retry lease.
/// </summary>
internal sealed class RuntimePlacementPresentationSink
: IRuntimePlacementProjectionSink