From 6e797ddcac59f939f7fed68a9f0a91c1bf9a5143 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Oct 2021 12:41:17 +0900 Subject: [PATCH 1/5] Add test coverage of creating, saving and loading a new beatmap --- .../Visual/Editing/TestSceneEditorSaving.cs | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs new file mode 100644 index 0000000000..2258a209e2 --- /dev/null +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs @@ -0,0 +1,62 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Input; +using osu.Framework.Testing; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Edit; +using osu.Game.Screens.Edit; +using osu.Game.Screens.Menu; +using osu.Game.Screens.Select; +using osuTK.Input; + +namespace osu.Game.Tests.Visual.Editing +{ + public class TestSceneEditorSaving : OsuGameTestScene + { + private Editor editor => Game.ChildrenOfType().FirstOrDefault(); + + private EditorBeatmap editorBeatmap => (EditorBeatmap)editor.Dependencies.Get(typeof(EditorBeatmap)); + + /// + /// Tests the general expected flow of creating a new beatmap, saving it, then loading it back from song select. + /// + [Test] + public void TestNewBeatmapSaveThenLoad() + { + AddStep("set default beatmap", () => Game.Beatmap.SetDefault()); + + PushAndConfirm(() => new EditorLoader()); + + AddUntilStep("wait for editor load", () => editor != null); + + AddStep("Add timing point", () => editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint())); + + AddStep("Enter compose mode", () => InputManager.Key(Key.F1)); + AddUntilStep("Wait for compose mode load", () => editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true); + + AddStep("Change to placement mode", () => InputManager.Key(Key.Number2)); + AddStep("Move to playfield", () => InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre)); + AddStep("Place single hitcircle", () => InputManager.Click(MouseButton.Left)); + + AddStep("Save and exit", () => + { + InputManager.Keys(PlatformAction.Save); + InputManager.Key(Key.Escape); + }); + + AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu); + + PushAndConfirm(() => new PlaySongSelect()); + + AddUntilStep("Wait for beatmap selected", () => !Game.Beatmap.IsDefault); + AddStep("Open options", () => InputManager.Key(Key.F3)); + AddStep("Enter editor", () => InputManager.Key(Key.Number5)); + + AddUntilStep("Wait for editor load", () => editor != null); + AddAssert("Beatmap contains single hitcircle", () => editorBeatmap.HitObjects.Count == 1); + } + } +} From 007b33cd88d465253613f6d74d05c93c8a6a0882 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Oct 2021 12:05:11 +0900 Subject: [PATCH 2/5] Add missing methods to interfaces --- osu.Game/Beatmaps/BeatmapModelManager.cs | 4 ++-- osu.Game/Beatmaps/IBeatmapModelManager.cs | 20 ++++++++++++++++++++ osu.Game/Beatmaps/IWorkingBeatmapCache.cs | 12 ++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Beatmaps/IBeatmapModelManager.cs diff --git a/osu.Game/Beatmaps/BeatmapModelManager.cs b/osu.Game/Beatmaps/BeatmapModelManager.cs index 250d6653d5..787559899a 100644 --- a/osu.Game/Beatmaps/BeatmapModelManager.cs +++ b/osu.Game/Beatmaps/BeatmapModelManager.cs @@ -32,7 +32,7 @@ namespace osu.Game.Beatmaps /// Handles ef-core storage of beatmaps. /// [ExcludeFromDynamicCompile] - public class BeatmapModelManager : ArchiveModelManager + public class BeatmapModelManager : ArchiveModelManager, IBeatmapModelManager { /// /// Fired when a single difficulty has been hidden. @@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps /// /// The game working beatmap cache, used to invalidate entries on changes. /// - public WorkingBeatmapCache WorkingBeatmapCache { private get; set; } + public IWorkingBeatmapCache WorkingBeatmapCache { private get; set; } private readonly Bindable> beatmapRestored = new Bindable>(); diff --git a/osu.Game/Beatmaps/IBeatmapModelManager.cs b/osu.Game/Beatmaps/IBeatmapModelManager.cs new file mode 100644 index 0000000000..8c243c2b77 --- /dev/null +++ b/osu.Game/Beatmaps/IBeatmapModelManager.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Database; + +namespace osu.Game.Beatmaps +{ + public interface IBeatmapModelManager : IModelManager + { + /// + /// Provide an online lookup queue component to handle populating online beatmap metadata. + /// + BeatmapOnlineLookupQueue OnlineLookupQueue { set; } + + /// + /// Provide a working beatmap cache, used to invalidate entries on changes. + /// + IWorkingBeatmapCache WorkingBeatmapCache { set; } + } +} diff --git a/osu.Game/Beatmaps/IWorkingBeatmapCache.cs b/osu.Game/Beatmaps/IWorkingBeatmapCache.cs index 881e734292..3eb33f10d6 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmapCache.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmapCache.cs @@ -11,5 +11,17 @@ namespace osu.Game.Beatmaps /// The beatmap to lookup. /// A instance correlating to the provided . WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo); + + /// + /// Invalidate a cache entry if it exists. + /// + /// The beatmap set info to invalidate any cached entries for. + void Invalidate(BeatmapSetInfo beatmapSetInfo); + + /// + /// Invalidate a cache entry if it exists. + /// + /// The beatmap info to invalidate any cached entries for. + void Invalidate(BeatmapInfo beatmapInfo); } } From 8ffaa491e7303289b35de86eb1fb85e3a9097e81 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Oct 2021 12:05:30 +0900 Subject: [PATCH 3/5] Fix `BeatmapModelManager` not receiving `WorkingBeatmapCache` --- osu.Game/Beatmaps/BeatmapManager.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 91d5b16204..240db22c00 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -45,6 +45,7 @@ namespace osu.Game.Beatmaps workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, resources, new FileStore(contextFactory, storage).Store, defaultBeatmap, host); workingBeatmapCache.BeatmapManager = beatmapModelManager; + beatmapModelManager.WorkingBeatmapCache = workingBeatmapCache; if (performOnlineLookups) { @@ -305,6 +306,9 @@ namespace osu.Game.Beatmaps public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo importedBeatmap) => workingBeatmapCache.GetWorkingBeatmap(importedBeatmap); + void IWorkingBeatmapCache.Invalidate(BeatmapSetInfo beatmapSetInfo) => workingBeatmapCache.Invalidate(beatmapSetInfo); + void IWorkingBeatmapCache.Invalidate(BeatmapInfo beatmapInfo) => workingBeatmapCache.Invalidate(beatmapInfo); + #endregion #region Implementation of IModelFileManager From 90fdaf18c027ac08b3cd15e636105709dd6903e2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Oct 2021 12:40:25 +0900 Subject: [PATCH 4/5] Fix `PushAndConfirm` potentially failing if new screen quickly pushes a child screen --- osu.Game/Tests/Visual/OsuGameTestScene.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs index 881c4bab02..c025cf85c7 100644 --- a/osu.Game/Tests/Visual/OsuGameTestScene.cs +++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs @@ -83,8 +83,17 @@ namespace osu.Game.Tests.Visual protected void PushAndConfirm(Func newScreen) { Screen screen = null; - AddStep("Push new screen", () => Game.ScreenStack.Push(screen = newScreen())); - AddUntilStep("Wait for new screen", () => Game.ScreenStack.CurrentScreen == screen && screen.IsLoaded); + IScreen previousScreen = null; + + AddStep("Push new screen", () => + { + previousScreen = Game.ScreenStack.CurrentScreen; + Game.ScreenStack.Push(screen = newScreen()); + }); + + AddUntilStep("Wait for new screen", () => screen.IsLoaded + && Game.ScreenStack.CurrentScreen != previousScreen + && previousScreen.GetChildScreen() == screen); } protected void ConfirmAtMainMenu() => AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded); From d9849bcf4995b69bf493d9dcaab88950c40f3a4f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Oct 2021 13:14:39 +0900 Subject: [PATCH 5/5] Fix dragging on an editor file selection text box causing repeated popover display Local fix and no tests as this is a pretty weird usage of `TextBox`. We'll probably want to change it to not use a textbox eventually. Closes #14969. --- osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs b/osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs index fd43349793..f833bc49f7 100644 --- a/osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs +++ b/osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs @@ -89,6 +89,13 @@ namespace osu.Game.Screens.Edit.Setup { public Action OnFocused; + protected override bool OnDragStart(DragStartEvent e) + { + // This text box is intended to be "read only" without actually specifying that. + // As such we don't want to allow the user to select its content with a drag. + return false; + } + protected override void OnFocus(FocusEvent e) { OnFocused?.Invoke();