refactor(input): extract the gameplay frame
This commit is contained in:
parent
0bc9fda9de
commit
c557038353
24 changed files with 2433 additions and 559 deletions
|
|
@ -230,12 +230,15 @@ public sealed class UpdateFrameOrchestratorTests
|
|||
Assert.DoesNotContain(ownerFields, field => field.FieldType == typeof(GameWindow));
|
||||
if (owner == typeof(AcDream.App.Input.RetailLocalPlayerFrameController))
|
||||
{
|
||||
// Checkpoint B deliberately leaves this single legacy callback
|
||||
// composition for D/F, which own input capture and the mutable
|
||||
// player-mode/controller slot. No other phase owner may add one.
|
||||
// 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(
|
||||
|
|
@ -364,7 +367,7 @@ public sealed class UpdateFrameOrchestratorTests
|
|||
AssertAppearsInOrder(
|
||||
source,
|
||||
"_streamingFrame.Tick();",
|
||||
"_inputDispatcher?.Tick();",
|
||||
"_gameplayInputFrame!.Tick(frameTiming);",
|
||||
"_liveFrameCoordinator.Tick(frameDelta);");
|
||||
Assert.DoesNotContain("_streamingController.Tick(observerCx", source,
|
||||
StringComparison.Ordinal);
|
||||
|
|
@ -373,6 +376,152 @@ public sealed class UpdateFrameOrchestratorTests
|
|||
Assert.DoesNotContain("DrainRescued()", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GameWindow_DelegatesTheCompleteGameplayInputFrameBody()
|
||||
{
|
||||
string source = File.ReadAllText(Path.Combine(
|
||||
FindRepoRoot(),
|
||||
"src",
|
||||
"AcDream.App",
|
||||
"Rendering",
|
||||
"GameWindow.cs"));
|
||||
|
||||
Assert.Contains("new AcDream.App.Input.GameplayInputFrameController(", source);
|
||||
Assert.Equal(1, CountOccurrences(source, "_gameplayInputFrame!.Tick(frameTiming);"));
|
||||
Assert.DoesNotContain("_inputDispatcher?.Tick()", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("TryTakeRawSample", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("_combatAttackController?.Tick()", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("CaptureMovementInput", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("EndMouseLookAndRestoreCursor", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("HideCursorForMouseLook", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("RestoreCursorAfterMouseLook", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("CanStartLiveCombatAttack", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("SendLiveCombatAttack", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("PreparePlayerForAttackRequest", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("DumpMovementTruthOutbound", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("DumpMovementTruthServerEcho", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("wantCaptureMouse: ()", source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Equal(5, CountOccurrences(
|
||||
source,
|
||||
"_gameplayInputFrame?.EndMouseLook();"));
|
||||
Assert.Contains(
|
||||
"new(\"mouse capture\", () => _gameplayInputFrame?.EndMouseLook())",
|
||||
source,
|
||||
StringComparison.Ordinal);
|
||||
AssertAppearsInOrder(
|
||||
source,
|
||||
"_teleportTransit.CanBegin(teleportSequence)",
|
||||
"_gameplayInputFrame?.EndMouseLook();",
|
||||
"_teleportTransit.QueueStart(teleportSequence)");
|
||||
AssertAppearsInOrder(
|
||||
source,
|
||||
"private void OnFocusChanged(bool focused)",
|
||||
"if (!focused)",
|
||||
"_gameplayInputFrame?.EndMouseLook();");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GameplayInputOwnersUseTypedSeamsWithoutGameWindowBackReferences()
|
||||
{
|
||||
Type[] owners =
|
||||
[
|
||||
typeof(AcDream.App.Input.GameplayInputFrameController),
|
||||
typeof(AcDream.App.Input.DispatcherMovementInputSource),
|
||||
typeof(AcDream.App.Input.MouseLookController),
|
||||
];
|
||||
|
||||
foreach (Type owner in owners)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
Assert.DoesNotContain(
|
||||
typeof(AcDream.App.Input.MouseLookController).GetFields(
|
||||
BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
field => field.FieldType == typeof(Silk.NET.Input.IMouse));
|
||||
|
||||
FieldInfo combatOperations = Assert.Single(
|
||||
typeof(AcDream.App.Combat.CombatAttackController).GetFields(
|
||||
BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
field => field.Name == "_operations");
|
||||
Assert.Equal(
|
||||
typeof(AcDream.App.Combat.ICombatAttackOperations),
|
||||
combatOperations.FieldType);
|
||||
Assert.DoesNotContain(
|
||||
typeof(AcDream.App.Combat.LiveCombatAttackOperations).GetFields(
|
||||
BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
|
||||
FieldInfo combatTargets = Assert.Single(
|
||||
typeof(AcDream.App.Combat.LiveCombatAttackOperations).GetFields(
|
||||
BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
field => field.Name == "_targets");
|
||||
Assert.Equal(
|
||||
typeof(AcDream.App.Combat.ICombatAttackTargetSource),
|
||||
combatTargets.FieldType);
|
||||
Assert.DoesNotContain(
|
||||
typeof(AcDream.App.Combat.CombatAttackTargetSource).GetFields(
|
||||
BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
|
||||
Assert.DoesNotContain(
|
||||
typeof(AcDream.App.Combat.CombatAttackTargetSource).GetFields(
|
||||
BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
field => field.FieldType
|
||||
== typeof(AcDream.App.Interaction.SelectionInteractionController));
|
||||
|
||||
FieldInfo outboundDiagnostics = Assert.Single(
|
||||
typeof(AcDream.App.Input.LocalPlayerOutboundController).GetFields(
|
||||
BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
field => field.Name == "_diagnostic");
|
||||
Assert.Equal(
|
||||
typeof(AcDream.App.Input.IMovementTruthDiagnosticSink),
|
||||
outboundDiagnostics.FieldType);
|
||||
Assert.DoesNotContain(
|
||||
typeof(AcDream.App.Input.MovementTruthDiagnosticController).GetFields(
|
||||
BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
field => typeof(Delegate).IsAssignableFrom(field.FieldType));
|
||||
|
||||
string mouseLookSource = File.ReadAllText(Path.Combine(
|
||||
FindRepoRoot(),
|
||||
"src",
|
||||
"AcDream.App",
|
||||
"Input",
|
||||
"MouseLookController.cs"));
|
||||
AssertAppearsInOrder(
|
||||
mouseLookSource,
|
||||
"controller?.StopMouseDrift",
|
||||
"retail.FilterMouseDelta",
|
||||
"_state.ApplyDelta");
|
||||
|
||||
string localPlayerSource = File.ReadAllText(Path.Combine(
|
||||
FindRepoRoot(),
|
||||
"src",
|
||||
"AcDream.App",
|
||||
"Input",
|
||||
"RetailLocalPlayerFrameController.cs"));
|
||||
Assert.DoesNotContain("Func<MovementInput>", localPlayerSource,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("IMovementInputSource", localPlayerSource,
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static UpdateFrameOrchestrator Create(
|
||||
List<string> calls,
|
||||
RecordingTeardown? teardown = null,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue