refactor(runtime): extract local teleport and player mode

Move local teleport, player-mode, animation, shadow, and sealed-dungeon lifetimes out of GameWindow. Make player-mode entry transactional and isolate approach completions by controller lifetime and approach generation so stale callbacks cannot affect replacements.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-22 02:50:15 +02:00
parent c557038353
commit eeb0f6b45c
29 changed files with 3311 additions and 1073 deletions

View file

@ -414,18 +414,32 @@ public sealed class UpdateFrameOrchestratorTests
StringComparison.Ordinal);
Assert.DoesNotContain("wantCaptureMouse: ()", source,
StringComparison.Ordinal);
Assert.Equal(5, CountOccurrences(
Assert.Equal(2, CountOccurrences(
source,
"_gameplayInputFrame?.EndMouseLook();"));
Assert.Contains(
"new(\"mouse capture\", () => _gameplayInputFrame?.EndMouseLook())",
source,
StringComparison.Ordinal);
string teleportSource = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Streaming",
"LocalPlayerTeleportController.cs"));
AssertAppearsInOrder(
source,
"_teleportTransit.CanBegin(teleportSequence)",
"_gameplayInputFrame?.EndMouseLook();",
"_teleportTransit.QueueStart(teleportSequence)");
teleportSource,
"_transit.CanBegin(teleportSequence)",
"_input.EndMouseLook();",
"_transit.QueueStart(teleportSequence)");
string playerModeSource = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Input",
"PlayerModeController.cs"));
Assert.Contains("_input.EndMouseLook();", playerModeSource,
StringComparison.Ordinal);
AssertAppearsInOrder(
source,
"private void OnFocusChanged(bool focused)",
@ -433,6 +447,50 @@ public sealed class UpdateFrameOrchestratorTests
"_gameplayInputFrame?.EndMouseLook();");
}
[Fact]
public void GameWindow_DelegatesTheCompleteLocalTeleportLifetime()
{
string root = FindRepoRoot();
string source = File.ReadAllText(Path.Combine(
root,
"src",
"AcDream.App",
"Rendering",
"GameWindow.cs"));
string networkSource = File.ReadAllText(Path.Combine(
root,
"src",
"AcDream.App",
"Physics",
"LiveEntityNetworkUpdateController.cs"));
Assert.Contains(
"new AcDream.App.Streaming.LocalPlayerTeleportController(",
source,
StringComparison.Ordinal);
Assert.Equal(1, CountOccurrences(
source,
"_localPlayerTeleport!.Tick(frameDelta);"));
Assert.DoesNotContain("_teleportTransit", source, StringComparison.Ordinal);
Assert.DoesNotContain("_teleportAnim", source, StringComparison.Ordinal);
Assert.DoesNotContain("_teleportViewPlane", source, StringComparison.Ordinal);
Assert.DoesNotContain("_pendingTeleport", source, StringComparison.Ordinal);
Assert.DoesNotContain("AimTeleportDestination", source, StringComparison.Ordinal);
Assert.DoesNotContain("ResetTeleportTransitState", source, StringComparison.Ordinal);
Assert.DoesNotContain("PlaceTeleportArrival", source, StringComparison.Ordinal);
Assert.DoesNotContain("TryActivatePendingTeleportPresentation", source,
StringComparison.Ordinal);
Assert.DoesNotContain("Action<WorldSession.EntityPositionUpdate>", networkSource,
StringComparison.Ordinal);
Assert.Contains("ILocalPlayerTeleportNetworkSink", networkSource,
StringComparison.Ordinal);
AssertAppearsInOrder(
source,
"_liveEntityLiveness?.Tick(ClientTimerNow());",
"_localPlayerTeleport!.Tick(frameDelta);",
"_playerModeAutoEntry?.TryEnter();");
}
[Fact]
public void GameplayInputOwnersUseTypedSeamsWithoutGameWindowBackReferences()
{
@ -498,6 +556,45 @@ public sealed class UpdateFrameOrchestratorTests
BindingFlags.Instance | BindingFlags.NonPublic),
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
FieldInfo approachCompletions = Assert.Single(
typeof(AcDream.App.Input.PlayerModeController).GetFields(
BindingFlags.Instance | BindingFlags.NonPublic),
field => field.Name == "_approachCompletions");
Assert.Equal(
typeof(AcDream.App.Interaction.IPlayerApproachCompletionLifetimeOwner),
approachCompletions.FieldType);
Assert.DoesNotContain(
typeof(AcDream.App.Input.PlayerModeController).GetFields(
BindingFlags.Instance | BindingFlags.NonPublic),
field => field.FieldType
== typeof(AcDream.App.Interaction.SelectionInteractionController));
Assert.DoesNotContain(
typeof(AcDream.App.Interaction.PlayerApproachCompletionState).GetFields(
BindingFlags.Instance | BindingFlags.NonPublic),
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
string playerModeSource = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",
"AcDream.App",
"Input",
"PlayerModeController.cs"));
AssertAppearsInOrder(
playerModeSource,
"controller.PreparePositionForCommit(",
"_camera.EnterChaseMode(legacyCamera, retailCamera);",
"EntityPhysicsHost.SelectStableHostWithoutRebind(",
"_shadow.SyncPose(",
"EntityPhysicsHost.InstallOrRebind(",
"playerEntity.SetPosition(initial.Position);",
"controller.CommitPreparedPosition();",
"_controllerSlot.Controller = controller;",
"_mode.IsPlayerMode = true;");
Assert.Contains("_shadow.Restore(playerEntity, priorShadow);", playerModeSource,
StringComparison.Ordinal);
Assert.Contains("_camera.RestoreState(priorCamera);", playerModeSource,
StringComparison.Ordinal);
string mouseLookSource = File.ReadAllText(Path.Combine(
FindRepoRoot(),
"src",