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
|
|
@ -511,6 +511,7 @@ public sealed class CurrentGameRuntimeAdapterTests
|
|||
EquippedChildren = noop,
|
||||
ExternalContainer = noop,
|
||||
InteractionAndSelection = noop,
|
||||
InventoryTransactions = noop,
|
||||
SelectionPresentation = noop,
|
||||
ObjectTable = noop,
|
||||
Spellbook = noop,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
namespace AcDream.App.Tests.Runtime;
|
||||
|
||||
public sealed class RuntimeInventoryOwnershipTests
|
||||
{
|
||||
[Fact]
|
||||
public void ProductionConstructsOnlyTheRuntimeInventoryOwner()
|
||||
{
|
||||
string source = ReadSource("Rendering", "GameWindow.cs");
|
||||
|
||||
Assert.Contains(
|
||||
"_runtimeInventory = new RuntimeInventoryState(_runtimeEntityObjects);",
|
||||
source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain(
|
||||
"new AcDream.Core.Items.ItemManaState",
|
||||
source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain(
|
||||
"new DesiredComponentSnapshotState",
|
||||
source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain(
|
||||
"new ShortcutSnapshotState",
|
||||
source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain(
|
||||
"new AcDream.Core.Items.ExternalContainerState",
|
||||
source,
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UiSessionAndShutdownBorrowTheExactRuntimeOwner()
|
||||
{
|
||||
string ui = ReadSource(
|
||||
"Composition",
|
||||
"InteractionRetainedUiComposition.cs");
|
||||
string session = ReadSource("Net", "LiveSessionRuntimeFactory.cs");
|
||||
string shutdown = ReadSource("Rendering", "GameWindowLifetime.cs");
|
||||
|
||||
Assert.Contains(
|
||||
"transactions: d.Inventory.Transactions",
|
||||
ui,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"OnShortcuts: _domain.Inventory.Shortcuts.Replace",
|
||||
session,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"_domain.Inventory.Transactions.CompleteUse(error)",
|
||||
session,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"OnDesiredComponents: _domain.Inventory.DesiredComponents.Replace",
|
||||
session,
|
||||
StringComparison.Ordinal);
|
||||
AssertAppearsInOrder(
|
||||
shutdown,
|
||||
"\"runtime inventory state\"",
|
||||
"\"runtime entity/object lifetime\"");
|
||||
}
|
||||
|
||||
private static string ReadSource(params string[] relative)
|
||||
{
|
||||
string root = FindRepositoryRoot();
|
||||
return File.ReadAllText(Path.Combine(
|
||||
[root, "src", "AcDream.App", .. relative]));
|
||||
}
|
||||
|
||||
private static string FindRepositoryRoot()
|
||||
{
|
||||
var current = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (current is not null)
|
||||
{
|
||||
if (File.Exists(Path.Combine(current.FullName, "AcDream.slnx")))
|
||||
return current.FullName;
|
||||
current = current.Parent;
|
||||
}
|
||||
throw new DirectoryNotFoundException("AcDream.slnx was not found.");
|
||||
}
|
||||
|
||||
private static void AssertAppearsInOrder(
|
||||
string source,
|
||||
params string[] fragments)
|
||||
{
|
||||
int cursor = 0;
|
||||
foreach (string fragment in fragments)
|
||||
{
|
||||
int index = source.IndexOf(
|
||||
fragment,
|
||||
cursor,
|
||||
StringComparison.Ordinal);
|
||||
Assert.True(index >= 0, $"Missing source fragment: {fragment}");
|
||||
cursor = index + fragment.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue