Centralise and update WorkingBeatmap creation in test cases

This commit is contained in:
Dean Herbert 2019-05-31 14:40:53 +09:00
parent 80d65f9a3b
commit f33a5bc54c
34 changed files with 278 additions and 250 deletions

View File

@ -20,14 +20,14 @@ namespace osu.Game.Rulesets.Catch.Tests
{ {
} }
protected override IBeatmap CreateBeatmap(Ruleset ruleset) protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{ {
var beatmap = new Beatmap var beatmap = new Beatmap
{ {
BeatmapInfo = new BeatmapInfo BeatmapInfo = new BeatmapInfo
{ {
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 }, BaseDifficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 },
Ruleset = ruleset.RulesetInfo Ruleset = ruleset
} }
}; };

View File

@ -29,14 +29,14 @@ namespace osu.Game.Rulesets.Catch.Tests
{ {
} }
protected override IBeatmap CreateBeatmap(Ruleset ruleset) protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{ {
var beatmap = new Beatmap var beatmap = new Beatmap
{ {
BeatmapInfo = new BeatmapInfo BeatmapInfo = new BeatmapInfo
{ {
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 }, BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
Ruleset = ruleset.RulesetInfo Ruleset = ruleset
} }
}; };

View File

@ -16,14 +16,14 @@ namespace osu.Game.Rulesets.Catch.Tests
{ {
} }
protected override IBeatmap CreateBeatmap(Ruleset ruleset) protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{ {
var beatmap = new Beatmap var beatmap = new Beatmap
{ {
BeatmapInfo = new BeatmapInfo BeatmapInfo = new BeatmapInfo
{ {
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 }, BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
Ruleset = ruleset.RulesetInfo Ruleset = ruleset
} }
}; };

View File

@ -23,13 +23,13 @@ namespace osu.Game.Rulesets.Catch.Tests
AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash); AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash);
} }
protected override IBeatmap CreateBeatmap(Ruleset ruleset) protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{ {
var beatmap = new Beatmap var beatmap = new Beatmap
{ {
BeatmapInfo = BeatmapInfo =
{ {
Ruleset = ruleset.RulesetInfo, Ruleset = ruleset,
BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f } BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f }
} }
}; };

View File

@ -17,14 +17,14 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
} }
protected override IBeatmap CreateBeatmap(Ruleset ruleset) protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{ {
var beatmap = new Beatmap var beatmap = new Beatmap
{ {
BeatmapInfo = new BeatmapInfo BeatmapInfo = new BeatmapInfo
{ {
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 }, BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
Ruleset = ruleset.RulesetInfo Ruleset = ruleset
} }
}; };

View File

@ -20,7 +20,6 @@ using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
using osuTK; using osuTK;
@ -299,7 +298,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
AddStep("load player", () => AddStep("load player", () =>
{ {
Beatmap.Value = new TestWorkingBeatmap(new Beatmap<OsuHitObject> Beatmap.Value = CreateWorkingBeatmap(new Beatmap<OsuHitObject>
{ {
HitObjects = HitObjects =
{ {
@ -323,7 +322,7 @@ namespace osu.Game.Rulesets.Osu.Tests
BaseDifficulty = new BeatmapDifficulty { SliderTickRate = 3 }, BaseDifficulty = new BeatmapDifficulty { SliderTickRate = 3 },
Ruleset = new OsuRuleset().RulesetInfo Ruleset = new OsuRuleset().RulesetInfo
}, },
}, Clock); });
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } }); var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });

View File

@ -18,7 +18,6 @@ using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Tests.Beatmaps;
using osu.Game.Tests.Visual; using osu.Game.Tests.Visual;
using osuTK; using osuTK;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
@ -64,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
var controlPointInfo = new ControlPointInfo(); var controlPointInfo = new ControlPointInfo();
controlPointInfo.TimingPoints.Add(new TimingControlPoint()); controlPointInfo.TimingPoints.Add(new TimingControlPoint());
WorkingBeatmap beatmap = new TestWorkingBeatmap(new Beatmap WorkingBeatmap beatmap = CreateWorkingBeatmap(new Beatmap
{ {
HitObjects = new List<HitObject> { new CentreHit() }, HitObjects = new List<HitObject> { new CentreHit() },
BeatmapInfo = new BeatmapInfo BeatmapInfo = new BeatmapInfo
@ -79,7 +78,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
Ruleset = new TaikoRuleset().RulesetInfo Ruleset = new TaikoRuleset().RulesetInfo
}, },
ControlPointInfo = controlPointInfo ControlPointInfo = controlPointInfo
}, Clock); });
Add(playfieldContainer = new Container Add(playfieldContainer = new Container
{ {

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
@ -54,7 +55,7 @@ namespace osu.Game.Tests.Visual.Background
private RulesetStore rulesets; private RulesetStore rulesets;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host) private void load(GameHost host, AudioManager audio)
{ {
factory = new DatabaseContextFactory(LocalStorage); factory = new DatabaseContextFactory(LocalStorage);
factory.ResetDatabase(); factory.ResetDatabase();
@ -68,7 +69,7 @@ namespace osu.Game.Tests.Visual.Background
usage.Migrate(); usage.Migrate();
Dependencies.Cache(rulesets = new RulesetStore(factory)); Dependencies.Cache(rulesets = new RulesetStore(factory));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, audio, host, Beatmap.Default));
Dependencies.Cache(new OsuConfigManager(LocalStorage)); Dependencies.Cache(new OsuConfigManager(LocalStorage));
manager.Import(TestResources.GetTestBeatmapForImport()); manager.Import(TestResources.GetTestBeatmapForImport());

View File

@ -7,7 +7,6 @@ using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual.Editor namespace osu.Game.Tests.Visual.Editor
{ {
@ -19,7 +18,7 @@ namespace osu.Game.Tests.Visual.Editor
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, Clock); Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
Child = new ComposeScreen(); Child = new ComposeScreen();
} }
} }

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -30,9 +31,9 @@ namespace osu.Game.Tests.Visual.Editor
}; };
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load(AudioManager audio)
{ {
Beatmap.Value = new WaveformTestBeatmap(); Beatmap.Value = new WaveformTestBeatmap(audio);
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using NUnit.Framework; using NUnit.Framework;
@ -10,7 +10,6 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Beatmaps;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -48,7 +47,7 @@ namespace osu.Game.Tests.Visual.Editor
} }
}; };
Beatmap.Value = new TestWorkingBeatmap(testBeatmap, Clock); Beatmap.Value = CreateWorkingBeatmap(testBeatmap);
Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock }; Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock };
} }

View File

@ -8,7 +8,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Edit.Components.Timelines.Summary; using osu.Game.Screens.Edit.Components.Timelines.Summary;
using osu.Game.Tests.Beatmaps;
using osuTK; using osuTK;
namespace osu.Game.Tests.Visual.Editor namespace osu.Game.Tests.Visual.Editor
@ -21,7 +20,7 @@ namespace osu.Game.Tests.Visual.Editor
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, null); Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
Add(new SummaryTimeline Add(new SummaryTimeline
{ {

View File

@ -18,7 +18,6 @@ using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
using osu.Game.Tests.Beatmaps;
using osuTK; using osuTK;
namespace osu.Game.Tests.Visual.Editor namespace osu.Game.Tests.Visual.Editor
@ -45,7 +44,7 @@ namespace osu.Game.Tests.Visual.Editor
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Beatmap.Value = new TestWorkingBeatmap(new Beatmap Beatmap.Value = CreateWorkingBeatmap(new Beatmap
{ {
HitObjects = new List<HitObject> HitObjects = new List<HitObject>
{ {

View File

@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using NUnit.Framework; using NUnit.Framework;
@ -7,7 +7,6 @@ using osu.Framework.Graphics;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components;
using osu.Game.Tests.Beatmaps;
using osuTK; using osuTK;
namespace osu.Game.Tests.Visual.Editor namespace osu.Game.Tests.Visual.Editor
@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.Editor
Size = new Vector2(200, 100) Size = new Vector2(200, 100)
}; };
Beatmap.Value = new TestWorkingBeatmap(new Beatmap(), Clock); Beatmap.Value = CreateWorkingBeatmap(new Beatmap());
Child = playback; Child = playback;
} }

View File

@ -3,6 +3,7 @@
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Audio;
@ -19,10 +20,13 @@ namespace osu.Game.Tests.Visual.Editor
{ {
private WorkingBeatmap waveformBeatmap; private WorkingBeatmap waveformBeatmap;
private OsuGameBase game;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load(AudioManager audio, OsuGameBase game)
{ {
waveformBeatmap = new WaveformTestBeatmap(); waveformBeatmap = new WaveformTestBeatmap(audio);
this.game = game;
} }
[TestCase(1f)] [TestCase(1f)]
@ -91,7 +95,7 @@ namespace osu.Game.Tests.Visual.Editor
Child = graph = new TestWaveformGraph Child = graph = new TestWaveformGraph
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Waveform = new DummyWorkingBeatmap().Waveform, Waveform = new DummyWorkingBeatmap(game).Waveform,
}, },
}; };
}); });

View File

@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
@ -16,7 +16,6 @@ using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Screens; using osu.Game.Screens;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual.Gameplay namespace osu.Game.Tests.Visual.Gameplay
{ {
@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public void Setup() => Schedule(() => public void Setup() => Schedule(() =>
{ {
InputManager.Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }; InputManager.Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
Beatmap.Value = new TestWorkingBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo), Clock); Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
}); });
[Test] [Test]

View File

@ -3,7 +3,6 @@
using System; using System;
using osu.Framework.Lists; using osu.Framework.Lists;
using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
@ -43,9 +42,9 @@ namespace osu.Game.Tests.Visual.Gameplay
}); });
} }
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock clock) protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap)
{ {
var working = base.CreateWorkingBeatmap(beatmap, clock); var working = base.CreateWorkingBeatmap(beatmap);
workingWeakReferences.Add(working); workingWeakReferences.Add(working);
return working; return working;
} }

View File

@ -19,6 +19,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
public class TestSceneMatchSettingsOverlay : MultiplayerTestScene public class TestSceneMatchSettingsOverlay : MultiplayerTestScene
{ {
[Resolved]
private OsuGameBase game { get; set; }
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(MatchSettingsOverlay) typeof(MatchSettingsOverlay)
@ -57,7 +60,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("set name", () => Room.Name.Value = "Room name"); AddStep("set name", () => Room.Name.Value = "Room name");
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value); AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
AddStep("set beatmap", () => Room.Playlist.Add(new PlaylistItem { Beatmap = new DummyWorkingBeatmap().BeatmapInfo })); AddStep("set beatmap", () => Room.Playlist.Add(new PlaylistItem { Beatmap = new DummyWorkingBeatmap(game).BeatmapInfo }));
AddAssert("button enabled", () => settings.ApplyButton.Enabled.Value); AddAssert("button enabled", () => settings.ApplyButton.Enabled.Value);
AddStep("clear name", () => Room.Name.Value = ""); AddStep("clear name", () => Room.Name.Value = "");

View File

@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Direct; using osu.Game.Overlays.Direct;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Tests.Beatmaps;
using osuTK; using osuTK;
namespace osu.Game.Tests.Visual.Online namespace osu.Game.Tests.Visual.Online
@ -25,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
var beatmap = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, null); var beatmap = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
beatmap.BeatmapSetInfo.OnlineInfo.HasVideo = true; beatmap.BeatmapSetInfo.OnlineInfo.HasVideo = true;
beatmap.BeatmapSetInfo.OnlineInfo.HasStoryboard = true; beatmap.BeatmapSetInfo.OnlineInfo.HasStoryboard = true;

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
@ -18,7 +19,8 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BeatmapDetails) }; public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BeatmapDetails) };
public TestSceneBeatmapDetailArea() [BackgroundDependencyLoader]
private void load(OsuGameBase game)
{ {
BeatmapDetailArea detailsArea; BeatmapDetailArea detailsArea;
Add(detailsArea = new BeatmapDetailArea Add(detailsArea = new BeatmapDetailArea
@ -28,7 +30,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Size = new Vector2(550f, 450f), Size = new Vector2(550f, 450f),
}); });
AddStep("all metrics", () => detailsArea.Beatmap = new DummyWorkingBeatmap AddStep("all metrics", () => detailsArea.Beatmap = new DummyWorkingBeatmap(game)
{ {
BeatmapInfo = BeatmapInfo =
{ {
@ -56,7 +58,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
); );
AddStep("all except source", () => detailsArea.Beatmap = new DummyWorkingBeatmap AddStep("all except source", () => detailsArea.Beatmap = new DummyWorkingBeatmap(game)
{ {
BeatmapInfo = BeatmapInfo =
{ {
@ -82,7 +84,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
}); });
AddStep("ratings", () => detailsArea.Beatmap = new DummyWorkingBeatmap AddStep("ratings", () => detailsArea.Beatmap = new DummyWorkingBeatmap(game)
{ {
BeatmapInfo = BeatmapInfo =
{ {
@ -107,7 +109,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
}); });
AddStep("fails+retries", () => detailsArea.Beatmap = new DummyWorkingBeatmap AddStep("fails+retries", () => detailsArea.Beatmap = new DummyWorkingBeatmap(game)
{ {
BeatmapInfo = BeatmapInfo =
{ {
@ -133,7 +135,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
}); });
AddStep("null metrics", () => detailsArea.Beatmap = new DummyWorkingBeatmap AddStep("null metrics", () => detailsArea.Beatmap = new DummyWorkingBeatmap(game)
{ {
BeatmapInfo = BeatmapInfo =
{ {

View File

@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
@ -18,7 +18,6 @@ using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Taiko; using osu.Game.Rulesets.Taiko;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
using osu.Game.Tests.Beatmaps;
using osuTK; using osuTK;
namespace osu.Game.Tests.Visual.SongSelect namespace osu.Game.Tests.Visual.SongSelect
@ -136,7 +135,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep($"select {b?.Metadata.Title ?? "null"} beatmap", () => AddStep($"select {b?.Metadata.Title ?? "null"} beatmap", () =>
{ {
infoBefore = infoWedge.Info; infoBefore = infoWedge.Info;
infoWedge.Beatmap = Beatmap.Value = b == null ? Beatmap.Default : new TestWorkingBeatmap(b); infoWedge.Beatmap = Beatmap.Value = b == null ? Beatmap.Default : CreateWorkingBeatmap(b);
}); });
AddUntilStep("wait for async load", () => infoWedge.Info != infoBefore); AddUntilStep("wait for async load", () => infoWedge.Info != infoBefore);

View File

@ -8,6 +8,7 @@ using System.Linq;
using System.Text; using System.Text;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions; using osu.Framework.Extensions;
using osu.Framework.MathUtils; using osu.Framework.MathUtils;
@ -79,7 +80,7 @@ namespace osu.Game.Tests.Visual.SongSelect
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host) private void load(GameHost host, AudioManager audio)
{ {
factory = new DatabaseContextFactory(LocalStorage); factory = new DatabaseContextFactory(LocalStorage);
factory.ResetDatabase(); factory.ResetDatabase();
@ -93,7 +94,7 @@ namespace osu.Game.Tests.Visual.SongSelect
usage.Migrate(); usage.Migrate();
Dependencies.Cache(rulesets = new RulesetStore(factory)); Dependencies.Cache(rulesets = new RulesetStore(factory));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null, host, defaultBeatmap = Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, audio, host, defaultBeatmap = Beatmap.Default));
Beatmap.SetDefault(); Beatmap.SetDefault();
} }

View File

@ -3,6 +3,7 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using osu.Framework.Audio;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -19,12 +20,14 @@ namespace osu.Game.Tests
{ {
private readonly ZipArchiveReader reader; private readonly ZipArchiveReader reader;
private readonly Stream stream; private readonly Stream stream;
private readonly ITrackStore trackStore;
public WaveformTestBeatmap() public WaveformTestBeatmap(AudioManager audioManager)
: base(new BeatmapInfo()) : base(new BeatmapInfo(), audioManager)
{ {
stream = TestResources.GetTestBeatmapStream(); stream = TestResources.GetTestBeatmapStream();
reader = new ZipArchiveReader(stream); reader = new ZipArchiveReader(stream);
trackStore = audioManager.GetTrackStore(reader);
} }
public override void Dispose() public override void Dispose()
@ -32,17 +35,17 @@ namespace osu.Game.Tests
base.Dispose(); base.Dispose();
stream?.Dispose(); stream?.Dispose();
reader?.Dispose(); reader?.Dispose();
trackStore?.Dispose();
} }
protected override IBeatmap GetBeatmap() => createTestBeatmap(); protected override IBeatmap GetBeatmap() => createTestBeatmap();
protected override Texture GetBackground() => null; protected override Texture GetBackground() => null;
protected override Waveform GetWaveform() => new Waveform(getAudioStream()); protected override Waveform GetWaveform() => new Waveform(trackStore.GetStream(reader.Filenames.First(f => f.EndsWith(".mp3"))));
protected override Track GetTrack() => new TrackBass(getAudioStream()); protected override Track GetTrack() => trackStore.Get(reader.Filenames.First(f => f.EndsWith(".mp3")));
private Stream getAudioStream() => reader.GetStream(reader.Filenames.First(f => f.EndsWith(".mp3")));
private Stream getBeatmapStream() => reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu"))); private Stream getBeatmapStream() => reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu")));
private Beatmap createTestBeatmap() private Beatmap createTestBeatmap()

View File

@ -429,7 +429,7 @@ namespace osu.Game.Beatmaps
private readonly IBeatmap beatmap; private readonly IBeatmap beatmap;
public DummyConversionBeatmap(IBeatmap beatmap) public DummyConversionBeatmap(IBeatmap beatmap)
: base(beatmap.BeatmapInfo) : base(beatmap.BeatmapInfo, null)
{ {
this.beatmap = beatmap; this.beatmap = beatmap;
} }

View File

@ -22,11 +22,10 @@ namespace osu.Game.Beatmaps
private readonly IResourceStore<byte[]> store; private readonly IResourceStore<byte[]> store;
public BeatmapManagerWorkingBeatmap(IResourceStore<byte[]> store, TextureStore textureStore, BeatmapInfo beatmapInfo, AudioManager audioManager) public BeatmapManagerWorkingBeatmap(IResourceStore<byte[]> store, TextureStore textureStore, BeatmapInfo beatmapInfo, AudioManager audioManager)
: base(beatmapInfo) : base(beatmapInfo, audioManager)
{ {
this.store = store; this.store = store;
this.textureStore = textureStore; this.textureStore = textureStore;
AudioManager = audioManager;
} }
protected override IBeatmap GetBeatmap() protected override IBeatmap GetBeatmap()

View File

@ -2,8 +2,6 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Diagnostics; using System.Diagnostics;
using JetBrains.Annotations;
using osu.Framework.Audio;
using osu.Framework.Bindables; using osu.Framework.Bindables;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
@ -14,29 +12,20 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public abstract class BindableBeatmap : NonNullableBindable<WorkingBeatmap> public abstract class BindableBeatmap : NonNullableBindable<WorkingBeatmap>
{ {
protected AudioManager AudioManager;
private WorkingBeatmap lastBeatmap; private WorkingBeatmap lastBeatmap;
protected BindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) protected BindableBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue) : base(defaultValue)
{ {
// we don't want to attempt to update tracks if we are a bound copy. BindValueChanged(b => updateAudioTrack(b.NewValue), true);
if (audioManager != null)
{
AudioManager = audioManager;
ValueChanged += b => updateAudioTrack(b.NewValue);
// If the track has changed prior to this being called, let's register it
if (Value != Default)
updateAudioTrack(Value);
}
} }
private void updateAudioTrack(WorkingBeatmap beatmap) private void updateAudioTrack(WorkingBeatmap beatmap)
{ {
var trackLoaded = lastBeatmap?.TrackLoaded ?? false; var trackLoaded = lastBeatmap?.TrackLoaded ?? false;
//beatmap.AudioManager = AudioManager;
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
if (!trackLoaded || lastBeatmap?.Track != beatmap.Track) if (!trackLoaded || lastBeatmap?.Track != beatmap.Track)
{ {
@ -51,12 +40,5 @@ namespace osu.Game.Beatmaps
lastBeatmap = beatmap; lastBeatmap = beatmap;
} }
/// <summary>
/// Retrieve a new <see cref="BindableBeatmap"/> instance weakly bound to this <see cref="BindableBeatmap"/>.
/// If you are further binding to events of the retrieved <see cref="BindableBeatmap"/>, ensure a local reference is held.
/// </summary>
[NotNull]
public new abstract BindableBeatmap GetBoundCopy();
} }
} }

View File

@ -18,7 +18,7 @@ namespace osu.Game.Beatmaps
{ {
private readonly OsuGameBase game; private readonly OsuGameBase game;
public DummyWorkingBeatmap(OsuGameBase game = null) public DummyWorkingBeatmap(OsuGameBase game)
: base(new BeatmapInfo : base(new BeatmapInfo
{ {
Metadata = new BeatmapMetadata Metadata = new BeatmapMetadata
@ -34,7 +34,7 @@ namespace osu.Game.Beatmaps
OverallDifficulty = 0, OverallDifficulty = 0,
}, },
Ruleset = new DummyRulesetInfo() Ruleset = new DummyRulesetInfo()
}) }, game.Audio)
{ {
this.game = game; this.game = game;
} }
@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps
protected override Texture GetBackground() => game?.Textures.Get(@"Backgrounds/bg4"); protected override Texture GetBackground() => game?.Textures.Get(@"Backgrounds/bg4");
protected override Track GetTrack() => game?.Audio.Tracks.GetVirtual(1000); protected override Track GetTrack() => game?.Audio?.Tracks.GetVirtual(1000);
private class DummyRulesetInfo : RulesetInfo private class DummyRulesetInfo : RulesetInfo
{ {

View File

@ -29,8 +29,11 @@ namespace osu.Game.Beatmaps
public readonly BeatmapMetadata Metadata; public readonly BeatmapMetadata Metadata;
protected WorkingBeatmap(BeatmapInfo beatmapInfo) protected AudioManager AudioManager { get; }
protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager)
{ {
AudioManager = audioManager;
BeatmapInfo = beatmapInfo; BeatmapInfo = beatmapInfo;
BeatmapSetInfo = beatmapInfo.BeatmapSet; BeatmapSetInfo = beatmapInfo.BeatmapSet;
Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
@ -179,8 +182,6 @@ namespace osu.Game.Beatmaps
public bool SkinLoaded => skin.IsResultAvailable; public bool SkinLoaded => skin.IsResultAvailable;
public Skin Skin => skin.Value; public Skin Skin => skin.Value;
public AudioManager AudioManager { get; set; }
protected virtual Skin GetSkin() => new DefaultSkin(); protected virtual Skin GetSkin() => new DefaultSkin();
private readonly RecyclableLazy<Skin> skin; private readonly RecyclableLazy<Skin> skin;

View File

@ -195,7 +195,7 @@ namespace osu.Game
// this adds a global reduction of track volume for the time being. // this adds a global reduction of track volume for the time being.
Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio); beatmap = new OsuBindableBeatmap(defaultBeatmap);
dependencies.CacheAs<IBindable<WorkingBeatmap>>(beatmap); dependencies.CacheAs<IBindable<WorkingBeatmap>>(beatmap);
dependencies.CacheAs(beatmap); dependencies.CacheAs(beatmap);
@ -282,21 +282,9 @@ namespace osu.Game
private class OsuBindableBeatmap : BindableBeatmap private class OsuBindableBeatmap : BindableBeatmap
{ {
public OsuBindableBeatmap(WorkingBeatmap defaultValue) public OsuBindableBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue, null) : base(defaultValue)
{ {
} }
public OsuBindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager)
: base(defaultValue, audioManager)
{
}
public override BindableBeatmap GetBoundCopy()
{
var copy = new OsuBindableBeatmap(Default, AudioManager);
copy.BindTo(this);
return copy;
}
} }
private class OsuUserInputManager : UserInputManager private class OsuUserInputManager : UserInputManager

View File

@ -1,134 +1,30 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osuTK;
namespace osu.Game.Tests.Beatmaps namespace osu.Game.Tests.Beatmaps
{ {
public class TestWorkingBeatmap : WorkingBeatmap public class TestWorkingBeatmap : WorkingBeatmap
{ {
private readonly TrackVirtualManual track;
private readonly IBeatmap beatmap; private readonly IBeatmap beatmap;
/// <summary>
/// Create an instance which creates a <see cref="TestBeatmap"/> for the provided ruleset when requested.
/// </summary>
/// <param name="ruleset">The target ruleset.</param>
/// <param name="referenceClock">A clock which should be used instead of a stopwatch for virtual time progression.</param>
public TestWorkingBeatmap(RulesetInfo ruleset, IFrameBasedClock referenceClock)
: this(new TestBeatmap(ruleset), referenceClock)
{
}
/// <summary> /// <summary>
/// Create an instance which provides the <see cref="IBeatmap"/> when requested. /// Create an instance which provides the <see cref="IBeatmap"/> when requested.
/// </summary> /// </summary>
/// <param name="beatmap">The beatmap</param> /// <param name="beatmap">The beatmap</param>
/// <param name="referenceClock">An optional clock which should be used instead of a stopwatch for virtual time progression.</param> public TestWorkingBeatmap(IBeatmap beatmap)
public TestWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock referenceClock = null) : base(beatmap.BeatmapInfo, null)
: base(beatmap.BeatmapInfo)
{ {
this.beatmap = beatmap; this.beatmap = beatmap;
if (referenceClock != null)
track = new TrackVirtualManual(referenceClock);
} }
protected override IBeatmap GetBeatmap() => beatmap; protected override IBeatmap GetBeatmap() => beatmap;
protected override Texture GetBackground() => null; protected override Texture GetBackground() => null;
protected override Track GetTrack() => track;
/// <summary> protected override Track GetTrack() => null;
/// A virtual track which tracks a reference clock.
/// </summary>
public class TrackVirtualManual : Track
{
private readonly IFrameBasedClock referenceClock;
private readonly ManualClock clock = new ManualClock();
private bool running;
/// <summary>
/// Local offset added to the reference clock to resolve correct time.
/// </summary>
private double offset;
public TrackVirtualManual(IFrameBasedClock referenceClock)
{
this.referenceClock = referenceClock;
Length = double.PositiveInfinity;
}
public override bool Seek(double seek)
{
offset = MathHelper.Clamp(seek, 0, Length);
lastReferenceTime = null;
return offset == seek;
}
public override void Start()
{
running = true;
}
public override void Reset()
{
Seek(0);
base.Reset();
}
public override void Stop()
{
if (running)
{
running = false;
// on stopping, the current value should be transferred out of the clock, as we can no longer rely on
// the referenceClock (which will still be counting time).
offset = clock.CurrentTime;
lastReferenceTime = null;
}
}
public override bool IsRunning => running;
private double? lastReferenceTime;
public override double CurrentTime => clock.CurrentTime;
protected override void UpdateState()
{
base.UpdateState();
if (running)
{
double refTime = referenceClock.CurrentTime;
if (!lastReferenceTime.HasValue)
{
// if the clock just started running, the current value should be transferred to the offset
// (to zero the progression of time).
offset -= refTime;
}
lastReferenceTime = refTime;
}
clock.CurrentTime = Math.Min((lastReferenceTime ?? 0) + offset, Length);
if (CurrentTime >= Length)
{
Stop();
RaiseCompleted();
}
}
}
} }
} }

View File

@ -4,13 +4,10 @@
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual namespace osu.Game.Tests.Visual
{ {
@ -50,26 +47,20 @@ namespace osu.Game.Tests.Visual
protected abstract void AddCheckSteps(); protected abstract void AddCheckSteps();
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); private Player loadPlayerFor(RulesetInfo rulesetInfo)
protected virtual WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock clock) =>
new TestWorkingBeatmap(beatmap, Clock);
private Player loadPlayerFor(RulesetInfo ri)
{ {
Ruleset.Value = ri; Ruleset.Value = rulesetInfo;
var r = ri.CreateInstance(); var ruleset = rulesetInfo.CreateInstance();
var beatmap = CreateBeatmap(r); var working = CreateWorkingBeatmap(rulesetInfo);
var working = CreateWorkingBeatmap(beatmap, Clock);
Beatmap.Value = working; Beatmap.Value = working;
Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) };
Player?.Exit(); Player?.Exit();
Player = null; Player = null;
Player = CreatePlayer(r); Player = CreatePlayer(ruleset);
LoadScreen(Player); LoadScreen(Player);

View File

@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
@ -6,7 +6,6 @@ using System.Collections.Generic;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Screens.Edit; using osu.Game.Screens.Edit;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual namespace osu.Game.Tests.Visual
{ {
@ -24,7 +23,7 @@ namespace osu.Game.Tests.Visual
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Beatmap.Value = new TestWorkingBeatmap(ruleset.RulesetInfo, null); Beatmap.Value = CreateWorkingBeatmap(ruleset.RulesetInfo);
LoadScreen(new Editor()); LoadScreen(new Editor());
} }

View File

@ -3,15 +3,21 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Tests.Beatmaps;
using osuTK;
namespace osu.Game.Tests.Visual namespace osu.Game.Tests.Visual
{ {
@ -19,7 +25,7 @@ namespace osu.Game.Tests.Visual
{ {
[Cached(typeof(Bindable<WorkingBeatmap>))] [Cached(typeof(Bindable<WorkingBeatmap>))]
[Cached(typeof(IBindable<WorkingBeatmap>))] [Cached(typeof(IBindable<WorkingBeatmap>))]
private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap(), null); private OsuTestBeatmap beatmap;
protected BindableBeatmap Beatmap => beatmap; protected BindableBeatmap Beatmap => beatmap;
@ -39,7 +45,10 @@ namespace osu.Game.Tests.Visual
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{ {
// This is the earliest we can get OsuGameBase, which is used by the dummy working beatmap to find textures // This is the earliest we can get OsuGameBase, which is used by the dummy working beatmap to find textures
beatmap.Default = new DummyWorkingBeatmap(parent.Get<OsuGameBase>()); beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap(parent.Get<OsuGameBase>()))
{
Default = new DummyWorkingBeatmap(parent.Get<OsuGameBase>())
};
return Dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); return Dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
} }
@ -49,8 +58,19 @@ namespace osu.Game.Tests.Visual
localStorage = new Lazy<Storage>(() => new NativeStorage($"{GetType().Name}-{Guid.NewGuid()}")); localStorage = new Lazy<Storage>(() => new NativeStorage($"{GetType().Name}-{Guid.NewGuid()}"));
} }
[Resolved]
private AudioManager audio { get; set; }
protected virtual IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset);
protected WorkingBeatmap CreateWorkingBeatmap(RulesetInfo ruleset = null) =>
CreateWorkingBeatmap(CreateBeatmap(ruleset));
protected virtual WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap) =>
new ClockBackedTestWorkingBeatmap(beatmap, Clock, audio);
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audioManager, RulesetStore rulesets) private void load(RulesetStore rulesets)
{ {
Ruleset.Value = rulesets.AvailableRulesets.First(); Ruleset.Value = rulesets.AvailableRulesets.First();
} }
@ -59,7 +79,8 @@ namespace osu.Game.Tests.Visual
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
beatmap?.Value.Track.Stop(); if (beatmap?.Value.TrackLoaded == true)
beatmap.Value.Track.Stop();
if (localStorage.IsValueCreated) if (localStorage.IsValueCreated)
{ {
@ -76,6 +97,164 @@ namespace osu.Game.Tests.Visual
protected override ITestSceneTestRunner CreateRunner() => new OsuTestSceneTestRunner(); protected override ITestSceneTestRunner CreateRunner() => new OsuTestSceneTestRunner();
public class ClockBackedTestWorkingBeatmap : TestWorkingBeatmap
{
private readonly Track track;
private readonly TrackVirtualStore store;
/// <summary>
/// Create an instance which creates a <see cref="TestBeatmap"/> for the provided ruleset when requested.
/// </summary>
/// <param name="ruleset">The target ruleset.</param>
/// <param name="referenceClock">A clock which should be used instead of a stopwatch for virtual time progression.</param>
/// <param name="audio">Audio manager. Required if a reference clock isn't provided.</param>
public ClockBackedTestWorkingBeatmap(RulesetInfo ruleset, IFrameBasedClock referenceClock, AudioManager audio)
: this(new TestBeatmap(ruleset), referenceClock, audio)
{
}
/// <summary>
/// Create an instance which provides the <see cref="IBeatmap"/> when requested.
/// </summary>
/// <param name="beatmap">The beatmap</param>
/// <param name="referenceClock">An optional clock which should be used instead of a stopwatch for virtual time progression.</param>
/// <param name="audio">Audio manager. Required if a reference clock isn't provided.</param>
/// <param name="length">The length of the returned virtual track.</param>
public ClockBackedTestWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock referenceClock, AudioManager audio, double length = 60000)
: base(beatmap)
{
if (referenceClock != null)
{
store = new TrackVirtualStore(referenceClock);
audio.AddItem(store);
track = store.GetVirtual(length);
}
else
track = audio?.Tracks.GetVirtual(length);
}
public override void Dispose()
{
base.Dispose();
store?.Dispose();
}
protected override Track GetTrack() => track;
public class TrackVirtualStore : AudioCollectionManager<Track>, ITrackStore
{
private readonly IFrameBasedClock referenceClock;
public TrackVirtualStore(IFrameBasedClock referenceClock)
{
this.referenceClock = referenceClock;
}
public Track Get(string name) => throw new NotImplementedException();
public Task<Track> GetAsync(string name) => throw new NotImplementedException();
public Stream GetStream(string name) => throw new NotImplementedException();
public IEnumerable<string> GetAvailableResources() => throw new NotImplementedException();
public Track GetVirtual(double length = Double.PositiveInfinity)
{
var track = new TrackVirtualManual(referenceClock) { Length = length };
AddItem(track);
return track;
}
}
/// <summary>
/// A virtual track which tracks a reference clock.
/// </summary>
public class TrackVirtualManual : Track
{
private readonly IFrameBasedClock referenceClock;
private readonly ManualClock clock = new ManualClock();
private bool running;
/// <summary>
/// Local offset added to the reference clock to resolve correct time.
/// </summary>
private double offset;
public TrackVirtualManual(IFrameBasedClock referenceClock)
{
this.referenceClock = referenceClock;
Length = double.PositiveInfinity;
}
public override bool Seek(double seek)
{
offset = MathHelper.Clamp(seek, 0, Length);
lastReferenceTime = null;
return offset == seek;
}
public override void Start()
{
running = true;
}
public override void Reset()
{
Seek(0);
base.Reset();
}
public override void Stop()
{
if (running)
{
running = false;
// on stopping, the current value should be transferred out of the clock, as we can no longer rely on
// the referenceClock (which will still be counting time).
offset = clock.CurrentTime;
lastReferenceTime = null;
}
}
public override bool IsRunning => running;
private double? lastReferenceTime;
public override double CurrentTime => clock.CurrentTime;
protected override void UpdateState()
{
base.UpdateState();
if (running)
{
double refTime = referenceClock.CurrentTime;
if (!lastReferenceTime.HasValue)
{
// if the clock just started running, the current value should be transferred to the offset
// (to zero the progression of time).
offset -= refTime;
}
lastReferenceTime = refTime;
}
clock.CurrentTime = Math.Min((lastReferenceTime ?? 0) + offset, Length);
if (CurrentTime >= Length)
{
Stop();
RaiseCompleted();
}
}
}
}
public class OsuTestSceneTestRunner : OsuGameBase, ITestSceneTestRunner public class OsuTestSceneTestRunner : OsuGameBase, ITestSceneTestRunner
{ {
private TestSceneTestRunner.TestRunner runner; private TestSceneTestRunner.TestRunner runner;
@ -93,17 +272,10 @@ namespace osu.Game.Tests.Visual
private class OsuTestBeatmap : BindableBeatmap private class OsuTestBeatmap : BindableBeatmap
{ {
public OsuTestBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) public OsuTestBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue, audioManager) : base(defaultValue)
{ {
} }
public override BindableBeatmap GetBoundCopy()
{
var copy = new OsuTestBeatmap(Default, AudioManager);
copy.BindTo(this);
return copy;
}
} }
} }
} }

View File

@ -4,12 +4,10 @@
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual namespace osu.Game.Tests.Visual
{ {
@ -39,15 +37,13 @@ namespace osu.Game.Tests.Visual
AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1); AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1);
} }
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo);
protected virtual bool AllowFail => false; protected virtual bool AllowFail => false;
private void loadPlayer() private void loadPlayer()
{ {
var beatmap = CreateBeatmap(ruleset); var beatmap = CreateBeatmap(ruleset.RulesetInfo);
Beatmap.Value = new TestWorkingBeatmap(beatmap, Clock); Beatmap.Value = CreateWorkingBeatmap(beatmap);
if (!AllowFail) if (!AllowFail)
Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) };