refactor(runtime): own inventory transaction state
Move the retail one-request-at-a-time gate, shared use busy references, external-container state, item mana, shortcuts, and desired-component snapshots into one Runtime-owned graph over J3's exact ClientObjectTable. Retained UI and session routing now borrow that owner; reset and shutdown preserve the existing order while failure/reentrancy tests protect the transaction boundary. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
595d5e6b01
commit
011efbeaa7
18 changed files with 1337 additions and 406 deletions
|
|
@ -46,13 +46,11 @@ internal sealed record InteractionRetainedUiDependencies(
|
|||
CombatState Combat,
|
||||
ICombatAttackOperations CombatAttackOperations,
|
||||
SelectionState Selection,
|
||||
ExternalContainerState ExternalContainers,
|
||||
ClientObjectTable Objects,
|
||||
RuntimeInventoryState Inventory,
|
||||
MagicCatalog MagicCatalog,
|
||||
Spellbook Spellbook,
|
||||
RuntimeCommunicationState Communication,
|
||||
LocalPlayerState LocalPlayer,
|
||||
ItemManaState ItemMana,
|
||||
StackSplitQuantityState StackSplitQuantity,
|
||||
BufferedUiRegistry? UiRegistry,
|
||||
LiveCombatModeCommandSlot CombatModeCommands,
|
||||
|
|
@ -60,7 +58,6 @@ internal sealed record InteractionRetainedUiDependencies(
|
|||
ILocalPlayerControllerSource PlayerController,
|
||||
ILocalPlayerModeSource PlayerMode,
|
||||
PlayerCharacterOptionsState CharacterOptions,
|
||||
ShortcutSnapshotState Shortcuts,
|
||||
Func<DeferredSelectionViewPlaneSource, SelectionCameraSource>
|
||||
SelectionCameraFactory,
|
||||
DeferredRenderFrameDiagnosticsSource FrameDiagnostics,
|
||||
|
|
@ -275,8 +272,8 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
InteractionRetainedUiDependencies d,
|
||||
DeferredLiveSessionUiAuthority session) =>
|
||||
new(
|
||||
d.ExternalContainers,
|
||||
d.Objects,
|
||||
d.Inventory.ExternalContainers,
|
||||
d.Inventory.Objects,
|
||||
guid => session.CurrentSession?.SendNoLongerViewingContents(guid));
|
||||
|
||||
public ItemInteractionController CreateItemInteraction(
|
||||
|
|
@ -286,7 +283,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
DeferredLiveSessionUiAuthority session = late.Session;
|
||||
DeferredSelectionUiAuthority selection = late.Selection;
|
||||
return new ItemInteractionController(
|
||||
d.Objects,
|
||||
d.Inventory.Objects,
|
||||
playerGuid: () => d.PlayerIdentity.ServerGuid,
|
||||
sendUse: null,
|
||||
sendExamine: guid => session.CurrentSession?.SendAppraise(guid),
|
||||
|
|
@ -313,7 +310,8 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
placeInBackpack: selection.SendPickup,
|
||||
backpackContainerId: () => late.InventoryContainer.Current(
|
||||
d.PlayerIdentity.ServerGuid),
|
||||
groundObjectId: () => d.ExternalContainers.CurrentContainerId,
|
||||
groundObjectId: () =>
|
||||
d.Inventory.ExternalContainers.CurrentContainerId,
|
||||
sendSplitToWorld: (item, amount) =>
|
||||
session.CurrentSession?.SendStackableSplitTo3D(item, amount),
|
||||
selectedObjectId: () => d.Selection.SelectedObjectId ?? 0u,
|
||||
|
|
@ -333,9 +331,10 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
amount),
|
||||
requestExternalContainer: guid =>
|
||||
{
|
||||
d.ExternalContainers.RequestOpen(guid);
|
||||
d.Inventory.ExternalContainers.RequestOpen(guid);
|
||||
},
|
||||
requestUse: selection.RequestUse);
|
||||
requestUse: selection.RequestUse,
|
||||
transactions: d.Inventory.Transactions);
|
||||
}
|
||||
|
||||
public RetainedUiComposition CreateRetainedUi(
|
||||
|
|
@ -372,7 +371,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
checkpoint(InteractionRetainedUiCompositionPoint.CursorAssetsCreated);
|
||||
|
||||
var characterSheet = new CharacterSheetProvider(
|
||||
d.Objects,
|
||||
d.Inventory.Objects,
|
||||
d.LocalPlayer,
|
||||
playerGuid: () => d.PlayerIdentity.ServerGuid,
|
||||
activeToonName: () => d.Settings.ActiveToonKey,
|
||||
|
|
@ -391,7 +390,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
MagicRuntime magic = MagicRuntime.Create(
|
||||
d.MagicCatalog,
|
||||
d.Spellbook,
|
||||
d.Objects,
|
||||
d.Inventory.Objects,
|
||||
selectedObject: () => d.Selection.SelectedObjectId,
|
||||
localPlayerId: () => d.PlayerIdentity.ServerGuid,
|
||||
accountName: () => late.Session.AccountName
|
||||
|
|
@ -530,7 +529,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
Magic: new MagicRuntimeBindings(
|
||||
d.Spellbook,
|
||||
magic.Casting,
|
||||
d.Objects,
|
||||
d.Inventory.Objects,
|
||||
() => d.PlayerIdentity.ServerGuid,
|
||||
d.MagicCatalog.Components,
|
||||
iconComposer.GetIcon,
|
||||
|
|
@ -571,7 +570,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
late.SelectionCamera.UiSnapshot),
|
||||
Indicators: new IndicatorRuntimeBindings(
|
||||
d.Spellbook,
|
||||
d.Objects,
|
||||
d.Inventory.Objects,
|
||||
() => d.PlayerIdentity.ServerGuid,
|
||||
() => d.LocalPlayer.GetAttribute(
|
||||
LocalPlayerState.AttributeKind.Strength)
|
||||
|
|
@ -581,13 +580,13 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
() => late.Session.CurrentSession?.RequestLinkStatusPing(),
|
||||
d.Window.Close),
|
||||
Toolbar: new ToolbarRuntimeBindings(
|
||||
d.Objects,
|
||||
() => d.Shortcuts.Items,
|
||||
d.Inventory.Objects,
|
||||
() => d.Inventory.Shortcuts.Items,
|
||||
iconComposer.GetIcon,
|
||||
iconComposer.GetDragIcon,
|
||||
guid => late.Session.TryUseItem(guid, d.Log),
|
||||
d.Combat,
|
||||
d.ItemMana,
|
||||
d.Inventory.ItemMana,
|
||||
d.CombatModeCommands.Toggle,
|
||||
itemInteraction,
|
||||
entry => late.Session.CurrentSession?.SendAddShortcut(entry),
|
||||
|
|
@ -596,10 +595,11 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
handler => d.Combat.HealthChanged += handler,
|
||||
handler => d.Combat.HealthChanged -= handler,
|
||||
late.Selection.ShouldShowHealth,
|
||||
guid => d.Objects.Get(guid)?.GetAppropriateName(),
|
||||
guid => d.Inventory.Objects.Get(guid)?.GetAppropriateName(),
|
||||
d.Combat.GetHealthPercent,
|
||||
d.Combat.HasHealth,
|
||||
guid => (uint)(d.Objects.Get(guid)?.StackSize ?? 0),
|
||||
guid =>
|
||||
(uint)(d.Inventory.Objects.Get(guid)?.StackSize ?? 0),
|
||||
guid => late.Session.CurrentSession?.SendQueryHealth(guid),
|
||||
guid => late.Session.CurrentSession?.SendQueryItemMana(guid),
|
||||
() => d.PlayerIdentity.ServerGuid,
|
||||
|
|
@ -610,7 +610,7 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
placement)),
|
||||
Character: new CharacterRuntimeBindings(characterSheet),
|
||||
Inventory: new InventoryRuntimeBindings(
|
||||
d.Objects,
|
||||
d.Inventory.Objects,
|
||||
() => d.PlayerIdentity.ServerGuid,
|
||||
iconComposer.GetIcon,
|
||||
iconComposer.GetDragIcon,
|
||||
|
|
@ -637,8 +637,8 @@ internal sealed class RetailInteractionRetainedUiCompositionFactory
|
|||
itemInteraction,
|
||||
d.Selection),
|
||||
ExternalContainer: new ExternalContainerRuntimeBindings(
|
||||
d.ExternalContainers,
|
||||
d.Objects,
|
||||
d.Inventory.ExternalContainers,
|
||||
d.Inventory.Objects,
|
||||
iconComposer.GetIcon,
|
||||
iconComposer.GetDragIcon,
|
||||
itemInteraction,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue