test: replace composition source freezes

This commit is contained in:
Erik 2026-08-18 15:50:53 +02:00
parent caa5eb8b2b
commit 80c7b44457
8 changed files with 471 additions and 406 deletions

View file

@ -6,12 +6,15 @@ using AcDream.App.Physics;
using AcDream.App.Rendering;
using AcDream.App.Rendering.Residency;
using AcDream.App.Rendering.Vfx;
using AcDream.App.Rendering.Wb;
using AcDream.App.Spells;
using AcDream.App.Tests.Architecture;
using AcDream.Content;
using AcDream.Content.Vfx;
using AcDream.Core.Audio;
using AcDream.Core.CharGen;
using AcDream.Core.Lighting;
using AcDream.Core.Meshing;
using AcDream.Core.Physics;
using AcDream.Core.Rendering;
using AcDream.Core.Spells;
@ -20,6 +23,7 @@ using AcDream.Runtime.Gameplay;
using AcDream.Runtime.Physics;
using AcDream.Runtime.Session;
using DatReaderWriter.DBObjs;
using DatReaderWriter.Lib.IO;
using Silk.NET.Input;
using Silk.NET.OpenAL;
@ -163,84 +167,73 @@ public sealed class ContentEffectsAudioCompositionTests
[Fact]
public void GameWindowUsesTheProductionPhaseAndNoLongerConstructsItsBodyInline()
{
string source = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Rendering",
"GameWindow.cs"));
IReadOnlyList<CompiledCall> calls =
CompiledCallGraph.ReadDeclared(typeof(GameWindow));
Assert.Contains("new ContentEffectsAudioCompositionPhase(", source,
StringComparison.Ordinal);
Assert.Single(
calls,
call => call.Target.DeclaringType
== typeof(ContentEffectsAudioCompositionPhase)
&& call.Target.IsConstructor);
Assert.DoesNotContain(
"_dats = RuntimeDatCollectionFactory.OpenReadOnly(_datDir);",
source,
StringComparison.Ordinal);
Assert.DoesNotContain("_hookRouter.Register(_particleSink)", source,
StringComparison.Ordinal);
Assert.DoesNotContain("new AcDream.App.Audio.OpenAlAudioEngine()", source,
StringComparison.Ordinal);
calls,
call => call.Target.DeclaringType
== typeof(RuntimeDatCollectionFactory)
&& call.Target.Name == nameof(RuntimeDatCollectionFactory.OpenReadOnly));
Assert.DoesNotContain(
calls,
call => call.Target.DeclaringType == typeof(AnimationHookRouter)
&& call.Target.Name == nameof(AnimationHookRouter.Register));
Assert.DoesNotContain(
calls,
call => call.Target.DeclaringType == typeof(OpenAlAudioEngine)
&& call.Target.IsConstructor);
}
[Fact]
public void ProductionRendererConsumesOnlyThePublishedPreparedAssetSource()
{
string root = FindRepoRoot();
string contentPhase = File.ReadAllText(Path.Combine(
root,
"src",
"AcDream.App",
"Composition",
"ContentEffectsAudioComposition.cs"));
string worldPhase = File.ReadAllText(Path.Combine(
root,
"src",
"AcDream.App",
"Composition",
"WorldRenderComposition.cs"));
string manager = File.ReadAllText(Path.Combine(
root,
"src",
"AcDream.App",
"Rendering",
"Wb",
"ObjectMeshManager.cs"));
string adapter = File.ReadAllText(Path.Combine(
root,
"src",
"AcDream.App",
"Rendering",
"Wb",
"WbMeshAdapter.cs"));
string lifetime = File.ReadAllText(Path.Combine(
root,
"src",
"AcDream.App",
"Rendering",
"GameWindowLifetime.cs"));
MethodInfo openPrepared = typeof(RetailContentEffectsAudioCompositionFactory)
.GetMethod(nameof(
RetailContentEffectsAudioCompositionFactory.OpenPreparedAssetSource))!;
Assert.Contains(
CompiledCallGraph.Read(openPrepared),
call => call.Target.DeclaringType == typeof(PakPreparedAssetSource)
&& call.Target.IsConstructor);
Assert.Contains("new PakPreparedAssetSource(path, dats, diagnostic)",
contentPhase, StringComparison.Ordinal);
Assert.Contains("content.PreparedAssets", worldPhase,
StringComparison.Ordinal);
Assert.Contains("_preparedAssets.Read(request.Asset, ct)", manager,
StringComparison.Ordinal);
Assert.DoesNotContain("MeshExtractor", manager,
StringComparison.Ordinal);
Assert.DoesNotContain("IDatReaderWriter", manager,
StringComparison.Ordinal);
Assert.DoesNotContain("GfxObjMesh.Build", adapter,
StringComparison.Ordinal);
MethodInfo compose = typeof(WorldRenderCompositionPhase)
.GetMethod(nameof(WorldRenderCompositionPhase.Compose))!;
IReadOnlyList<CompiledCall> worldCalls = CompiledCallGraph.Read(compose);
Assert.Contains(
worldCalls,
call => call.Target.DeclaringType == typeof(ContentEffectsAudioResult)
&& call.Target.Name == "get_PreparedAssets");
int meshStage = lifetime.IndexOf(
"new ResourceShutdownStage(\"mesh adapter\"",
StringComparison.Ordinal);
int preparedRelease = lifetime.IndexOf(
"Hard(\"prepared asset source\"",
StringComparison.Ordinal);
int datRelease = lifetime.IndexOf(
"Hard(\"DAT collection\"",
StringComparison.Ordinal);
FieldInfo preparedAssets = Assert.Single(
typeof(ObjectMeshManager).GetFields(
BindingFlags.Instance | BindingFlags.NonPublic),
field => field.FieldType == typeof(IPreparedAssetSource));
Assert.Equal("_preparedAssets", preparedAssets.Name);
Assert.DoesNotContain(
typeof(ObjectMeshManager).GetConstructors(),
constructor => constructor.GetParameters().Any(parameter =>
parameter.ParameterType == typeof(IDatReaderWriter)));
Assert.Contains(
CompiledCallGraph.ReadDeclared(typeof(ObjectMeshManager)),
call => call.Target.DeclaringType == typeof(IPreparedAssetSource)
&& call.Target.Name == nameof(IPreparedAssetSource.Read));
Assert.DoesNotContain(
CompiledCallGraph.ReadDeclared(typeof(WbMeshAdapter)),
call => call.Target.DeclaringType == typeof(GfxObjMesh)
&& call.Target.Name == nameof(GfxObjMesh.Build));
MethodInfo shutdown = typeof(GameWindowShutdownManifest).GetMethod(
nameof(GameWindowShutdownManifest.Create))!;
List<string> labels =
CompiledCallGraph.ReadStringLiterals(shutdown).ToList();
int meshStage = labels.IndexOf("mesh adapter");
int preparedRelease = labels.IndexOf("prepared asset source");
int datRelease = labels.IndexOf("DAT collection");
Assert.True(meshStage >= 0);
Assert.True(preparedRelease > meshStage);
Assert.True(datRelease > preparedRelease);
@ -564,15 +557,4 @@ public sealed class ContentEffectsAudioCompositionTests
public void CloseDevice(nint device) { }
}
private static string FindRepoRoot()
{
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.");
}
}