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

@ -16,10 +16,11 @@ public sealed class PlayerInteractionMovementSinkTests
[Fact]
public void MissingPlayerDoesNotArmTheIntent()
{
var sink = new PlayerInteractionMovementSink(() => null);
var completions = new PlayerApproachCompletionState();
var sink = new PlayerInteractionMovementSink(() => null, completions);
bool armed = false;
Assert.False(sink.BeginApproach(Approach(closeRange: true), () => armed = true));
Assert.False(sink.BeginApproach(Approach(closeRange: true), _ => armed = true));
Assert.False(armed);
}
@ -66,11 +67,15 @@ public sealed class PlayerInteractionMovementSinkTests
new Position(Cell, new Vector3(2f, 0f, 0f), Quaternion.Identity),
new MovementParameters { UseSpheres = false });
bool armedAfterCancellation = false;
var sink = new PlayerInteractionMovementSink(() => controller);
var completions = new PlayerApproachCompletionState();
_ = completions.BeginControllerLifetime();
var sink = new PlayerInteractionMovementSink(
() => controller,
completions);
Assert.True(sink.BeginApproach(
Approach(closeRange),
() => armedAfterCancellation = cancellations == 1 && !moveTo.IsMovingTo()));
_ => armedAfterCancellation = cancellations == 1 && !moveTo.IsMovingTo()));
Assert.True(armedAfterCancellation);
Assert.True(nonAutonomousAtTargetInstall);