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:
Erik 2026-07-18 21:35:16 +02:00
parent 3971997689
commit 749e8ceeb1
225 changed files with 29107 additions and 3914 deletions

View 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.");
}
}