From 47c1bb00b84b204b4765fc75502df9358218bdb3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 15:27:29 +0900 Subject: [PATCH 1/2] Add the ability for headless runs to exceed realtime Improves efficiency of unit testing. --- .../Platform/HeadlessGameHost.cs | 36 ++++++++++++++++++- osu.Framework.Testing/TestCase.cs | 2 +- osu.Framework/Platform/GameHost.cs | 10 ++++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/osu.Framework.Desktop/Platform/HeadlessGameHost.cs b/osu.Framework.Desktop/Platform/HeadlessGameHost.cs index df9decff9b..c9fb253e7c 100644 --- a/osu.Framework.Desktop/Platform/HeadlessGameHost.cs +++ b/osu.Framework.Desktop/Platform/HeadlessGameHost.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using osu.Framework.Input.Handlers; +using osu.Framework.Timing; namespace osu.Framework.Desktop.Platform { @@ -11,9 +12,15 @@ namespace osu.Framework.Desktop.Platform /// public class HeadlessGameHost : DesktopGameHost { - public HeadlessGameHost(string gameName = @"", bool bindIPC = false) + private readonly IFrameBasedClock customClock; + + protected override IFrameBasedClock SceneGraphClock => customClock ?? base.SceneGraphClock; + + public HeadlessGameHost(string gameName = @"", bool bindIPC = false, bool realtime = true) : base(gameName, bindIPC) { + if (!realtime) customClock = new FramedClock(new FastClock(1000.0 / 30)); + UpdateThread.Scheduler.Update(); Dependencies.Cache(Storage = new DesktopStorage(string.Empty)); } @@ -31,6 +38,33 @@ protected override void DrawFrame() //we can't draw. } + protected override void UpdateFrame() + { + customClock?.ProcessFrame(); + + base.UpdateFrame(); + } + protected override IEnumerable CreateAvailableInputHandlers() => new InputHandler[] { }; + + private class FastClock : IClock + { + private readonly double increment; + private double time; + + /// + /// A clock which increments each time is requested. + /// Run fast. Run consistent. + /// + /// Milliseconds we should increment the clock by each time the time is requested. + public FastClock(double increment) + { + this.increment = increment; + } + + public double CurrentTime => time += increment; + public double Rate => 1; + public bool IsRunning => true; + } } } diff --git a/osu.Framework.Testing/TestCase.cs b/osu.Framework.Testing/TestCase.cs index 987239d986..8634b97f6f 100644 --- a/osu.Framework.Testing/TestCase.cs +++ b/osu.Framework.Testing/TestCase.cs @@ -29,7 +29,7 @@ public abstract class TestCase : Container [Test] public virtual void RunTest() { - using (var host = new HeadlessGameHost()) + using (var host = new HeadlessGameHost(realtime: false)) host.Run(new TestCaseTestRunner(this)); } diff --git a/osu.Framework/Platform/GameHost.cs b/osu.Framework/Platform/GameHost.cs index 5d5db11de7..0e57b9111b 100644 --- a/osu.Framework/Platform/GameHost.cs +++ b/osu.Framework/Platform/GameHost.cs @@ -25,6 +25,7 @@ using osu.Framework.Logging; using osu.Framework.Statistics; using osu.Framework.Threading; +using osu.Framework.Timing; namespace osu.Framework.Platform { @@ -227,7 +228,7 @@ protected virtual void UpdateInitialize() protected Container Root; - protected void UpdateFrame() + protected virtual void UpdateFrame() { if (Root == null) return; @@ -386,6 +387,11 @@ private void resetInputHandlers() } } + /// + /// The clock which is to be used by the scene graph (will be assigned to ). + /// + protected virtual IFrameBasedClock SceneGraphClock => UpdateThread.Clock; + private void bootstrapSceneGraph(Game game) { var root = new UserInputManager { Child = game }; @@ -395,7 +401,7 @@ private void bootstrapSceneGraph(Game game) game.SetHost(this); - root.Load(UpdateThread.Clock, Dependencies); + root.Load(SceneGraphClock, Dependencies); //publish bootstrapped scene graph to all threads. Root = root; From 92aea3d67ffefbf203838682c0a11370d18d62cd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 15:59:37 +0900 Subject: [PATCH 2/2] Update TestCase to not rely on online loading of textures --- ...lineTextures.cs => TestCaseDelayedLoad.cs} | 43 +++++++------------ .../osu.Framework.Desktop.Tests.csproj | 2 +- 2 files changed, 17 insertions(+), 28 deletions(-) rename osu.Framework.Desktop.Tests/Visual/{TestCaseOnlineTextures.cs => TestCaseDelayedLoad.cs} (64%) diff --git a/osu.Framework.Desktop.Tests/Visual/TestCaseOnlineTextures.cs b/osu.Framework.Desktop.Tests/Visual/TestCaseDelayedLoad.cs similarity index 64% rename from osu.Framework.Desktop.Tests/Visual/TestCaseOnlineTextures.cs rename to osu.Framework.Desktop.Tests/Visual/TestCaseDelayedLoad.cs index ad3875e7af..cc6b6fbd7a 100644 --- a/osu.Framework.Desktop.Tests/Visual/TestCaseOnlineTextures.cs +++ b/osu.Framework.Desktop.Tests/Visual/TestCaseDelayedLoad.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE using System.Linq; @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; using osu.Framework.Testing; using OpenTK; using OpenTK.Graphics; @@ -15,11 +14,11 @@ namespace osu.Framework.Desktop.Tests.Visual { [TestFixture] - internal class TestCaseOnlineTextures : TestCase + internal class TestCaseDelayedLoad : TestCase { private const int panel_count = 2048; - public TestCaseOnlineTextures() + public TestCaseDelayedLoad() { FillFlowContainerNoInput flow; ScrollContainer scroll; @@ -49,23 +48,9 @@ public TestCaseOnlineTextures() new DelayedLoadWrapper(new Container { RelativeSizeAxes = Axes.Both, - OnLoadComplete = d => - { - var c = (Container)d; - - if ((c.Children.FirstOrDefault() as Sprite)?.Texture == null) - { - c.Add(new SpriteText { - Colour = Color4.Gray, - Text = @"nope", - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); - } - }, Children = new Drawable[] { - new Avatar(i) { RelativeSizeAxes = Axes.Both } + new TestBox{ RelativeSizeAxes = Axes.Both } } }), new SpriteText { Text = i.ToString() }, @@ -87,19 +72,23 @@ private class FillFlowContainerNoInput : FillFlowContainer } } - public class Avatar : Sprite + public class TestBox : Container { - private readonly int userId; - - public Avatar(int userId) + public TestBox() { - this.userId = userId; + RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load() { - Texture = textures.Get($@"https://a.ppy.sh/{userId}"); + Child = new SpriteText + { + Colour = Color4.Yellow, + Text = @"loaded", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; } } -} +} \ No newline at end of file diff --git a/osu.Framework.Desktop.Tests/osu.Framework.Desktop.Tests.csproj b/osu.Framework.Desktop.Tests/osu.Framework.Desktop.Tests.csproj index c0ef7cbb54..709e7b877b 100644 --- a/osu.Framework.Desktop.Tests/osu.Framework.Desktop.Tests.csproj +++ b/osu.Framework.Desktop.Tests/osu.Framework.Desktop.Tests.csproj @@ -59,6 +59,7 @@ + @@ -72,7 +73,6 @@ -