namespace AcDream.App.Composition; internal interface IGameWindowPlatformPublication where TGraphics : class where TInput : class { void PublishGraphics(TGraphics graphics); void PublishInput(TInput input); } internal sealed record GameWindowPlatformResult( TGraphics Graphics, TInput Input) where TGraphics : class where TInput : class; internal enum GameWindowPlatformAcquisitionPoint { GraphicsPublished, InputPublished, } /// /// Exact host-platform acquisition prelude. Graphics ownership publishes /// before input construction starts so a later input failure remains /// recoverable through the normal lifetime transaction. /// internal static class GameWindowPlatformAcquisition { public static GameWindowPlatformResult Acquire( Func graphicsFactory, Action releaseUnpublishedGraphics, Func inputFactory, Action releaseUnpublishedInput, IGameWindowPlatformPublication publication, Action? faultInjection = null) where TGraphics : class where TInput : class { ArgumentNullException.ThrowIfNull(graphicsFactory); ArgumentNullException.ThrowIfNull(releaseUnpublishedGraphics); ArgumentNullException.ThrowIfNull(inputFactory); ArgumentNullException.ThrowIfNull(releaseUnpublishedInput); ArgumentNullException.ThrowIfNull(publication); var scope = new CompositionAcquisitionScope(); try { var graphicsLease = scope.Acquire( "graphics API", graphicsFactory, releaseUnpublishedGraphics); TGraphics graphics = graphicsLease.Publish(publication.PublishGraphics); faultInjection?.Invoke(GameWindowPlatformAcquisitionPoint.GraphicsPublished); var inputLease = scope.Acquire( "input context", inputFactory, releaseUnpublishedInput); TInput input = inputLease.Publish(publication.PublishInput); faultInjection?.Invoke(GameWindowPlatformAcquisitionPoint.InputPublished); scope.Complete(); return new GameWindowPlatformResult(graphics, input); } catch (Exception failure) { scope.RollbackAndThrow(failure); throw new System.Diagnostics.UnreachableException(); } } }