fix(rendering): bound portal resource lifetime
Separate logical ownership, render publication, and GPU retirement across live entities, landblocks, particles, textures, mesh arenas, portal/UI teardown, and per-frame scratch storage. Add bounded DAT/texture caches, upload budgets, three-frame fence retirement, exact-incarnation appearance reconciliation, frame pacing, and extensive lifetime conformance coverage.\n\nThe seven-destination connected route now cuts peak working/private memory roughly in half, returns Caul to 125-153 FPS locally, and produces no WER or AMD reset.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
3971997689
commit
749e8ceeb1
225 changed files with 29107 additions and 3914 deletions
91
tests/AcDream.App.Tests/RuntimeDatAccessArchitectureTests.cs
Normal file
91
tests/AcDream.App.Tests/RuntimeDatAccessArchitectureTests.cs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
using DatReaderWriter;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace AcDream.App.Tests;
|
||||
|
||||
public sealed class RuntimeDatAccessArchitectureTests
|
||||
{
|
||||
[Fact]
|
||||
public void ProductionAppTypes_DoNotStoreOrAcceptRawDatCollection()
|
||||
{
|
||||
Type rawType = typeof(DatReaderWriter.DatCollection);
|
||||
Type ownerType = typeof(RuntimeDatCollection);
|
||||
Type[] appTypes = typeof(RuntimeDatCollectionFactory).Assembly.GetTypes();
|
||||
var violations = new List<string>();
|
||||
|
||||
foreach (Type type in appTypes.Where(type => type != ownerType))
|
||||
{
|
||||
foreach (FieldInfo field in type.GetFields(
|
||||
BindingFlags.Instance | BindingFlags.Static |
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
|
||||
{
|
||||
if (field.FieldType == rawType)
|
||||
violations.Add($"{type.FullName} field {field.Name}");
|
||||
}
|
||||
|
||||
foreach (PropertyInfo property in type.GetProperties(
|
||||
BindingFlags.Instance | BindingFlags.Static |
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
|
||||
{
|
||||
if (property.PropertyType == rawType)
|
||||
violations.Add($"{type.FullName} property {property.Name}");
|
||||
}
|
||||
|
||||
foreach (MethodBase method in type.GetMethods(
|
||||
BindingFlags.Instance | BindingFlags.Static |
|
||||
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
|
||||
.Cast<MethodBase>()
|
||||
.Concat(type.GetConstructors(
|
||||
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)))
|
||||
{
|
||||
if (method.GetParameters().Any(parameter => parameter.ParameterType == rawType))
|
||||
violations.Add($"{type.FullName} method {method.Name}");
|
||||
if (method is MethodInfo info && info.ReturnType == rawType)
|
||||
violations.Add($"{type.FullName} return {method.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
Assert.Empty(violations);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProductionSource_CreatesRawHandlesAndBoundedAdapterOnlyInRuntimeOwner()
|
||||
{
|
||||
string root = FindRepoRoot();
|
||||
string appRoot = Path.Combine(root, "src", "AcDream.App");
|
||||
string ownerPath = Path.GetFullPath(
|
||||
Path.Combine(appRoot, "RuntimeDatCollectionFactory.cs"));
|
||||
string[] sources = Directory.GetFiles(appRoot, "*.cs", SearchOption.AllDirectories);
|
||||
|
||||
string[] rawCreates = FindMatchingFiles(sources, @"\bnew\s+DatCollection\s*\(");
|
||||
string[] adapterCreates = FindMatchingFiles(sources, @"\bnew\s+DatCollectionAdapter\s*\(");
|
||||
string[] rawTypedReads = FindMatchingFiles(
|
||||
sources,
|
||||
@"\.Db\s*\.\s*(?:Get|TryGet)\s*<");
|
||||
|
||||
Assert.Equal([ownerPath], rawCreates);
|
||||
Assert.Equal([ownerPath], adapterCreates);
|
||||
Assert.Empty(rawTypedReads);
|
||||
}
|
||||
|
||||
private static string[] FindMatchingFiles(IEnumerable<string> sources, string pattern) =>
|
||||
sources
|
||||
.Where(path => Regex.IsMatch(File.ReadAllText(path), pattern))
|
||||
.Select(Path.GetFullPath)
|
||||
.OrderBy(path => path, StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
|
||||
private static string FindRepoRoot()
|
||||
{
|
||||
string? dir = AppContext.BaseDirectory;
|
||||
while (dir is not null)
|
||||
{
|
||||
if (File.Exists(Path.Combine(dir, "AcDream.slnx")))
|
||||
return dir;
|
||||
dir = Directory.GetParent(dir)?.FullName;
|
||||
}
|
||||
|
||||
throw new DirectoryNotFoundException("Could not locate AcDream.slnx.");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue