refactor(app): close ordered startup composition
This commit is contained in:
parent
54244d31f1
commit
530b4bd8f5
16 changed files with 537 additions and 215 deletions
|
|
@ -42,6 +42,65 @@ public sealed class GameWindowCompositionPipelineTests
|
|||
Assert.Equal("phase-9", phases.Calls[^1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProductionDelegateEntryUsesTheSamePipelineAndExactResults()
|
||||
{
|
||||
var calls = new List<int>();
|
||||
var values = Enumerable.Range(0, 9).Select(value => new Token(value)).ToArray();
|
||||
|
||||
GameWindowCompositionPipeline.Run<
|
||||
Token,
|
||||
Token,
|
||||
Token,
|
||||
Token,
|
||||
Token,
|
||||
Token,
|
||||
Token,
|
||||
Token,
|
||||
Token>(
|
||||
values[0],
|
||||
platform => Pass(1, values[1], platform),
|
||||
(platform, host) => Pass(2, values[2], platform, host),
|
||||
(platform, host, content) => Pass(3, values[3], platform, host, content),
|
||||
(platform, content, settings) => Pass(4, values[4], platform, content, settings),
|
||||
(platform, host, content, settings, world) =>
|
||||
Pass(5, values[5], platform, host, content, settings, world),
|
||||
(platform, host, content, settings, world, interaction) =>
|
||||
Pass(6, values[6], platform, host, content, settings, world, interaction),
|
||||
(host, content, settings, world, interaction, live) =>
|
||||
Pass(7, values[7], host, content, settings, world, interaction, live),
|
||||
(platform, host, content, settings, world, interaction, live, session) =>
|
||||
Pass(8, values[8], platform, host, content, settings, world, interaction, live, session),
|
||||
frame =>
|
||||
{
|
||||
Assert.Same(values[8], frame);
|
||||
calls.Add(9);
|
||||
});
|
||||
|
||||
Assert.Equal(Enumerable.Range(1, 9), calls);
|
||||
|
||||
Token Pass(int phase, Token result, params Token[] actual)
|
||||
{
|
||||
Token[] expected = phase switch
|
||||
{
|
||||
1 => [values[0]],
|
||||
2 => [values[0], values[1]],
|
||||
3 => [values[0], values[1], values[2]],
|
||||
4 => [values[0], values[2], values[3]],
|
||||
5 => [values[0], values[1], values[2], values[3], values[4]],
|
||||
6 => [values[0], values[1], values[2], values[3], values[4], values[5]],
|
||||
7 => [values[1], values[2], values[3], values[4], values[5], values[6]],
|
||||
8 => [values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7]],
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(phase)),
|
||||
};
|
||||
Assert.Equal(expected.Length, actual.Length);
|
||||
for (int index = 0; index < expected.Length; index++)
|
||||
Assert.Same(expected[index], actual[index]);
|
||||
calls.Add(phase);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed record Token(int Phase);
|
||||
|
||||
private sealed class RecordingPhases(int failingPhase) :
|
||||
|
|
@ -49,10 +108,10 @@ public sealed class GameWindowCompositionPipelineTests
|
|||
IContentEffectsAudioCompositionPhase<Token, Token, Token>,
|
||||
ISettingsDevToolsCompositionPhase<Token, Token, Token, Token>,
|
||||
IWorldRenderCompositionPhase<Token, Token, Token, Token>,
|
||||
IInteractionUiCompositionPhase<Token, Token, Token, Token, Token>,
|
||||
ILivePresentationCompositionPhase<Token, Token, Token, Token, Token>,
|
||||
ISessionPlayerCompositionPhase<Token, Token, Token, Token, Token, Token>,
|
||||
IFrameRootCompositionPhase<Token, Token, Token, Token, Token, Token, Token, Token>,
|
||||
IInteractionUiCompositionPhase<Token, Token, Token, Token, Token, Token>,
|
||||
ILivePresentationCompositionPhase<Token, Token, Token, Token, Token, Token, Token>,
|
||||
ISessionPlayerCompositionPhase<Token, Token, Token, Token, Token, Token, Token>,
|
||||
IFrameRootCompositionPhase<Token, Token, Token, Token, Token, Token, Token, Token, Token>,
|
||||
ISessionStartCompositionPhase<Token>
|
||||
{
|
||||
public Token Platform { get; } = new(0);
|
||||
|
|
@ -111,12 +170,14 @@ public sealed class GameWindowCompositionPipelineTests
|
|||
return _world;
|
||||
}
|
||||
|
||||
Token IInteractionUiCompositionPhase<Token, Token, Token, Token, Token>.Compose(
|
||||
Token IInteractionUiCompositionPhase<Token, Token, Token, Token, Token, Token>.Compose(
|
||||
Token platform,
|
||||
Token host,
|
||||
Token content,
|
||||
Token settings,
|
||||
Token world)
|
||||
{
|
||||
Assert.Same(Platform, platform);
|
||||
Assert.Same(_host, host);
|
||||
Assert.Same(_content, content);
|
||||
Assert.Same(_settings, settings);
|
||||
|
|
@ -125,29 +186,35 @@ public sealed class GameWindowCompositionPipelineTests
|
|||
return _interaction;
|
||||
}
|
||||
|
||||
Token ILivePresentationCompositionPhase<Token, Token, Token, Token, Token>.Compose(
|
||||
Token ILivePresentationCompositionPhase<Token, Token, Token, Token, Token, Token, Token>.Compose(
|
||||
Token platform,
|
||||
Token host,
|
||||
Token content,
|
||||
Token settings,
|
||||
Token world,
|
||||
Token interaction)
|
||||
{
|
||||
Assert.Same(Platform, platform);
|
||||
Assert.Same(_host, host);
|
||||
Assert.Same(_content, content);
|
||||
Assert.Same(_settings, settings);
|
||||
Assert.Same(_world, world);
|
||||
Assert.Same(_interaction, interaction);
|
||||
Record(6);
|
||||
return _live;
|
||||
}
|
||||
|
||||
Token ISessionPlayerCompositionPhase<Token, Token, Token, Token, Token, Token>.Compose(
|
||||
Token ISessionPlayerCompositionPhase<Token, Token, Token, Token, Token, Token, Token>.Compose(
|
||||
Token host,
|
||||
Token content,
|
||||
Token settings,
|
||||
Token world,
|
||||
Token interaction,
|
||||
Token live)
|
||||
{
|
||||
Assert.Same(_host, host);
|
||||
Assert.Same(_content, content);
|
||||
Assert.Same(_settings, settings);
|
||||
Assert.Same(_world, world);
|
||||
Assert.Same(_interaction, interaction);
|
||||
Assert.Same(_live, live);
|
||||
|
|
@ -155,7 +222,8 @@ public sealed class GameWindowCompositionPipelineTests
|
|||
return _session;
|
||||
}
|
||||
|
||||
Token IFrameRootCompositionPhase<Token, Token, Token, Token, Token, Token, Token, Token>.Compose(
|
||||
Token IFrameRootCompositionPhase<Token, Token, Token, Token, Token, Token, Token, Token, Token>.Compose(
|
||||
Token platform,
|
||||
Token host,
|
||||
Token content,
|
||||
Token settings,
|
||||
|
|
@ -164,6 +232,7 @@ public sealed class GameWindowCompositionPipelineTests
|
|||
Token live,
|
||||
Token session)
|
||||
{
|
||||
Assert.Same(Platform, platform);
|
||||
Assert.Same(_host, host);
|
||||
Assert.Same(_content, content);
|
||||
Assert.Same(_settings, settings);
|
||||
|
|
|
|||
|
|
@ -52,22 +52,21 @@ public sealed class GameWindowSlice8BoundaryTests
|
|||
AssertAppearsInOrder(
|
||||
body,
|
||||
"GameWindowPlatformResult<GL, IInputContext> platform = AcquirePlatform();",
|
||||
"GameWindowCompositionPipeline.Run<",
|
||||
"new HostInputCameraCompositionPhase(",
|
||||
"this).Compose(platform);",
|
||||
"this).Compose(platformResult),",
|
||||
"new ContentEffectsAudioCompositionPhase(",
|
||||
"this).Compose(platform, hostInputCamera);",
|
||||
"this).Compose(platformResult, hostInputCamera),",
|
||||
"new SettingsDevToolsCompositionPhase(",
|
||||
"this).Compose(platform, hostInputCamera, contentEffectsAudio);",
|
||||
"InteractionRetainedUiResult interactionUi =",
|
||||
"this).Compose(platformResult, hostInputCamera, contentEffectsAudio);",
|
||||
"new InteractionRetainedUiCompositionPhase(",
|
||||
"this).Compose(",
|
||||
"LivePresentationResult livePresentation =",
|
||||
"new LivePresentationCompositionPhase(",
|
||||
"this).Compose(",
|
||||
"new SessionPlayerCompositionPhase(",
|
||||
"FrameRootResult frameRoots = new FrameRootCompositionPhase(",
|
||||
"new FrameRootCompositionPhase(",
|
||||
"new SessionStartCompositionPhase(",
|
||||
".Start(frameRoots);");
|
||||
".Start(frameRoots));");
|
||||
|
||||
string framePhase = File.ReadAllText(Path.Combine(
|
||||
FindRepoRoot(),
|
||||
|
|
@ -98,7 +97,7 @@ public sealed class GameWindowSlice8BoundaryTests
|
|||
"_publication.PublishSessionPlayer(result);");
|
||||
Assert.Equal(1, CountOccurrences(
|
||||
body,
|
||||
".Start(frameRoots);"));
|
||||
".Start(frameRoots));"));
|
||||
string phaseOne = Slice(
|
||||
File.ReadAllText(Path.Combine(
|
||||
FindRepoRoot(),
|
||||
|
|
@ -131,9 +130,9 @@ public sealed class GameWindowSlice8BoundaryTests
|
|||
"case LiveSessionStartStatus.MissingCredentials:",
|
||||
"case LiveSessionStartStatus.Failed:");
|
||||
int start = body.IndexOf(
|
||||
".Start(frameRoots);",
|
||||
".Start(frameRoots));",
|
||||
StringComparison.Ordinal);
|
||||
string postStart = body[(start + ".Start(frameRoots);".Length)..];
|
||||
string postStart = body[(start + ".Start(frameRoots));".Length)..];
|
||||
Assert.Empty(System.Text.RegularExpressions.Regex.Matches(
|
||||
postStart,
|
||||
@"(?m)^\s+_[A-Za-z]\w*\s*(?:\?\?=|=)"));
|
||||
|
|
@ -174,7 +173,7 @@ public sealed class GameWindowSlice8BoundaryTests
|
|||
source,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"new WorldRenderDependencies(\n _worldEnvironment,",
|
||||
"new WorldRenderDependencies(\n _worldEnvironment,",
|
||||
load.Replace("\r\n", "\n", StringComparison.Ordinal),
|
||||
StringComparison.Ordinal);
|
||||
string worldCompose = Slice(
|
||||
|
|
@ -350,13 +349,14 @@ public sealed class GameWindowSlice8BoundaryTests
|
|||
"Window.Create(options)");
|
||||
AssertAppearsInOrder(
|
||||
load,
|
||||
"GameWindowCompositionPipeline.Run<",
|
||||
"new SettingsDevToolsCompositionPhase(",
|
||||
"this).Compose(platform, hostInputCamera, contentEffectsAudio);",
|
||||
"this).Compose(platformResult, hostInputCamera, contentEffectsAudio);",
|
||||
"new WorldRenderCompositionPhase(",
|
||||
"new SessionPlayerCompositionPhase(",
|
||||
"new FrameRootCompositionPhase(",
|
||||
"new SessionStartCompositionPhase(",
|
||||
".Start(frameRoots);");
|
||||
".Start(frameRoots));");
|
||||
string sessionPhase = File.ReadAllText(Path.Combine(
|
||||
FindRepoRoot(),
|
||||
"src",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue