namespace AcDream.App.Composition; internal interface IHostInputCameraCompositionPhase { TResult Compose(TPlatform platform); } internal interface IContentEffectsAudioCompositionPhase { TResult Compose(TPlatform platform, THost host); } internal interface ISettingsDevToolsCompositionPhase { TResult Compose(TPlatform platform, THost host, TContent content); } internal interface IWorldRenderCompositionPhase { TResult Compose(TPlatform platform, TContent content, TSettings settings); } internal interface IInteractionUiCompositionPhase { TResult Compose(TPlatform platform, THost host, TContent content, TSettings settings, TWorld world); } internal interface ILivePresentationCompositionPhase { TResult Compose( TPlatform platform, THost host, TContent content, TSettings settings, TWorld world, TInteraction interaction); } internal interface ISessionPlayerCompositionPhase { TResult Compose( THost host, TContent content, TSettings settings, TWorld world, TInteraction interaction, TLive live); } internal interface IFrameRootCompositionPhase { TResult Compose( TPlatform platform, THost host, TContent content, TSettings settings, TWorld world, TInteraction interaction, TLive live, TSession session); } internal interface ISessionStartCompositionPhase { void Start(TFrame frame); } /// /// Synchronous production entry point for the fixed composition topology. /// The delegates exist only for the duration of ; this lets /// the native host remain the write-only publication shell without retaining /// it in any phase owner. /// internal static class GameWindowCompositionPipeline { public static void Run< TPlatform, THost, TContent, TSettings, TWorld, TInteraction, TLive, TSession, TFrame>( TPlatform platform, Func host, Func content, Func settings, Func world, Func interaction, Func live, Func session, Func frame, Action start) { new GameWindowCompositionPipeline< TPlatform, THost, TContent, TSettings, TWorld, TInteraction, TLive, TSession, TFrame>( new HostPhase(host), new ContentPhase(content), new SettingsPhase(settings), new WorldPhase(world), new InteractionPhase(interaction), new LivePhase(live), new SessionPhase(session), new FramePhase(frame), new StartPhase(start)) .Run(platform); } private sealed class HostPhase( Func compose) : IHostInputCameraCompositionPhase { public TResult Compose(TPlatform platform) => compose(platform); } private sealed class ContentPhase( Func compose) : IContentEffectsAudioCompositionPhase { public TResult Compose(TPlatform platform, THost host) => compose(platform, host); } private sealed class SettingsPhase( Func compose) : ISettingsDevToolsCompositionPhase { public TResult Compose(TPlatform platform, THost host, TContent content) => compose(platform, host, content); } private sealed class WorldPhase( Func compose) : IWorldRenderCompositionPhase { public TResult Compose(TPlatform platform, TContent content, TSettings settings) => compose(platform, content, settings); } private sealed class InteractionPhase( Func compose) : IInteractionUiCompositionPhase { public TResult Compose( TPlatform platform, THost host, TContent content, TSettings settings, TWorld world) => compose(platform, host, content, settings, world); } private sealed class LivePhase( Func compose) : ILivePresentationCompositionPhase { public TResult Compose( TPlatform platform, THost host, TContent content, TSettings settings, TWorld world, TInteraction interaction) => compose(platform, host, content, settings, world, interaction); } private sealed class SessionPhase( Func compose) : ISessionPlayerCompositionPhase { public TResult Compose( THost host, TContent content, TSettings settings, TWorld world, TInteraction interaction, TLive live) => compose(host, content, settings, world, interaction, live); } private sealed class FramePhase( Func compose) : IFrameRootCompositionPhase { public TResult Compose( TPlatform platform, THost host, TContent content, TSettings settings, TWorld world, TInteraction interaction, TLive live, TSession session) => compose(platform, host, content, settings, world, interaction, live, session); } private sealed class StartPhase(Action start) : ISessionStartCompositionPhase { public void Start(TFrame frame) => start(frame); } } /// /// Fixed startup topology. It intentionally retains no cumulative context or /// final runtime graph; immutable phase results exist only as locals during /// one composition run. /// internal sealed class GameWindowCompositionPipeline< TPlatform, THost, TContent, TSettings, TWorld, TInteraction, TLive, TSession, TFrame> { private readonly IHostInputCameraCompositionPhase _host; private readonly IContentEffectsAudioCompositionPhase _content; private readonly ISettingsDevToolsCompositionPhase _settings; private readonly IWorldRenderCompositionPhase _world; private readonly IInteractionUiCompositionPhase _interaction; private readonly ILivePresentationCompositionPhase _live; private readonly ISessionPlayerCompositionPhase _session; private readonly IFrameRootCompositionPhase _frame; private readonly ISessionStartCompositionPhase _start; public GameWindowCompositionPipeline( IHostInputCameraCompositionPhase host, IContentEffectsAudioCompositionPhase content, ISettingsDevToolsCompositionPhase settings, IWorldRenderCompositionPhase world, IInteractionUiCompositionPhase interaction, ILivePresentationCompositionPhase live, ISessionPlayerCompositionPhase session, IFrameRootCompositionPhase frame, ISessionStartCompositionPhase start) { _host = host ?? throw new ArgumentNullException(nameof(host)); _content = content ?? throw new ArgumentNullException(nameof(content)); _settings = settings ?? throw new ArgumentNullException(nameof(settings)); _world = world ?? throw new ArgumentNullException(nameof(world)); _interaction = interaction ?? throw new ArgumentNullException(nameof(interaction)); _live = live ?? throw new ArgumentNullException(nameof(live)); _session = session ?? throw new ArgumentNullException(nameof(session)); _frame = frame ?? throw new ArgumentNullException(nameof(frame)); _start = start ?? throw new ArgumentNullException(nameof(start)); } public void Run(TPlatform platform) { THost host = _host.Compose(platform); TContent content = _content.Compose(platform, host); TSettings settings = _settings.Compose(platform, host, content); TWorld world = _world.Compose(platform, content, settings); TInteraction interaction = _interaction.Compose(platform, host, content, settings, world); TLive live = _live.Compose(platform, host, content, settings, world, interaction); TSession session = _session.Compose(host, content, settings, world, interaction, live); TFrame frame = _frame.Compose( platform, host, content, settings, world, interaction, live, session); _start.Start(frame); } }