Skip to content

Commit

Permalink
Merge pull request #995 from peppy/headless-ftl
Browse files Browse the repository at this point in the history
Add the ability for headless runs to exceed realtime
  • Loading branch information
Dan Balasescu committed Aug 23, 2017
2 parents e2d4182 + 92aea3d commit 1ba1e8e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE

using System.Linq;
Expand All @@ -7,19 +7,18 @@
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;

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;
Expand Down Expand Up @@ -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() },
Expand All @@ -87,19 +72,23 @@ private class FillFlowContainerNoInput : FillFlowContainer<Container>
}
}

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,
};
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<Compile Include="Visual\TestCaseColourGradient.cs" />
<Compile Include="Visual\TestCaseContextMenu.cs" />
<Compile Include="Visual\TestCaseCoordinateSpaces.cs" />
<Compile Include="Visual\TestCaseDelayedLoad.cs" />
<Compile Include="Visual\TestCaseDrawablePath.cs" />
<Compile Include="Visual\TestCaseDropdownBox.cs" />
<Compile Include="Visual\TestCaseDynamicDepth.cs" />
Expand All @@ -72,7 +73,6 @@
<Compile Include="Visual\TestCaseMasking.cs" />
<Compile Include="Visual\TestCaseNestedHover.cs" />
<Compile Include="Visual\TestCaseContainerState.cs" />
<Compile Include="Visual\TestCaseOnlineTextures.cs" />
<Compile Include="Visual\TestCasePadding.cs" />
<Compile Include="Visual\TestCasePropertyBoundaries.cs" />
<Compile Include="Visual\TestCaseRigidBody.cs" />
Expand Down
36 changes: 35 additions & 1 deletion osu.Framework.Desktop/Platform/HeadlessGameHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using osu.Framework.Input.Handlers;
using osu.Framework.Timing;

namespace osu.Framework.Desktop.Platform
{
Expand All @@ -11,9 +12,15 @@ namespace osu.Framework.Desktop.Platform
/// </summary>
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));
}
Expand All @@ -31,6 +38,33 @@ protected override void DrawFrame()
//we can't draw.
}

protected override void UpdateFrame()
{
customClock?.ProcessFrame();

base.UpdateFrame();
}

protected override IEnumerable<InputHandler> CreateAvailableInputHandlers() => new InputHandler[] { };

private class FastClock : IClock
{
private readonly double increment;
private double time;

/// <summary>
/// A clock which increments each time <see cref="CurrentTime"/> is requested.
/// Run fast. Run consistent.
/// </summary>
/// <param name="increment">Milliseconds we should increment the clock by each time the time is requested.</param>
public FastClock(double increment)
{
this.increment = increment;
}

public double CurrentTime => time += increment;
public double Rate => 1;
public bool IsRunning => true;
}
}
}
2 changes: 1 addition & 1 deletion osu.Framework.Testing/TestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
10 changes: 8 additions & 2 deletions osu.Framework/Platform/GameHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using osu.Framework.Logging;
using osu.Framework.Statistics;
using osu.Framework.Threading;
using osu.Framework.Timing;

namespace osu.Framework.Platform
{
Expand Down Expand Up @@ -227,7 +228,7 @@ protected virtual void UpdateInitialize()

protected Container Root;

protected void UpdateFrame()
protected virtual void UpdateFrame()
{
if (Root == null) return;

Expand Down Expand Up @@ -386,6 +387,11 @@ private void resetInputHandlers()
}
}

/// <summary>
/// The clock which is to be used by the scene graph (will be assigned to <see cref="Root"/>).
/// </summary>
protected virtual IFrameBasedClock SceneGraphClock => UpdateThread.Clock;

private void bootstrapSceneGraph(Game game)
{
var root = new UserInputManager { Child = game };
Expand All @@ -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;
Expand Down

0 comments on commit 1ba1e8e

Please sign in to comment.