using AcDream.Core.Items; using AcDream.Runtime.Entities; using AcDream.Runtime.Gameplay; namespace AcDream.Runtime.Tests.Gameplay; public sealed class RuntimeInventoryStateTests { [Fact] public void OwnsOneGameplayGraphOverExactEntityObjectTable() { using var entities = new RuntimeEntityObjectLifetime(); using var inventory = new RuntimeInventoryState(entities); IReadOnlyList shortcuts = [new ShortcutEntry(2, 0x50000001u, 0u)]; inventory.ExternalContainers.RequestOpen(0x70000001u); inventory.ExternalContainers.ApplyViewContents(0x70000001u); inventory.ItemMana.OnQueryItemManaResponse(0x50000001u, 0.75f, true); inventory.Shortcuts.Replace(shortcuts); Assert.Same(entities.Objects, inventory.Objects); Assert.Equal(0x70000001u, inventory.ExternalContainers.CurrentContainerId); Assert.Equal(0.75f, inventory.ItemMana.GetManaPercent(0x50000001u)); Assert.Same(shortcuts, inventory.Shortcuts.Items); Assert.Equal(1, inventory.Shortcuts.Revision); } [Fact] public void ResetOperationsClearOnlyTheirOwnedLifetimeGroup() { using var entities = new RuntimeEntityObjectLifetime(); using var inventory = new RuntimeInventoryState(entities); inventory.ExternalContainers.RequestOpen(0x70000001u); inventory.ExternalContainers.ApplyViewContents(0x70000001u); inventory.ItemMana.OnQueryItemManaResponse(0x50000001u, 0.75f, true); inventory.Shortcuts.Replace([new ShortcutEntry(1, 2u, 3u)]); inventory.Transactions.IncrementBusyCount(); inventory.ResetExternalContainer(); Assert.Equal(0u, inventory.ExternalContainers.CurrentContainerId); Assert.True(inventory.ItemMana.HasMana(0x50000001u)); Assert.NotEmpty(inventory.Shortcuts.Items); Assert.Equal(1, inventory.Transactions.BusyCount); inventory.ResetTransactions(); inventory.ResetItemMana(); inventory.ResetPlayerSnapshots(); Assert.Equal(0, inventory.Transactions.BusyCount); Assert.False(inventory.ItemMana.HasMana(0x50000001u)); Assert.Empty(inventory.Shortcuts.Items); } [Fact] public void IndependentRuntimeInstancesNeverShareState() { using var firstEntities = new RuntimeEntityObjectLifetime(); using var secondEntities = new RuntimeEntityObjectLifetime(); using var first = new RuntimeInventoryState(firstEntities); using var second = new RuntimeInventoryState(secondEntities); first.Shortcuts.Replace([new ShortcutEntry(1, 2u, 3u)]); first.Transactions.IncrementBusyCount(); Assert.NotSame(first.Objects, second.Objects); Assert.Single(first.Shortcuts.Items); Assert.Empty(second.Shortcuts.Items); Assert.Equal(1, first.Transactions.BusyCount); Assert.Equal(0, second.Transactions.BusyCount); } [Fact] public void DisposeDetachesTransactionsAndClearsOwnedState() { using var entities = new RuntimeEntityObjectLifetime(); var inventory = new RuntimeInventoryState(entities); inventory.ExternalContainers.RequestOpen(0x70000001u); inventory.ExternalContainers.ApplyViewContents(0x70000001u); inventory.ItemMana.OnQueryItemManaResponse(0x50000001u, 0.5f, true); inventory.Shortcuts.Replace([new ShortcutEntry(1, 2u, 3u)]); inventory.Dispose(); inventory.Dispose(); Assert.True(inventory.IsDisposed); Assert.True(inventory.Transactions.IsDisposed); Assert.Equal(0u, inventory.ExternalContainers.CurrentContainerId); Assert.False(inventory.ItemMana.HasMana(0x50000001u)); Assert.Empty(inventory.Shortcuts.Items); } [Fact] public void DisposalRetriesATransientOwnerObserverFailureToConvergence() { using var entities = new RuntimeEntityObjectLifetime(); var inventory = new RuntimeInventoryState(entities); inventory.ExternalContainers.RequestOpen(0x70000001u); inventory.ExternalContainers.ApplyViewContents(0x70000001u); bool fail = true; inventory.ExternalContainers.Changed += _ => { if (fail) { fail = false; throw new InvalidOperationException("transient"); } }; Assert.Throws(inventory.Dispose); Assert.False(inventory.IsDisposed); Assert.True(inventory.Transactions.IsDisposed); inventory.Dispose(); Assert.True(inventory.IsDisposed); Assert.Equal(0u, inventory.ExternalContainers.CurrentContainerId); } }