From c3cf8d9439e453743b21f47ed6eb9b77bcbcfe68 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Sep 2023 15:26:41 +0900 Subject: [PATCH 1/3] Fix startup sequence continuing after window creation failure This would lead to `KeyboardHandler` entering a disabled state due to https://github.com/ppy/osu-framework/blob/75ed421f60228920abd819cebc5982cb7799bbbb/osu.Framework/Input/Handlers/Keyboard/KeyboardHandler.cs#L22-L23. --- osu.Framework/Platform/GameHost.cs | 18 +++++++++++++++--- osu.Framework/Platform/HeadlessGameHost.cs | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Framework/Platform/GameHost.cs b/osu.Framework/Platform/GameHost.cs index 926a08dbd6..601e0df813 100644 --- a/osu.Framework/Platform/GameHost.cs +++ b/osu.Framework/Platform/GameHost.cs @@ -53,6 +53,11 @@ public abstract class GameHost : IIpcHost, IDisposable { public IWindow Window { get; private set; } + /// + /// Whether needs to be non-null for startup to succeed. + /// + protected virtual bool RequireWindowExists => true; + public IRenderer Renderer { get; private set; } public string RendererInfo { get; private set; } @@ -724,6 +729,12 @@ public void Run(Game game) ChooseAndSetupRenderer(); + if (RequireWindowExists && Window == null) + { + Logger.Log("Aborting startup as no window could be created."); + return; + } + initialiseInputHandlers(); // Prepare renderer (requires config). @@ -964,10 +975,11 @@ protected void SetupRendererAndWindow(IRenderer renderer, GraphicsSurfaceType su // Prepare window Window = CreateWindow(surfaceType); - if (Window == null) + if (RequireWindowExists && Window == null) { - Logger.Log("🖼️ Renderer could not be initialised, no window exists."); - return; + // Window creation may fail in the case of a catastrophic failure (ie. graphics driver or SDL2 level). + // In such cases, we want to throw here to immediately mark this renderer setup as failed. + throw new InvalidOperationException("🖼️ Renderer could not be initialised as window creation failed."); } try diff --git a/osu.Framework/Platform/HeadlessGameHost.cs b/osu.Framework/Platform/HeadlessGameHost.cs index bff5953f5c..21bed6de1b 100644 --- a/osu.Framework/Platform/HeadlessGameHost.cs +++ b/osu.Framework/Platform/HeadlessGameHost.cs @@ -47,6 +47,8 @@ public HeadlessGameHost(string gameName = null, HostOptions options = null, bool this.realtime = realtime; } + protected override bool RequireWindowExists => false; + protected override IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => null; protected override Clipboard CreateClipboard() => new HeadlessClipboard(); From 3453423cd086754aae2c89afa805640ceccda208 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Sep 2023 19:27:50 +0900 Subject: [PATCH 2/3] Fix headless execution failing and throw window creation exception outwards --- osu.Framework/Platform/GameHost.cs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Framework/Platform/GameHost.cs b/osu.Framework/Platform/GameHost.cs index 601e0df813..27de21e806 100644 --- a/osu.Framework/Platform/GameHost.cs +++ b/osu.Framework/Platform/GameHost.cs @@ -972,18 +972,21 @@ protected void SetupRendererAndWindow(IRenderer renderer, GraphicsSurfaceType su Renderer = renderer; Renderer.CacheStorage = CacheStorage.GetStorageForDirectory("shaders"); - // Prepare window - Window = CreateWindow(surfaceType); - - if (RequireWindowExists && Window == null) - { - // Window creation may fail in the case of a catastrophic failure (ie. graphics driver or SDL2 level). - // In such cases, we want to throw here to immediately mark this renderer setup as failed. - throw new InvalidOperationException("🖼️ Renderer could not be initialised as window creation failed."); - } - try { + // Prepare window + Window = CreateWindow(surfaceType); + + if (Window == null) + { + if (!RequireWindowExists) + return; + + // Window creation may fail in the case of a catastrophic failure (ie. graphics driver or SDL2 level). + // In such cases, we want to throw here to immediately mark this renderer setup as failed. + throw new InvalidOperationException("🖼️ Renderer could not be initialised as window creation failed."); + } + Window.SetupWindow(Config); Window.Create(); Window.Title = $@"osu!framework (running ""{Name}"")"; From 9c2e1c0063c5f89158d5b238ebe7a39ce8cb324f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Sep 2023 22:33:38 +0900 Subject: [PATCH 3/3] Move comment to more correct location --- osu.Framework/Platform/GameHost.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Framework/Platform/GameHost.cs b/osu.Framework/Platform/GameHost.cs index 27de21e806..495ba30a6e 100644 --- a/osu.Framework/Platform/GameHost.cs +++ b/osu.Framework/Platform/GameHost.cs @@ -729,6 +729,8 @@ public void Run(Game game) ChooseAndSetupRenderer(); + // Window creation may fail in the case of a catastrophic failure (ie. graphics driver or SDL2 level). + // In such cases, we want to throw here to immediately mark this renderer setup as failed. if (RequireWindowExists && Window == null) { Logger.Log("Aborting startup as no window could be created."); @@ -979,11 +981,10 @@ protected void SetupRendererAndWindow(IRenderer renderer, GraphicsSurfaceType su if (Window == null) { + // Can be null, usually via Headless execution. if (!RequireWindowExists) return; - // Window creation may fail in the case of a catastrophic failure (ie. graphics driver or SDL2 level). - // In such cases, we want to throw here to immediately mark this renderer setup as failed. throw new InvalidOperationException("🖼️ Renderer could not be initialised as window creation failed."); }