diff --git a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs index 17535cae98..124d3bb453 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs @@ -5,12 +5,15 @@ using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Platform; using osu.Framework.Screens; using osu.Framework.Testing; +using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; @@ -18,7 +21,9 @@ using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Screens; using osu.Game.Screens.Menu; +using osu.Game.Screens.Play; using osu.Game.Screens.Select; +using osu.Game.Tests.Beatmaps.IO; using osuTK; using osuTK.Graphics; using osuTK.Input; @@ -31,11 +36,11 @@ namespace osu.Game.Tests.Visual.Menus private const float click_padding = 25; private GameHost host; - private TestOsuGame osuGame; + private TestOsuGame game; - private Vector2 backButtonPosition => osuGame.ToScreenSpace(new Vector2(click_padding, osuGame.LayoutRectangle.Bottom - click_padding)); + private Vector2 backButtonPosition => game.ToScreenSpace(new Vector2(click_padding, game.LayoutRectangle.Bottom - click_padding)); - private Vector2 optionsButtonPosition => osuGame.ToScreenSpace(new Vector2(click_padding, click_padding)); + private Vector2 optionsButtonPosition => game.ToScreenSpace(new Vector2(click_padding, click_padding)); [BackgroundDependencyLoader] private void load(GameHost host) @@ -54,23 +59,23 @@ namespace osu.Game.Tests.Visual.Menus { AddStep("Create new game instance", () => { - if (osuGame != null) + if (game != null) { - Remove(osuGame); - osuGame.Dispose(); + Remove(game); + game.Dispose(); } - osuGame = new TestOsuGame(LocalStorage, API); - osuGame.SetHost(host); + game = new TestOsuGame(LocalStorage, API); + game.SetHost(host); // todo: this can be removed once we can run audio trakcs without a device present // see https://github.com/ppy/osu/issues/1302 - osuGame.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles); + game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles); - Add(osuGame); + Add(game); }); - AddUntilStep("Wait for load", () => osuGame.IsLoaded); - AddUntilStep("Wait for intro", () => osuGame.ScreenStack.CurrentScreen is IntroScreen); + AddUntilStep("Wait for load", () => game.IsLoaded); + AddUntilStep("Wait for intro", () => game.ScreenStack.CurrentScreen is IntroScreen); confirmAtMainMenu(); } @@ -82,11 +87,39 @@ namespace osu.Game.Tests.Visual.Menus pushAndConfirm(() => songSelect = new TestSongSelect()); AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show()); AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible); - AddStep("Press escape", () => pressAndRelease(Key.Escape)); + pushEscape(); AddAssert("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden); exitViaEscapeAndConfirm(); } + [Test] + public void TestSongContinuesAfterExitPlayer() + { + Player player = null; + + WorkingBeatmap beatmap() => game.Beatmap.Value; + Track track() => beatmap().Track; + + pushAndConfirm(() => new TestSongSelect()); + + AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(game).Wait()); + + AddUntilStep("wait for selected", () => !(track() is TrackVirtual)); + + AddStep("press enter", () => pressAndRelease(Key.Enter)); + + AddUntilStep("wait for player", () => (player = game.ScreenStack.CurrentScreen as Player) != null); + AddUntilStep("wait for fail", () => player.HasFailed); + + AddUntilStep("wait for track stop", () => !track().IsRunning); + AddAssert("Ensure time before preview point", () => track().CurrentTime < beatmap().Metadata.PreviewTime); + + pushEscape(); + + AddUntilStep("wait for track playing", () => track().IsRunning); + AddAssert("Ensure time wasn't reset to preview point", () => track().CurrentTime < beatmap().Metadata.PreviewTime); + } + [Test] public void TestExitSongSelectWithClick() { @@ -98,7 +131,7 @@ namespace osu.Game.Tests.Visual.Menus AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition)); // BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered. - AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == osuGame.BackButton)); + AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == game.BackButton)); AddStep("Click back button", () => InputManager.Click(MouseButton.Left)); AddUntilStep("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden); @@ -122,25 +155,28 @@ namespace osu.Game.Tests.Visual.Menus [Test] public void TestOpenOptionsAndExitWithEscape() { - AddUntilStep("Wait for options to load", () => osuGame.Settings.IsLoaded); + AddUntilStep("Wait for options to load", () => game.Settings.IsLoaded); AddStep("Enter menu", () => pressAndRelease(Key.Enter)); AddStep("Move mouse to options overlay", () => InputManager.MoveMouseTo(optionsButtonPosition)); AddStep("Click options overlay", () => InputManager.Click(MouseButton.Left)); - AddAssert("Options overlay was opened", () => osuGame.Settings.State.Value == Visibility.Visible); + AddAssert("Options overlay was opened", () => game.Settings.State.Value == Visibility.Visible); AddStep("Hide options overlay using escape", () => pressAndRelease(Key.Escape)); - AddAssert("Options overlay was closed", () => osuGame.Settings.State.Value == Visibility.Hidden); + AddAssert("Options overlay was closed", () => game.Settings.State.Value == Visibility.Hidden); } private void pushAndConfirm(Func newScreen) { Screen screen = null; - AddStep("Push new screen", () => osuGame.ScreenStack.Push(screen = newScreen())); - AddUntilStep("Wait for new screen", () => osuGame.ScreenStack.CurrentScreen == screen && screen.IsLoaded); + AddStep("Push new screen", () => game.ScreenStack.Push(screen = newScreen())); + AddUntilStep("Wait for new screen", () => game.ScreenStack.CurrentScreen == screen && screen.IsLoaded); } + private void pushEscape() => + AddStep("Press escape", () => pressAndRelease(Key.Escape)); + private void exitViaEscapeAndConfirm() { - AddStep("Press escape", () => pressAndRelease(Key.Escape)); + pushEscape(); confirmAtMainMenu(); } @@ -151,7 +187,7 @@ namespace osu.Game.Tests.Visual.Menus confirmAtMainMenu(); } - private void confirmAtMainMenu() => AddUntilStep("Wait for main menu", () => osuGame.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded); + private void confirmAtMainMenu() => AddUntilStep("Wait for main menu", () => game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded); private void pressAndRelease(Key key) { @@ -169,6 +205,8 @@ namespace osu.Game.Tests.Visual.Menus public new OsuConfigManager LocalConfig => base.LocalConfig; + public new Bindable Beatmap => base.Beatmap; + protected override Loader CreateLoader() => new TestLoader(); public TestOsuGame(Storage storage, IAPIProvider api) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6c5f64ed6c..0025188ad4 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -490,7 +490,7 @@ namespace osu.Game.Screens.Select if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending) { UpdateBeatmap(Beatmap.Value); - ensurePlayingSelected(); + ensurePlayingSelected(false); } base.OnResuming(last); @@ -587,7 +587,8 @@ namespace osu.Game.Screens.Select /// Ensures some music is playing for the current track. /// Will resume playback from a manual user pause if the track has changed. /// - private void ensurePlayingSelected() + /// Whether to restart from the preview point, rather than resuming from previous location. + private void ensurePlayingSelected(bool fromPreviewPoint = true) { Track track = Beatmap.Value.Track; @@ -596,7 +597,12 @@ namespace osu.Game.Screens.Select track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; if (!track.IsRunning && (music?.IsUserPaused != true || isNewTrack)) - track.Restart(); + { + if (fromPreviewPoint) + track.Restart(); + else + track.Start(); + } lastTrack.SetTarget(track); }