From f33a5bc54cee705bcdb8d8d77f1f1e314b2f322c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 May 2019 14:40:53 +0900 Subject: [PATCH] Centralise and update WorkingBeatmap creation in test cases --- .../TestSceneAutoJuiceStream.cs | 4 +- .../TestSceneBananaShower.cs | 4 +- .../TestSceneCatchStacker.cs | 4 +- .../TestSceneHyperDash.cs | 4 +- .../TestSceneHitCircleLongCombo.cs | 4 +- .../TestSceneSliderInput.cs | 5 +- .../TestSceneTaikoPlayfield.cs | 5 +- .../TestSceneBackgroundScreenBeatmap.cs | 5 +- .../Visual/Editor/TestSceneEditorCompose.cs | 3 +- .../Editor/TestSceneEditorComposeTimeline.cs | 5 +- .../Editor/TestSceneEditorSeekSnapping.cs | 5 +- .../Editor/TestSceneEditorSummaryTimeline.cs | 3 +- .../Editor/TestSceneHitObjectComposer.cs | 3 +- .../Visual/Editor/TestScenePlaybackControl.cs | 5 +- .../Visual/Editor/TestSceneWaveform.cs | 10 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 5 +- .../TestScenePlayerReferenceLeaking.cs | 5 +- .../TestSceneMatchSettingsOverlay.cs | 5 +- .../Visual/Online/TestSceneDirectPanel.cs | 3 +- .../SongSelect/TestSceneBeatmapDetailArea.cs | 14 +- .../SongSelect/TestSceneBeatmapInfoWedge.cs | 5 +- .../SongSelect/TestScenePlaySongSelect.cs | 5 +- osu.Game.Tests/WaveformTestBeatmap.cs | 13 +- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 3 +- osu.Game/Beatmaps/BindableBeatmap.cs | 26 +-- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 6 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 +- osu.Game/OsuGameBase.cs | 16 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 112 +--------- osu.Game/Tests/Visual/AllPlayersTestScene.cs | 21 +- osu.Game/Tests/Visual/EditorTestScene.cs | 5 +- osu.Game/Tests/Visual/OsuTestScene.cs | 198 ++++++++++++++++-- osu.Game/Tests/Visual/PlayerTestScene.cs | 8 +- 34 files changed, 278 insertions(+), 250 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index 9cec0d280d..ab3c040b4e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -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 { BeatmapInfo = new BeatmapInfo { BaseDifficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 }, - Ruleset = ruleset.RulesetInfo + Ruleset = ruleset } }; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs index 035bbe4b4e..0ad72412fc 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs @@ -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 { BeatmapInfo = new BeatmapInfo { BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 }, - Ruleset = ruleset.RulesetInfo + Ruleset = ruleset } }; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs index 7d7528372a..9ce46ad6ba 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs @@ -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 { BeatmapInfo = new BeatmapInfo { BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 }, - Ruleset = ruleset.RulesetInfo + Ruleset = ruleset } }; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 7393f75e5a..9cbff8c5d3 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -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); } - protected override IBeatmap CreateBeatmap(Ruleset ruleset) + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { var beatmap = new Beatmap { BeatmapInfo = { - Ruleset = ruleset.RulesetInfo, + Ruleset = ruleset, BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f } } }; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs index 921246751c..399cf22599 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs @@ -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 { BeatmapInfo = new BeatmapInfo { BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 }, - Ruleset = ruleset.RulesetInfo + Ruleset = ruleset } }; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 193cfe9c94..2eb783233a 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -20,7 +20,6 @@ using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Screens.Play; -using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual; using osuTK; @@ -299,7 +298,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("load player", () => { - Beatmap.Value = new TestWorkingBeatmap(new Beatmap + Beatmap.Value = CreateWorkingBeatmap(new Beatmap { HitObjects = { @@ -323,7 +322,7 @@ namespace osu.Game.Rulesets.Osu.Tests BaseDifficulty = new BeatmapDifficulty { SliderTickRate = 3 }, Ruleset = new OsuRuleset().RulesetInfo }, - }, Clock); + }); var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } }); diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs index 3634ec7d4a..6f9856df83 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayfield.cs @@ -18,7 +18,6 @@ using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.Taiko.UI; -using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual; using osuTK; using osu.Game.Rulesets.Scoring; @@ -64,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Tests var controlPointInfo = new ControlPointInfo(); controlPointInfo.TimingPoints.Add(new TimingControlPoint()); - WorkingBeatmap beatmap = new TestWorkingBeatmap(new Beatmap + WorkingBeatmap beatmap = CreateWorkingBeatmap(new Beatmap { HitObjects = new List { new CentreHit() }, BeatmapInfo = new BeatmapInfo @@ -79,7 +78,7 @@ namespace osu.Game.Rulesets.Taiko.Tests Ruleset = new TaikoRuleset().RulesetInfo }, ControlPointInfo = controlPointInfo - }, Clock); + }); Add(playfieldContainer = new Container { diff --git a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenBeatmap.cs b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenBeatmap.cs index c9bdcf928f..7104a420a3 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenBeatmap.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenBeatmap.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Threading; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input.Events; @@ -54,7 +55,7 @@ namespace osu.Game.Tests.Visual.Background private RulesetStore rulesets; [BackgroundDependencyLoader] - private void load(GameHost host) + private void load(GameHost host, AudioManager audio) { factory = new DatabaseContextFactory(LocalStorage); factory.ResetDatabase(); @@ -68,7 +69,7 @@ namespace osu.Game.Tests.Visual.Background usage.Migrate(); 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)); manager.Import(TestResources.GetTestBeatmapForImport()); diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorCompose.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorCompose.cs index b537cb0beb..608df1965e 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorCompose.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorCompose.cs @@ -7,7 +7,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Edit.Compose; -using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual.Editor { @@ -19,7 +18,7 @@ namespace osu.Game.Tests.Visual.Editor [BackgroundDependencyLoader] private void load() { - Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, Clock); + Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); Child = new ComposeScreen(); } } diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs index 154c58dd99..a8c2362910 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -30,9 +31,9 @@ namespace osu.Game.Tests.Visual.Editor }; [BackgroundDependencyLoader] - private void load() + private void load(AudioManager audio) { - Beatmap.Value = new WaveformTestBeatmap(); + Beatmap.Value = new WaveformTestBeatmap(audio); Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorSeekSnapping.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorSeekSnapping.cs index 590fa59107..b997d6aaeb 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorSeekSnapping.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorSeekSnapping.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Tests.Beatmaps; using osuTK; 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 }; } diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorSummaryTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorSummaryTimeline.cs index f20c921ff2..2e04eb50ca 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneEditorSummaryTimeline.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorSummaryTimeline.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Edit.Components.Timelines.Summary; -using osu.Game.Tests.Beatmaps; using osuTK; namespace osu.Game.Tests.Visual.Editor @@ -21,7 +20,7 @@ namespace osu.Game.Tests.Visual.Editor [BackgroundDependencyLoader] private void load() { - Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, null); + Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); Add(new SummaryTimeline { diff --git a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs index 47aa059b62..7accbe2fa8 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs @@ -18,7 +18,6 @@ using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components; -using osu.Game.Tests.Beatmaps; using osuTK; namespace osu.Game.Tests.Visual.Editor @@ -45,7 +44,7 @@ namespace osu.Game.Tests.Visual.Editor [BackgroundDependencyLoader] private void load() { - Beatmap.Value = new TestWorkingBeatmap(new Beatmap + Beatmap.Value = CreateWorkingBeatmap(new Beatmap { HitObjects = new List { diff --git a/osu.Game.Tests/Visual/Editor/TestScenePlaybackControl.cs b/osu.Game.Tests/Visual/Editor/TestScenePlaybackControl.cs index 126ab98291..0d4fe4366d 100644 --- a/osu.Game.Tests/Visual/Editor/TestScenePlaybackControl.cs +++ b/osu.Game.Tests/Visual/Editor/TestScenePlaybackControl.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Screens.Edit.Components; -using osu.Game.Tests.Beatmaps; using osuTK; namespace osu.Game.Tests.Visual.Editor @@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.Editor Size = new Vector2(200, 100) }; - Beatmap.Value = new TestWorkingBeatmap(new Beatmap(), Clock); + Beatmap.Value = CreateWorkingBeatmap(new Beatmap()); Child = playback; } diff --git a/osu.Game.Tests/Visual/Editor/TestSceneWaveform.cs b/osu.Game.Tests/Visual/Editor/TestSceneWaveform.cs index e93789b1d3..6e2500d711 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneWaveform.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneWaveform.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; @@ -19,10 +20,13 @@ namespace osu.Game.Tests.Visual.Editor { private WorkingBeatmap waveformBeatmap; + private OsuGameBase game; + [BackgroundDependencyLoader] - private void load() + private void load(AudioManager audio, OsuGameBase game) { - waveformBeatmap = new WaveformTestBeatmap(); + waveformBeatmap = new WaveformTestBeatmap(audio); + this.game = game; } [TestCase(1f)] @@ -91,7 +95,7 @@ namespace osu.Game.Tests.Visual.Editor Child = graph = new TestWaveformGraph { RelativeSizeAxes = Axes.Both, - Waveform = new DummyWorkingBeatmap().Waveform, + Waveform = new DummyWorkingBeatmap(game).Waveform, }, }; }); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 5c26f733ab..daee3a520c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -16,7 +16,6 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Screens; using osu.Game.Screens.Play; -using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual.Gameplay { @@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.Gameplay public void Setup() => Schedule(() => { 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] diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs index c75fb2567b..65b56319e8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs @@ -3,7 +3,6 @@ using System; using osu.Framework.Lists; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets; 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); return working; } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSettingsOverlay.cs index 21b97fe73b..76a0604818 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSettingsOverlay.cs @@ -19,6 +19,9 @@ namespace osu.Game.Tests.Visual.Multiplayer { public class TestSceneMatchSettingsOverlay : MultiplayerTestScene { + [Resolved] + private OsuGameBase game { get; set; } + public override IReadOnlyList RequiredTypes => new[] { typeof(MatchSettingsOverlay) @@ -57,7 +60,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("set name", () => Room.Name.Value = "Room name"); 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); AddStep("clear name", () => Room.Name.Value = ""); diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index a3d932a383..8b67892fbb 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays.Direct; using osu.Game.Rulesets.Osu; -using osu.Game.Tests.Beatmaps; using osuTK; namespace osu.Game.Tests.Visual.Online @@ -25,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online [BackgroundDependencyLoader] 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.HasStoryboard = true; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs index cf4362ba28..d398423b9a 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetailArea.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Screens.Select; @@ -18,7 +19,8 @@ namespace osu.Game.Tests.Visual.SongSelect { public override IReadOnlyList RequiredTypes => new[] { typeof(BeatmapDetails) }; - public TestSceneBeatmapDetailArea() + [BackgroundDependencyLoader] + private void load(OsuGameBase game) { BeatmapDetailArea detailsArea; Add(detailsArea = new BeatmapDetailArea @@ -28,7 +30,7 @@ namespace osu.Game.Tests.Visual.SongSelect Size = new Vector2(550f, 450f), }); - AddStep("all metrics", () => detailsArea.Beatmap = new DummyWorkingBeatmap + AddStep("all metrics", () => detailsArea.Beatmap = new DummyWorkingBeatmap(game) { 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 = { @@ -82,7 +84,7 @@ namespace osu.Game.Tests.Visual.SongSelect } }); - AddStep("ratings", () => detailsArea.Beatmap = new DummyWorkingBeatmap + AddStep("ratings", () => detailsArea.Beatmap = new DummyWorkingBeatmap(game) { 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 = { @@ -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 = { diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs index b1ed5c46c2..9969795ecf 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; @@ -18,7 +18,6 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Taiko; using osu.Game.Screens.Select; -using osu.Game.Tests.Beatmaps; using osuTK; namespace osu.Game.Tests.Visual.SongSelect @@ -136,7 +135,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep($"select {b?.Metadata.Title ?? "null"} beatmap", () => { 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); diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 7e962dbc06..ebee358730 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.MathUtils; @@ -79,7 +80,7 @@ namespace osu.Game.Tests.Visual.SongSelect } [BackgroundDependencyLoader] - private void load(GameHost host) + private void load(GameHost host, AudioManager audio) { factory = new DatabaseContextFactory(LocalStorage); factory.ResetDatabase(); @@ -93,7 +94,7 @@ namespace osu.Game.Tests.Visual.SongSelect usage.Migrate(); 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(); } diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs index f66b374cd7..36cc1e5ad2 100644 --- a/osu.Game.Tests/WaveformTestBeatmap.cs +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; +using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; @@ -19,12 +20,14 @@ namespace osu.Game.Tests { private readonly ZipArchiveReader reader; private readonly Stream stream; + private readonly ITrackStore trackStore; - public WaveformTestBeatmap() - : base(new BeatmapInfo()) + public WaveformTestBeatmap(AudioManager audioManager) + : base(new BeatmapInfo(), audioManager) { stream = TestResources.GetTestBeatmapStream(); reader = new ZipArchiveReader(stream); + trackStore = audioManager.GetTrackStore(reader); } public override void Dispose() @@ -32,17 +35,17 @@ namespace osu.Game.Tests base.Dispose(); stream?.Dispose(); reader?.Dispose(); + trackStore?.Dispose(); } protected override IBeatmap GetBeatmap() => createTestBeatmap(); 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 Beatmap createTestBeatmap() diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 798bca3ada..0200dd44ac 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -429,7 +429,7 @@ namespace osu.Game.Beatmaps private readonly IBeatmap beatmap; public DummyConversionBeatmap(IBeatmap beatmap) - : base(beatmap.BeatmapInfo) + : base(beatmap.BeatmapInfo, null) { this.beatmap = beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index cfeb6b0a92..e1cc5db3ad 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -22,11 +22,10 @@ namespace osu.Game.Beatmaps private readonly IResourceStore store; public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, BeatmapInfo beatmapInfo, AudioManager audioManager) - : base(beatmapInfo) + : base(beatmapInfo, audioManager) { this.store = store; this.textureStore = textureStore; - AudioManager = audioManager; } protected override IBeatmap GetBeatmap() diff --git a/osu.Game/Beatmaps/BindableBeatmap.cs b/osu.Game/Beatmaps/BindableBeatmap.cs index 6614a6f2fb..1e69a17ef7 100644 --- a/osu.Game/Beatmaps/BindableBeatmap.cs +++ b/osu.Game/Beatmaps/BindableBeatmap.cs @@ -2,8 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Diagnostics; -using JetBrains.Annotations; -using osu.Framework.Audio; using osu.Framework.Bindables; namespace osu.Game.Beatmaps @@ -14,29 +12,20 @@ namespace osu.Game.Beatmaps /// public abstract class BindableBeatmap : NonNullableBindable { - protected AudioManager AudioManager; - private WorkingBeatmap lastBeatmap; - protected BindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) + protected BindableBeatmap(WorkingBeatmap defaultValue) : base(defaultValue) { - // we don't want to attempt to update tracks if we are a bound copy. - 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); - } + BindValueChanged(b => updateAudioTrack(b.NewValue), true); } private void updateAudioTrack(WorkingBeatmap beatmap) { 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) if (!trackLoaded || lastBeatmap?.Track != beatmap.Track) { @@ -51,12 +40,5 @@ namespace osu.Game.Beatmaps lastBeatmap = beatmap; } - - /// - /// Retrieve a new instance weakly bound to this . - /// If you are further binding to events of the retrieved , ensure a local reference is held. - /// - [NotNull] - public new abstract BindableBeatmap GetBoundCopy(); } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index b35e98085a..72b477713a 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -18,7 +18,7 @@ namespace osu.Game.Beatmaps { private readonly OsuGameBase game; - public DummyWorkingBeatmap(OsuGameBase game = null) + public DummyWorkingBeatmap(OsuGameBase game) : base(new BeatmapInfo { Metadata = new BeatmapMetadata @@ -34,7 +34,7 @@ namespace osu.Game.Beatmaps OverallDifficulty = 0, }, Ruleset = new DummyRulesetInfo() - }) + }, game.Audio) { this.game = game; } @@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps 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 { diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 6c8f283923..cf1acaf46b 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -29,8 +29,11 @@ namespace osu.Game.Beatmaps public readonly BeatmapMetadata Metadata; - protected WorkingBeatmap(BeatmapInfo beatmapInfo) + protected AudioManager AudioManager { get; } + + protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager) { + AudioManager = audioManager; BeatmapInfo = beatmapInfo; BeatmapSetInfo = beatmapInfo.BeatmapSet; Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); @@ -179,8 +182,6 @@ namespace osu.Game.Beatmaps public bool SkinLoaded => skin.IsResultAvailable; public Skin Skin => skin.Value; - public AudioManager AudioManager { get; set; } - protected virtual Skin GetSkin() => new DefaultSkin(); private readonly RecyclableLazy skin; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8e663de8c5..39f5144cf8 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -195,7 +195,7 @@ namespace osu.Game // this adds a global reduction of track volume for the time being. Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); - beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio); + beatmap = new OsuBindableBeatmap(defaultBeatmap); dependencies.CacheAs>(beatmap); dependencies.CacheAs(beatmap); @@ -282,21 +282,9 @@ namespace osu.Game private class OsuBindableBeatmap : BindableBeatmap { 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 diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index c558275f62..0ef35879e3 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -1,134 +1,30 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; -using osu.Framework.Timing; using osu.Game.Beatmaps; -using osu.Game.Rulesets; -using osuTK; namespace osu.Game.Tests.Beatmaps { public class TestWorkingBeatmap : WorkingBeatmap { - private readonly TrackVirtualManual track; private readonly IBeatmap beatmap; - /// - /// Create an instance which creates a for the provided ruleset when requested. - /// - /// The target ruleset. - /// A clock which should be used instead of a stopwatch for virtual time progression. - public TestWorkingBeatmap(RulesetInfo ruleset, IFrameBasedClock referenceClock) - : this(new TestBeatmap(ruleset), referenceClock) - { - } - /// /// Create an instance which provides the when requested. /// /// The beatmap - /// An optional clock which should be used instead of a stopwatch for virtual time progression. - public TestWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock referenceClock = null) - : base(beatmap.BeatmapInfo) + public TestWorkingBeatmap(IBeatmap beatmap) + : base(beatmap.BeatmapInfo, null) { this.beatmap = beatmap; - - if (referenceClock != null) - track = new TrackVirtualManual(referenceClock); } protected override IBeatmap GetBeatmap() => beatmap; + protected override Texture GetBackground() => null; - protected override Track GetTrack() => track; - /// - /// A virtual track which tracks a reference clock. - /// - public class TrackVirtualManual : Track - { - private readonly IFrameBasedClock referenceClock; - - private readonly ManualClock clock = new ManualClock(); - - private bool running; - - /// - /// Local offset added to the reference clock to resolve correct time. - /// - 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(); - } - } - } + protected override Track GetTrack() => null; } } diff --git a/osu.Game/Tests/Visual/AllPlayersTestScene.cs b/osu.Game/Tests/Visual/AllPlayersTestScene.cs index 454fbe1222..b7d1979b0d 100644 --- a/osu.Game/Tests/Visual/AllPlayersTestScene.cs +++ b/osu.Game/Tests/Visual/AllPlayersTestScene.cs @@ -4,13 +4,10 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Screens; -using osu.Framework.Timing; -using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; -using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual { @@ -50,26 +47,20 @@ namespace osu.Game.Tests.Visual protected abstract void AddCheckSteps(); - protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); - - protected virtual WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock clock) => - new TestWorkingBeatmap(beatmap, Clock); - - private Player loadPlayerFor(RulesetInfo ri) + private Player loadPlayerFor(RulesetInfo rulesetInfo) { - Ruleset.Value = ri; - var r = ri.CreateInstance(); + Ruleset.Value = rulesetInfo; + var ruleset = rulesetInfo.CreateInstance(); - var beatmap = CreateBeatmap(r); - var working = CreateWorkingBeatmap(beatmap, Clock); + var working = CreateWorkingBeatmap(rulesetInfo); 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 = null; - Player = CreatePlayer(r); + Player = CreatePlayer(ruleset); LoadScreen(Player); diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 14c0f0950f..75bbb3e110 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -6,7 +6,6 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Game.Rulesets; using osu.Game.Screens.Edit; -using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual { @@ -24,7 +23,7 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load() { - Beatmap.Value = new TestWorkingBeatmap(ruleset.RulesetInfo, null); + Beatmap.Value = CreateWorkingBeatmap(ruleset.RulesetInfo); LoadScreen(new Editor()); } diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 806b73b517..d8a63d23e1 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -3,15 +3,21 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Platform; using osu.Framework.Testing; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Tests.Beatmaps; +using osuTK; namespace osu.Game.Tests.Visual { @@ -19,7 +25,7 @@ namespace osu.Game.Tests.Visual { [Cached(typeof(Bindable))] [Cached(typeof(IBindable))] - private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap(), null); + private OsuTestBeatmap beatmap; protected BindableBeatmap Beatmap => beatmap; @@ -39,7 +45,10 @@ namespace osu.Game.Tests.Visual 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 - beatmap.Default = new DummyWorkingBeatmap(parent.Get()); + beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap(parent.Get())) + { + Default = new DummyWorkingBeatmap(parent.Get()) + }; return Dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); } @@ -49,8 +58,19 @@ namespace osu.Game.Tests.Visual localStorage = new Lazy(() => 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] - private void load(AudioManager audioManager, RulesetStore rulesets) + private void load(RulesetStore rulesets) { Ruleset.Value = rulesets.AvailableRulesets.First(); } @@ -59,7 +79,8 @@ namespace osu.Game.Tests.Visual { base.Dispose(isDisposing); - beatmap?.Value.Track.Stop(); + if (beatmap?.Value.TrackLoaded == true) + beatmap.Value.Track.Stop(); if (localStorage.IsValueCreated) { @@ -76,6 +97,164 @@ namespace osu.Game.Tests.Visual protected override ITestSceneTestRunner CreateRunner() => new OsuTestSceneTestRunner(); + public class ClockBackedTestWorkingBeatmap : TestWorkingBeatmap + { + private readonly Track track; + + private readonly TrackVirtualStore store; + + /// + /// Create an instance which creates a for the provided ruleset when requested. + /// + /// The target ruleset. + /// A clock which should be used instead of a stopwatch for virtual time progression. + /// Audio manager. Required if a reference clock isn't provided. + public ClockBackedTestWorkingBeatmap(RulesetInfo ruleset, IFrameBasedClock referenceClock, AudioManager audio) + : this(new TestBeatmap(ruleset), referenceClock, audio) + { + } + + /// + /// Create an instance which provides the when requested. + /// + /// The beatmap + /// An optional clock which should be used instead of a stopwatch for virtual time progression. + /// Audio manager. Required if a reference clock isn't provided. + /// The length of the returned virtual track. + 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, ITrackStore + { + private readonly IFrameBasedClock referenceClock; + + public TrackVirtualStore(IFrameBasedClock referenceClock) + { + this.referenceClock = referenceClock; + } + + public Track Get(string name) => throw new NotImplementedException(); + + public Task GetAsync(string name) => throw new NotImplementedException(); + + public Stream GetStream(string name) => throw new NotImplementedException(); + + public IEnumerable GetAvailableResources() => throw new NotImplementedException(); + + public Track GetVirtual(double length = Double.PositiveInfinity) + { + var track = new TrackVirtualManual(referenceClock) { Length = length }; + AddItem(track); + return track; + } + } + + /// + /// A virtual track which tracks a reference clock. + /// + public class TrackVirtualManual : Track + { + private readonly IFrameBasedClock referenceClock; + + private readonly ManualClock clock = new ManualClock(); + + private bool running; + + /// + /// Local offset added to the reference clock to resolve correct time. + /// + 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 { private TestSceneTestRunner.TestRunner runner; @@ -93,17 +272,10 @@ namespace osu.Game.Tests.Visual private class OsuTestBeatmap : BindableBeatmap { - public OsuTestBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) - : base(defaultValue, audioManager) + public OsuTestBeatmap(WorkingBeatmap defaultValue) + : base(defaultValue) { } - - public override BindableBeatmap GetBoundCopy() - { - var copy = new OsuTestBeatmap(Default, AudioManager); - copy.BindTo(this); - return copy; - } } } } diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 0c39194088..03e17a819c 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -4,12 +4,10 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Testing; -using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; -using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual { @@ -39,15 +37,13 @@ namespace osu.Game.Tests.Visual AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1); } - protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); - protected virtual bool AllowFail => false; private void loadPlayer() { - var beatmap = CreateBeatmap(ruleset); + var beatmap = CreateBeatmap(ruleset.RulesetInfo); - Beatmap.Value = new TestWorkingBeatmap(beatmap, Clock); + Beatmap.Value = CreateWorkingBeatmap(beatmap); if (!AllowFail) Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) };