refactor(runtime): own canonical entity and object lifetime
Introduce one presentation-free RuntimeEntityObjectLifetime for the exact entity directory and ClientObjectTable. Make GameWindow, graphical projections, retained UI, interaction, session routing, create/delete integration, and reset borrow that owner while preserving synchronous retail ordering, dormant retention, and retry semantics. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
d9bf4c4960
commit
5ef8b5371d
40 changed files with 712 additions and 170 deletions
|
|
@ -13,8 +13,19 @@ namespace AcDream.App.Tests.World;
|
|||
public sealed class RuntimeEntityOwnershipTests
|
||||
{
|
||||
[Fact]
|
||||
public void LiveEntityRuntime_ComposesCanonicalRuntimeDirectory()
|
||||
public void LiveEntityRuntime_BorrowsCanonicalRuntimeDirectory()
|
||||
{
|
||||
var lifetime = new RuntimeEntityObjectLifetime();
|
||||
var runtime = new LiveEntityRuntime(
|
||||
new GpuWorldState(),
|
||||
new DelegateLiveEntityResourceLifecycle(
|
||||
static _ => { },
|
||||
static _ => { }),
|
||||
lifetime);
|
||||
FieldInfo owner = typeof(LiveEntityRuntime).GetField(
|
||||
"_entityObjects",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic)
|
||||
?? throw new InvalidOperationException("Missing Runtime lifetime root.");
|
||||
FieldInfo directory = typeof(LiveEntityRuntime).GetField(
|
||||
"_directory",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic)
|
||||
|
|
@ -25,9 +36,62 @@ public sealed class RuntimeEntityOwnershipTests
|
|||
?? throw new InvalidOperationException("Missing App projection sidecar store.");
|
||||
|
||||
Assert.Equal(typeof(RuntimeEntityDirectory), directory.FieldType);
|
||||
Assert.Same(lifetime, owner.GetValue(runtime));
|
||||
Assert.Same(lifetime.Entities, directory.GetValue(runtime));
|
||||
Assert.Equal(typeof(LiveEntityProjectionStore), sidecars.FieldType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProductionComposition_HasOneRuntimeEntityObjectConstructionRoot()
|
||||
{
|
||||
string root = FindRepositoryRoot();
|
||||
string appRoot = Path.Combine(root, "src", "AcDream.App");
|
||||
string runtimeRoot = Path.Combine(root, "src", "AcDream.Runtime");
|
||||
string[] appSources = Directory.GetFiles(
|
||||
appRoot,
|
||||
"*.cs",
|
||||
SearchOption.AllDirectories);
|
||||
string[] runtimeSources = Directory.GetFiles(
|
||||
runtimeRoot,
|
||||
"*.cs",
|
||||
SearchOption.AllDirectories);
|
||||
|
||||
string[] appObjectAllocators = appSources
|
||||
.Where(path => !path.Contains(
|
||||
$"{Path.DirectorySeparatorChar}Studio{Path.DirectorySeparatorChar}",
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
.Where(path => File.ReadAllText(path).Contains(
|
||||
"new ClientObjectTable",
|
||||
StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
string[] appDirectoryAllocators = appSources
|
||||
.Where(path => File.ReadAllText(path).Contains(
|
||||
"new RuntimeEntityDirectory",
|
||||
StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
string[] runtimeObjectAllocators = runtimeSources
|
||||
.Where(path => File.ReadAllText(path).Contains(
|
||||
"new ClientObjectTable",
|
||||
StringComparison.Ordinal))
|
||||
.Select(path => Path.GetFileName(path)!)
|
||||
.ToArray();
|
||||
string[] runtimeDirectoryAllocators = runtimeSources
|
||||
.Where(path => File.ReadAllText(path).Contains(
|
||||
"new RuntimeEntityDirectory",
|
||||
StringComparison.Ordinal))
|
||||
.Select(path => Path.GetFileName(path)!)
|
||||
.ToArray();
|
||||
|
||||
Assert.Empty(appObjectAllocators);
|
||||
Assert.Empty(appDirectoryAllocators);
|
||||
Assert.Equal(
|
||||
["RuntimeEntityObjectLifetime.cs"],
|
||||
runtimeObjectAllocators);
|
||||
Assert.Equal(
|
||||
["RuntimeEntityObjectLifetime.cs"],
|
||||
runtimeDirectoryAllocators);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppProjectionOwners_UseExactRuntimeKeysAndNoGuidDictionary()
|
||||
{
|
||||
|
|
@ -212,4 +276,18 @@ public sealed class RuntimeEntityOwnershipTests
|
|||
field.FieldType.IsGenericType
|
||||
&& field.FieldType.GetGenericTypeDefinition() == typeof(Dictionary<,>)
|
||||
&& field.FieldType.GetGenericArguments()[0] == keyType;
|
||||
|
||||
private static string FindRepositoryRoot()
|
||||
{
|
||||
DirectoryInfo? directory = new(AppContext.BaseDirectory);
|
||||
while (directory is not null)
|
||||
{
|
||||
if (File.Exists(Path.Combine(directory.FullName, "AcDream.slnx")))
|
||||
return directory.FullName;
|
||||
directory = directory.Parent;
|
||||
}
|
||||
|
||||
throw new DirectoryNotFoundException(
|
||||
$"Could not find AcDream.slnx above {AppContext.BaseDirectory}.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue