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
|
|
@ -18,6 +18,7 @@ internal sealed class LiveSessionResetBindings
|
|||
public required Action EquippedChildren { get; init; }
|
||||
public required Action ExternalContainer { get; init; }
|
||||
public required Action InteractionAndSelection { get; init; }
|
||||
public required Action InventoryTransactions { get; init; }
|
||||
public required Action SelectionPresentation { get; init; }
|
||||
public required Action ObjectTable { get; init; }
|
||||
public required Action Spellbook { get; init; }
|
||||
|
|
@ -67,6 +68,7 @@ internal static class LiveSessionResetManifest
|
|||
new("equipped children", bindings.EquippedChildren),
|
||||
new("external container", bindings.ExternalContainer),
|
||||
new("interaction and selection", bindings.InteractionAndSelection),
|
||||
new("inventory transactions", bindings.InventoryTransactions),
|
||||
new("selection presentation", bindings.SelectionPresentation),
|
||||
new("object table", bindings.ObjectTable),
|
||||
new("spellbook", bindings.Spellbook),
|
||||
|
|
|
|||
|
|
@ -38,17 +38,14 @@ internal sealed record LiveSessionPlayerRuntime(
|
|||
LocalPlayerControllerSlot Controller,
|
||||
LocalPlayerSkillState Skills,
|
||||
LiveWorldOriginState WorldOrigin,
|
||||
PlayerCharacterOptionsState CharacterOptions,
|
||||
ShortcutSnapshotState Shortcuts,
|
||||
DesiredComponentSnapshotState DesiredComponents);
|
||||
PlayerCharacterOptionsState CharacterOptions);
|
||||
|
||||
internal sealed record LiveSessionDomainRuntime(
|
||||
RuntimeEntityObjectLifetime EntityObjects,
|
||||
LocalPlayerState LocalPlayer,
|
||||
Spellbook Spellbook,
|
||||
CombatState Combat,
|
||||
ItemManaState ItemMana,
|
||||
ExternalContainerState ExternalContainers,
|
||||
RuntimeInventoryState Inventory,
|
||||
RuntimeCommunicationState Communication);
|
||||
|
||||
internal sealed record LiveSessionUiRuntime(
|
||||
|
|
@ -168,15 +165,16 @@ internal sealed class LiveSessionRuntimeFactory
|
|||
SettingsCharacterContext =
|
||||
_interaction.Settings.RestoreDefaultCharacterContext,
|
||||
EquippedChildren = _world.EquippedChildren.Clear,
|
||||
ExternalContainer = () => _domain.ExternalContainers.Reset(),
|
||||
ExternalContainer = _domain.Inventory.ResetExternalContainer,
|
||||
InteractionAndSelection = _interaction.SelectionInteractions.ResetSession,
|
||||
InventoryTransactions = _domain.Inventory.ResetTransactions,
|
||||
SelectionPresentation = _world.SelectionScene.Reset,
|
||||
ObjectTable = _domain.EntityObjects.ClearObjects,
|
||||
Spellbook = _domain.Spellbook.Clear,
|
||||
MagicRuntime = () => _ui.Magic?.Reset(),
|
||||
CombatAttack = _interaction.CombatAttack.ResetSession,
|
||||
CombatState = _domain.Combat.Clear,
|
||||
ItemMana = _domain.ItemMana.Clear,
|
||||
ItemMana = _domain.Inventory.ResetItemMana,
|
||||
LocalPlayer = _domain.LocalPlayer.Clear,
|
||||
Friends = _domain.Communication.ResetFriends,
|
||||
Squelch = _domain.Communication.ResetSquelch,
|
||||
|
|
@ -222,8 +220,7 @@ internal sealed class LiveSessionRuntimeFactory
|
|||
_player.Skills.ResetSession();
|
||||
_world.NetworkUpdates.ResetSessionState();
|
||||
_world.Hydration.ResetSessionState();
|
||||
_player.Shortcuts.Items = Array.Empty<ShortcutEntry>();
|
||||
_player.DesiredComponents.Clear();
|
||||
_domain.Inventory.ResetPlayerSnapshots();
|
||||
_ui.Paperdoll?.ResetSession();
|
||||
|
||||
// X/Y are ignored until the next logical player CreateObject claims a
|
||||
|
|
@ -258,19 +255,18 @@ internal sealed class LiveSessionRuntimeFactory
|
|||
}
|
||||
|
||||
private LiveInventorySessionBindings CreateInventoryBindings() => new(
|
||||
_domain.EntityObjects.Objects,
|
||||
_domain.Inventory.Objects,
|
||||
_domain.LocalPlayer,
|
||||
PlayerGuid: () => _player.Identity.ServerGuid,
|
||||
OnShortcuts: list => _player.Shortcuts.Items = list,
|
||||
OnShortcuts: _domain.Inventory.Shortcuts.Replace,
|
||||
OnUseDone: error =>
|
||||
{
|
||||
_domain.ExternalContainers.ApplyUseDone(error);
|
||||
_interaction.ItemInteraction.CompleteUse(error);
|
||||
_domain.Inventory.ExternalContainers.ApplyUseDone(error);
|
||||
_domain.Inventory.Transactions.CompleteUse(error);
|
||||
},
|
||||
_domain.ItemMana,
|
||||
OnDesiredComponents: components =>
|
||||
_player.DesiredComponents.Items = components,
|
||||
ExternalContainers: _domain.ExternalContainers,
|
||||
_domain.Inventory.ItemMana,
|
||||
OnDesiredComponents: _domain.Inventory.DesiredComponents.Replace,
|
||||
ExternalContainers: _domain.Inventory.ExternalContainers,
|
||||
OnAppraisal: appraisal =>
|
||||
{
|
||||
if (_ui.RetailUi is { } retailUi)
|
||||
|
|
@ -376,7 +372,7 @@ internal sealed class LiveSessionRuntimeFactory
|
|||
ClearDesiredComponents: () =>
|
||||
{
|
||||
session.SendClearDesiredComponents();
|
||||
_player.DesiredComponents.Clear();
|
||||
_domain.Inventory.DesiredComponents.Clear();
|
||||
},
|
||||
HasOpenVendor: () => false,
|
||||
FillComponentBuyList: (_, _) => { }),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue