fix(runtime): restore interaction completion ownership

Preserve prepublication local motion completion, require the PartArray enter-world lifecycle port, and balance deferred Use busy ownership across dispatch and cancellation. Reconcile the completed GameWindow connected gates and add regression coverage.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-23 05:51:51 +02:00
parent 5c955c36ec
commit f9736ece6c
26 changed files with 675 additions and 68 deletions

View file

@ -287,7 +287,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
return new ItemInteractionController(
d.Objects,
playerGuid: () => d.PlayerIdentity.ServerGuid,
sendUse: selection.SendUse,
sendUse: null,
sendExamine: guid => session.CurrentSession?.SendAppraise(guid),
sendUseWithTarget: (source, target) =>
session.CurrentSession?.SendUseWithTarget(source, target),
@ -332,7 +332,8 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
requestExternalContainer: guid =>
{
d.ExternalContainers.RequestOpen(guid);
});
},
requestUse: selection.RequestUse);
}
public RetainedUiComposition CreateRetainedUi(

View file

@ -169,6 +169,18 @@ internal sealed class DeferredSelectionUiAuthority
target?.SendUse(guid);
}
public void RequestUse(uint guid, ItemUseRequestReservation reservation)
{
ArgumentNullException.ThrowIfNull(reservation);
SelectionInteractionController? target;
lock (_gate)
target = !_deactivated ? _interactions : null;
if (target is null)
reservation.CancelBeforeDispatch();
else
target.RequestUse(guid, reservation);
}
public void SendPickup(uint itemGuid, uint destinationContainerId, int placement)
{
SelectionInteractionController? target;

View file

@ -460,10 +460,11 @@ internal sealed class LivePresentationCompositionPhase
liveEntities,
d.PhysicsEngine.ShadowObjects,
entityEffects.PlayTypedFromHiddenTransition,
new LiveEntityPartArrayEnterWorldPort(
partArrayLifecycle.HandleEnterWorld),
equippedLease.Resource.SetDirectChildrenNoDraw,
d.MotionBindings.ClearTargetForHiddenEntity,
d.WorldOrigin.GetCenter,
partArrayLifecycle.HandleEnterWorld),
d.WorldOrigin.GetCenter),
static value => value.Dispose());
var remoteShadowPlacement = new RemoteShadowPlacementSynchronizer(
d.RemotePhysicsUpdater,