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>
91 lines
3.6 KiB
C#
91 lines
3.6 KiB
C#
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.");
|
|
}
|
|
}
|