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
|
|
@ -335,22 +335,19 @@ public sealed class GameWindow :
|
|||
public AcDream.Core.Social.SquelchState Squelch =>
|
||||
_runtimeCommunication.Squelch;
|
||||
public readonly AcDream.Core.Combat.CombatState Combat = new();
|
||||
public readonly AcDream.Core.Items.ItemManaState ItemMana = new();
|
||||
private readonly DesiredComponentSnapshotState _desiredComponents = new();
|
||||
private readonly RuntimeEntityObjectLifetime _runtimeEntityObjects = new();
|
||||
private readonly RuntimeInventoryState _runtimeInventory;
|
||||
public AcDream.Core.Items.ItemManaState ItemMana =>
|
||||
_runtimeInventory.ItemMana;
|
||||
public IReadOnlyList<(uint Id, uint Amount)> DesiredComponents =>
|
||||
_desiredComponents.Items;
|
||||
_runtimeInventory.DesiredComponents.Items;
|
||||
// Retail resolves learned IDs through portal.dat's CSpellTable. MagicCatalog
|
||||
// installs that immutable table once DatCollection opens in OnLoad.
|
||||
public AcDream.Core.Spells.SpellTable SpellTable => SpellBook.Metadata;
|
||||
public readonly AcDream.Core.Spells.Spellbook SpellBook = null!;
|
||||
private readonly RuntimeEntityObjectLifetime _runtimeEntityObjects = new();
|
||||
/// <summary>Persisted hotbar shortcuts from the last PlayerDescription (D.5.1 toolbar source).</summary>
|
||||
private readonly ShortcutSnapshotState _shortcutSnapshots = new();
|
||||
public IReadOnlyList<AcDream.Core.Items.ShortcutEntry> Shortcuts
|
||||
{
|
||||
get => _shortcutSnapshots.Items;
|
||||
private set => _shortcutSnapshots.Items = value;
|
||||
}
|
||||
public IReadOnlyList<AcDream.Core.Items.ShortcutEntry> Shortcuts =>
|
||||
_runtimeInventory.Shortcuts.Items;
|
||||
// Issue #5 — caches CreatureProfile.{Stamina, Mana, *Max} from
|
||||
// PlayerDescription so the Vitals HUD can render those bars.
|
||||
// Issue #6 — wired to SpellBook so GetMaxApprox folds enchantment
|
||||
|
|
@ -377,7 +374,6 @@ public sealed class GameWindow :
|
|||
private AcDream.App.Combat.CombatAttackController? _combatAttackController;
|
||||
private AcDream.App.Combat.CombatTargetController? _combatTargetController;
|
||||
private AcDream.App.UI.ItemInteractionController? _itemInteractionController;
|
||||
private readonly AcDream.Core.Items.ExternalContainerState _externalContainers = new();
|
||||
private AcDream.App.World.ExternalContainerLifecycleController? _externalContainerLifecycle;
|
||||
private AcDream.App.Spells.MagicRuntime? _magicRuntime;
|
||||
private AcDream.App.Spells.MagicCatalog? _magicCatalog;
|
||||
|
|
@ -565,6 +561,7 @@ public sealed class GameWindow :
|
|||
AcDream.App.Plugins.BufferedUiRegistry? uiRegistry = null)
|
||||
{
|
||||
_options = options ?? throw new System.ArgumentNullException(nameof(options));
|
||||
_runtimeInventory = new RuntimeInventoryState(_runtimeEntityObjects);
|
||||
var alphaScratchBudgets =
|
||||
AcDream.App.Rendering.Residency.AlphaScratchBudgetProfile.Create(
|
||||
_options.ResidencyBudgets.AlphaScratchBytes);
|
||||
|
|
@ -1262,13 +1259,11 @@ public sealed class GameWindow :
|
|||
Combat,
|
||||
_combatAttackOperations,
|
||||
_selection,
|
||||
_externalContainers,
|
||||
_runtimeEntityObjects.Objects,
|
||||
_runtimeInventory,
|
||||
contentEffectsAudio.MagicCatalog,
|
||||
SpellBook,
|
||||
_runtimeCommunication,
|
||||
LocalPlayer,
|
||||
ItemMana,
|
||||
_stackSplitQuantity,
|
||||
_uiRegistry,
|
||||
_liveCombatModeCommands,
|
||||
|
|
@ -1276,7 +1271,6 @@ public sealed class GameWindow :
|
|||
_playerControllerSlot,
|
||||
_localPlayerMode,
|
||||
_characterOptions,
|
||||
_shortcutSnapshots,
|
||||
viewPlane => new SelectionCameraSource(
|
||||
hostInputCamera.CameraController,
|
||||
_window!,
|
||||
|
|
@ -1398,8 +1392,7 @@ public sealed class GameWindow :
|
|||
_viewportAspect,
|
||||
_playerApproachCompletions,
|
||||
_characterOptions,
|
||||
_shortcutSnapshots,
|
||||
_desiredComponents,
|
||||
_runtimeInventory,
|
||||
_pointerPosition,
|
||||
_movementInput,
|
||||
_inputCapture,
|
||||
|
|
@ -1414,8 +1407,6 @@ public sealed class GameWindow :
|
|||
_runtimeCommunication,
|
||||
LocalPlayer,
|
||||
SpellBook,
|
||||
ItemMana,
|
||||
_externalContainers,
|
||||
_portalTunnelFallback,
|
||||
Console.WriteLine),
|
||||
this).Compose(
|
||||
|
|
@ -1590,6 +1581,7 @@ public sealed class GameWindow :
|
|||
_equippedChildRenderer,
|
||||
_liveEntities,
|
||||
_runtimeEntityObjects,
|
||||
_runtimeInventory,
|
||||
_runtimeCommunication,
|
||||
_renderSceneShadow,
|
||||
_livePresentationBindings,
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ internal sealed record LiveShutdownRoots(
|
|||
EquippedChildRenderController? EquippedChildren,
|
||||
LiveEntityRuntime? LiveEntities,
|
||||
RuntimeEntityObjectLifetime EntityObjects,
|
||||
RuntimeInventoryState Inventory,
|
||||
RuntimeCommunicationState Communication,
|
||||
RenderSceneShadowRuntime? RenderSceneShadow,
|
||||
LivePresentationRuntimeBindings? PresentationBindings,
|
||||
|
|
@ -390,6 +391,9 @@ internal static class GameWindowShutdownManifest
|
|||
]),
|
||||
new ResourceShutdownStage("runtime entity/object stream",
|
||||
[
|
||||
Hard(
|
||||
"runtime inventory state",
|
||||
live.Inventory.Dispose),
|
||||
Hard(
|
||||
"runtime entity/object lifetime",
|
||||
live.EntityObjects.Dispose),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue