refactor(runtime): close canonical gameplay ownership

Unify the toolbar shortcut manager with Runtime inventory state, route retail-ordered shortcut and spellbook command effects through the canonical owners, and make retained controllers borrow those exact instances. Remove the item-interaction transaction fallback and add graphical/no-window parity plus failure-safe terminal ownership-ledger coverage.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-26 09:48:51 +02:00
parent ce6fae7b38
commit 89e6b207f8
36 changed files with 1433 additions and 251 deletions

View file

@ -31,7 +31,7 @@ public sealed class ItemInteractionControllerTests
public readonly List<CombatMode> CombatModeRequests = new();
public readonly CombatState Combat = new();
public readonly StackSplitQuantityState SplitQuantity = new();
public readonly InventoryTransactionState? SharedTransactions;
public readonly InventoryTransactionState SharedTransactions;
public uint SelectedObject;
public bool NonCombatMode;
public bool DragOnPlayerOpensSecureTrade = true;
@ -39,8 +39,7 @@ public sealed class ItemInteractionControllerTests
public long Now = 1_000;
public Harness(
Action<uint, ItemUseRequestReservation>? requestUse = null,
bool sharedTransactions = false)
Action<uint, ItemUseRequestReservation>? requestUse = null)
{
Objects.AddOrUpdate(new ClientObject
{
@ -56,12 +55,11 @@ public sealed class ItemInteractionControllerTests
ItemsCapacity = 24,
});
Objects.MoveItem(Pack, Player, 0);
SharedTransactions = sharedTransactions
? new InventoryTransactionState(Objects)
: null;
SharedTransactions = new InventoryTransactionState(Objects);
Controller = new ItemInteractionController(
Objects,
SharedTransactions,
playerGuid: () => Player,
sendUse: requestUse is null ? Uses.Add : null,
sendExamine: Examines.Add,
@ -91,8 +89,7 @@ public sealed class ItemInteractionControllerTests
},
combatState: Combat,
sendChangeCombatMode: CombatModeRequests.Add,
requestUse: requestUse,
transactions: SharedTransactions);
requestUse: requestUse);
}
public ItemInteractionController Controller { get; }
@ -321,11 +318,11 @@ public sealed class ItemInteractionControllerTests
[Fact]
public void BorrowedTransactionOwnerIsExactAndOutlivesController()
{
var h = new Harness(sharedTransactions: true);
var h = new Harness();
h.Controller.IncrementBusyCount();
Assert.Equal(1, h.SharedTransactions!.BusyCount);
Assert.Equal(1, h.SharedTransactions.BusyCount);
h.Controller.Dispose();
Assert.False(h.SharedTransactions.IsDisposed);
@ -343,12 +340,12 @@ public sealed class ItemInteractionControllerTests
Assert.Throws<ArgumentException>(() => new ItemInteractionController(
objects,
transactions,
playerGuid: () => Player,
sendUse: null,
sendUseWithTarget: null,
sendWield: null,
sendDrop: null,
transactions: transactions));
sendDrop: null));
}
[Fact]