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:
parent
5c955c36ec
commit
f9736ece6c
26 changed files with 675 additions and 68 deletions
|
|
@ -37,7 +37,8 @@ public sealed class ItemInteractionControllerTests
|
|||
public uint GroundObject;
|
||||
public long Now = 1_000;
|
||||
|
||||
public Harness()
|
||||
public Harness(
|
||||
Action<uint, ItemUseRequestReservation>? requestUse = null)
|
||||
{
|
||||
Objects.AddOrUpdate(new ClientObject
|
||||
{
|
||||
|
|
@ -57,7 +58,7 @@ public sealed class ItemInteractionControllerTests
|
|||
Controller = new ItemInteractionController(
|
||||
Objects,
|
||||
playerGuid: () => Player,
|
||||
sendUse: Uses.Add,
|
||||
sendUse: requestUse is null ? Uses.Add : null,
|
||||
sendExamine: Examines.Add,
|
||||
sendUseWithTarget: (source, target) => UseWithTarget.Add((source, target)),
|
||||
sendWield: (item, mask) => Wields.Add((item, mask)),
|
||||
|
|
@ -84,7 +85,8 @@ public sealed class ItemInteractionControllerTests
|
|||
ExternalRequests.Add(id);
|
||||
},
|
||||
combatState: Combat,
|
||||
sendChangeCombatMode: CombatModeRequests.Add);
|
||||
sendChangeCombatMode: CombatModeRequests.Add,
|
||||
requestUse: requestUse);
|
||||
}
|
||||
|
||||
public ItemInteractionController Controller { get; }
|
||||
|
|
@ -1446,6 +1448,66 @@ public sealed class ItemInteractionControllerTests
|
|||
Assert.Equal(2, h.Uses.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeferredUseCancellationReleasesExactlyItsBusyReference()
|
||||
{
|
||||
ItemUseRequestReservation? pending = null;
|
||||
var h = new Harness((_, reservation) => pending = reservation);
|
||||
h.AddContained(
|
||||
0x50000A0Bu,
|
||||
item => item.Useability = ItemUseability.Contained);
|
||||
|
||||
Assert.True(h.Controller.ActivateItem(0x50000A0Bu));
|
||||
Assert.Equal(1, h.Controller.BusyCount);
|
||||
|
||||
Assert.NotNull(pending);
|
||||
pending.CancelBeforeDispatch();
|
||||
pending.CancelBeforeDispatch();
|
||||
|
||||
Assert.Equal(0, h.Controller.BusyCount);
|
||||
Assert.True(h.Controller.CanMakeInventoryRequest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DispatchedUseReservationIsReleasedOnlyByUseDone()
|
||||
{
|
||||
ItemUseRequestReservation? pending = null;
|
||||
var h = new Harness((_, reservation) => pending = reservation);
|
||||
h.AddContained(
|
||||
0x50000A0Cu,
|
||||
item => item.Useability = ItemUseability.Contained);
|
||||
|
||||
Assert.True(h.Controller.ActivateItem(0x50000A0Cu));
|
||||
Assert.NotNull(pending);
|
||||
pending.MarkDispatched();
|
||||
pending.CancelBeforeDispatch();
|
||||
|
||||
Assert.Equal(1, h.Controller.BusyCount);
|
||||
|
||||
h.Controller.CompleteUse(0u);
|
||||
|
||||
Assert.Equal(0, h.Controller.BusyCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SessionResetInvalidatesLateUseReservationResolution()
|
||||
{
|
||||
ItemUseRequestReservation? stale = null;
|
||||
var h = new Harness((_, reservation) => stale = reservation);
|
||||
h.AddContained(
|
||||
0x50000A0Du,
|
||||
item => item.Useability = ItemUseability.Contained);
|
||||
|
||||
Assert.True(h.Controller.ActivateItem(0x50000A0Du));
|
||||
Assert.Equal(1, h.Controller.BusyCount);
|
||||
|
||||
h.Controller.ResetSession();
|
||||
stale!.CancelBeforeDispatch();
|
||||
|
||||
Assert.Equal(0, h.Controller.BusyCount);
|
||||
Assert.True(h.Controller.CanMakeInventoryRequest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyboardPickup_PublishesPendingDestinationBeforeRequest()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue