refactor(update): cut over the frame orchestrator

Reduce GameWindow.OnUpdate to one typed orchestration call and remove transitive window callbacks from teardown, liveness, teleport placement, live presentation, auto-entry, and entity packet routing. Preserve the frozen retail object/network order while making the production owner graph explicit and testable.
This commit is contained in:
Erik 2026-07-22 03:31:38 +02:00
parent 947c61d2d7
commit e91f310279
18 changed files with 864 additions and 348 deletions

View file

@ -36,9 +36,8 @@ public sealed class UpdateFrameOrchestratorTests
[Fact]
public void ConditionalReconciles_RemainAtTheirOwningEdges()
{
// Checkpoint A freezes only the outer ownership contract. Checkpoints
// E and F must replace these probes with production teleport/camera
// owner tests before the conditional edges can be claimed guarded.
// The outer ownership oracle is complemented by the production
// teleport and camera tests that pin both conditional reconcile edges.
var calls = new List<string>();
UpdateFrameOrchestrator frame = Create(
calls,
@ -228,19 +227,6 @@ public sealed class UpdateFrameOrchestratorTests
FieldInfo[] ownerFields = owner.GetFields(
BindingFlags.Instance | BindingFlags.NonPublic);
Assert.DoesNotContain(ownerFields, field => field.FieldType == typeof(GameWindow));
if (owner == typeof(AcDream.App.Input.RetailLocalPlayerFrameController))
{
// Checkpoint D replaced input capture with its typed owner.
// Checkpoint F still owns the remaining player presentation
// callback composition. No other phase owner may add one.
Assert.Contains(
ownerFields,
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
Assert.DoesNotContain(
ownerFields,
field => field.FieldType == typeof(Func<AcDream.App.Input.MovementInput>));
continue;
}
Assert.DoesNotContain(
ownerFields,
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
@ -277,14 +263,24 @@ public sealed class UpdateFrameOrchestratorTests
[Fact]
public void ProductionFrame_PublishesPhysicsScriptTimeExactlyOnce()
{
string root = FindRepoRoot();
string source = File.ReadAllText(Path.Combine(
FindRepoRoot(),
root,
"src",
"AcDream.App",
"Rendering",
"GameWindow.cs"));
string adapters = File.ReadAllText(Path.Combine(
root,
"src",
"AcDream.App",
"Update",
"UpdateFrameRuntimeAdapters.cs"));
Assert.Equal(1, source.Split("PublishTime(", StringSplitOptions.None).Length - 1);
Assert.Equal(0, CountOccurrences(source, "PublishTime("));
Assert.Equal(1, CountOccurrences(adapters, "_runner.PublishTime("));
Assert.Contains("new AcDream.App.Update.PhysicsScriptClockPublisher(", source,
StringComparison.Ordinal);
}
[Fact]
@ -363,12 +359,10 @@ public sealed class UpdateFrameOrchestratorTests
"GameWindow.cs"));
Assert.Contains("new AcDream.App.Streaming.StreamingFrameController(", source);
Assert.Equal(1, CountOccurrences(source, "_streamingFrame.Tick();"));
AssertAppearsInOrder(
Assert.DoesNotContain("_streamingFrame", source, StringComparison.Ordinal);
Assert.Equal(1, CountOccurrences(
source,
"_streamingFrame.Tick();",
"_gameplayInputFrame!.Tick(frameTiming);",
"_liveFrameCoordinator.Tick(frameDelta);");
"_updateFrameOrchestrator.Tick("));
Assert.DoesNotContain("_streamingController.Tick(observerCx", source,
StringComparison.Ordinal);
Assert.DoesNotContain("DungeonStreamingGate.Compute", source,
@ -387,7 +381,8 @@ public sealed class UpdateFrameOrchestratorTests
"GameWindow.cs"));
Assert.Contains("new AcDream.App.Input.GameplayInputFrameController(", source);
Assert.Equal(1, CountOccurrences(source, "_gameplayInputFrame!.Tick(frameTiming);"));
Assert.DoesNotContain("_gameplayInputFrame!.Tick", source,
StringComparison.Ordinal);
Assert.DoesNotContain("_inputDispatcher?.Tick()", source,
StringComparison.Ordinal);
Assert.DoesNotContain("TryTakeRawSample", source,
@ -468,9 +463,8 @@ public sealed class UpdateFrameOrchestratorTests
"new AcDream.App.Streaming.LocalPlayerTeleportController(",
source,
StringComparison.Ordinal);
Assert.Equal(1, CountOccurrences(
source,
"_localPlayerTeleport!.Tick(frameDelta);"));
Assert.DoesNotContain("_localPlayerTeleport!.Tick", source,
StringComparison.Ordinal);
Assert.DoesNotContain("_teleportTransit", source, StringComparison.Ordinal);
Assert.DoesNotContain("_teleportAnim", source, StringComparison.Ordinal);
Assert.DoesNotContain("_teleportViewPlane", source, StringComparison.Ordinal);
@ -486,9 +480,10 @@ public sealed class UpdateFrameOrchestratorTests
StringComparison.Ordinal);
AssertAppearsInOrder(
source,
"_liveEntityLiveness?.Tick(ClientTimerNow());",
"_localPlayerTeleport!.Tick(frameDelta);",
"_playerModeAutoEntry?.TryEnter();");
"new AcDream.App.Update.LiveEntityLivenessFramePhase(",
"_localPlayerTeleport,",
"new AcDream.App.Update.PlayerModeAutoEntryFramePhase(",
"cameraFrame);");
}
[Fact]
@ -649,7 +644,9 @@ public sealed class UpdateFrameOrchestratorTests
"AcDream.App",
"Rendering",
"GameWindow.cs"));
Assert.Equal(1, CountOccurrences(source, "_cameraFrame.Tick(frameTiming);"));
Assert.Equal(1, CountOccurrences(
source,
"_updateFrameOrchestrator.Tick("));
Assert.DoesNotContain("CanAdvanceLocalPlayer", source, StringComparison.Ordinal);
Assert.DoesNotContain("GetCombatCameraTargetPoint()", source,
StringComparison.Ordinal);
@ -657,11 +654,7 @@ public sealed class UpdateFrameOrchestratorTests
StringComparison.Ordinal);
Assert.DoesNotContain("_localPlayerFrame.TryGetPresentationAfterNetwork", source,
StringComparison.Ordinal);
AssertAppearsInOrder(
source,
"_localPlayerTeleport!.Tick(frameDelta);",
"_playerModeAutoEntry?.TryEnter();",
"_cameraFrame.Tick(frameTiming);");
Assert.DoesNotContain("_cameraFrame", source, StringComparison.Ordinal);
string cameraSource = File.ReadAllText(Path.Combine(
root,
@ -677,6 +670,123 @@ public sealed class UpdateFrameOrchestratorTests
"retail?.Update(");
}
[Fact]
public void GameWindow_OnUpdateOwnsOnlyProfilingAndOneOrchestratorTick()
{
string source = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Rendering",
"GameWindow.cs"));
Assert.Equal(1, CountOccurrences(
source,
"_updateFrameOrchestrator.Tick("));
Assert.DoesNotContain("_updateFrameClock.Advance(", source,
StringComparison.Ordinal);
Assert.DoesNotContain("_liveFrameCoordinator", source,
StringComparison.Ordinal);
Assert.DoesNotContain("_liveEntityLiveness?.Tick", source,
StringComparison.Ordinal);
Assert.DoesNotContain("_playerModeAutoEntry?.TryEnter", source,
StringComparison.Ordinal);
AssertAppearsInOrder(
source,
"private void OnUpdate(double dt)",
"_frameProfiler.BeginStage(",
"_updateFrameOrchestrator.Tick(",
"private void OnCameraModeChanged");
}
[Fact]
public void ProductionFrameAdaptersRetainTypedOwnersWithoutWindowCallbacks()
{
Type[] adapters =
[
typeof(LiveEntityTeardownFramePhase),
typeof(ConsoleUpdateFrameFailureSink),
typeof(PhysicsScriptClockPublisher),
typeof(LiveEntityLivenessFramePhase),
typeof(PlayerModeAutoEntryFramePhase),
];
foreach (Type adapter in adapters)
{
FieldInfo[] fields = adapter.GetFields(
BindingFlags.Instance | BindingFlags.NonPublic);
Assert.DoesNotContain(fields, field => field.FieldType == typeof(GameWindow));
Assert.DoesNotContain(
fields,
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
}
FieldInfo clock = Assert.Single(
typeof(LiveEntityLivenessFramePhase).GetFields(
BindingFlags.Instance | BindingFlags.NonPublic),
field => field.Name == "_clock");
Assert.Equal(typeof(IClientMonotonicTimeSource), clock.FieldType);
FieldInfo teardownRuntime = Assert.Single(
typeof(LiveEntityTeardownFramePhase).GetFields(
BindingFlags.Instance | BindingFlags.NonPublic));
Assert.Equal(typeof(LiveEntityRuntime), teardownRuntime.FieldType);
Type[] typedProductionOwners =
[
typeof(LiveEntityLivenessController),
typeof(AcDream.App.Input.LivePlayerModeAutoEntryContext),
typeof(LiveSessionLocalPhysicsTimestampPublisher),
typeof(AcDream.App.Physics.LiveEntityNetworkUpdateController),
typeof(AcDream.App.Rendering.LiveEntityPartArrayLifecycle),
typeof(AcDream.App.Physics.RemoteShadowPlacementSynchronizer),
typeof(AcDream.App.Physics.RemoteTeleportPlacementPresentation),
typeof(AcDream.App.Net.LiveEntitySessionController),
];
foreach (Type owner in typedProductionOwners)
{
FieldInfo[] fields = owner.GetFields(
BindingFlags.Instance | BindingFlags.NonPublic);
Assert.DoesNotContain(fields, field => field.FieldType == typeof(GameWindow));
Assert.DoesNotContain(
fields,
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
}
FieldInfo originIdentity = Assert.Single(
typeof(LiveEntityWorldOriginCoordinator).GetFields(
BindingFlags.Instance | BindingFlags.NonPublic),
field => field.Name == "_identity");
Assert.Equal(
typeof(AcDream.App.Input.ILocalPlayerIdentitySource),
originIdentity.FieldType);
string source = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Rendering",
"GameWindow.cs"));
Assert.DoesNotContain("PublishLocalPhysicsTimestamps", source,
StringComparison.Ordinal);
Assert.DoesNotContain("LoginWorldReady", source,
StringComparison.Ordinal);
Assert.DoesNotContain("candidate => _liveEntityHydration.OnPrune", source,
StringComparison.Ordinal);
Assert.DoesNotContain("CreateLiveEntitySessionSink", source,
StringComparison.Ordinal);
Assert.DoesNotContain("private System.Numerics.Vector3 CellLocalForSeed", source,
StringComparison.Ordinal);
Assert.DoesNotContain("OnPlayScriptReceived", source,
StringComparison.Ordinal);
Assert.Contains("_liveWorldOrigin.GetCenter", source,
StringComparison.Ordinal);
Assert.Contains("_liveWorldOrigin.CellLocalForSeed", source,
StringComparison.Ordinal);
Assert.Contains("_liveEntitySessionEvents.CreateSink()", source,
StringComparison.Ordinal);
}
private static UpdateFrameOrchestrator Create(
List<string> calls,
RecordingTeardown? teardown = null,