From 6d6fea47ab32c6dafbeb909189df9846741dce10 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 5 Aug 2018 14:36:09 +0900 Subject: [PATCH 01/11] Reduce animations of osu!direct list mode The panels' content was flying around and felt really shocking. This fixes elements in place to provide a better experience. --- osu.Game/Overlays/Direct/DirectListPanel.cs | 77 +++++++++++---------- osu.Game/Overlays/Direct/DirectPanel.cs | 5 +- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 45e1164a57..850ead37f6 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -12,7 +12,6 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Allocation; using osu.Framework.Localisation; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.States; using osu.Game.Beatmaps; namespace osu.Game.Overlays.Direct @@ -26,12 +25,14 @@ namespace osu.Game.Overlays.Direct private PlayButton playButton; private Box progressBar; - private Container downloadContainer; + + protected override bool FadePlayButton => false; protected override PlayButton PlayButton => playButton; protected override Box PreviewBar => progressBar; - public DirectListPanel(BeatmapSetInfo beatmap) : base(beatmap) + public DirectListPanel(BeatmapSetInfo beatmap) + : base(beatmap) { RelativeSizeAxes = Axes.X; Height = height; @@ -66,30 +67,45 @@ namespace osu.Game.Overlays.Direct Spacing = new Vector2(10, 0), Children = new Drawable[] { - playButton = new PlayButton(SetInfo) - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - Size = new Vector2(height / 2), - FillMode = FillMode.Fit, - Alpha = 0, - }, new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Children = new Drawable[] { - new OsuSpriteText + new FillFlowContainer { - Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), - TextSize = 18, - Font = @"Exo2.0-BoldItalic", - }, - new OsuSpriteText - { - Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), - Font = @"Exo2.0-BoldItalic", + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + playButton = new PlayButton(SetInfo) + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Size = new Vector2(height / 2), + FillMode = FillMode.Fit, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuSpriteText + { + Current = localisation.GetUnicodePreference(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title), + TextSize = 18, + Font = @"Exo2.0-BoldItalic", + }, + new OsuSpriteText + { + Current = localisation.GetUnicodePreference(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist), + Font = @"Exo2.0-BoldItalic", + }, + } + }, + } }, new FillFlowContainer { @@ -108,16 +124,13 @@ namespace osu.Game.Overlays.Direct Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - LayoutEasing = Easing.OutQuint, - LayoutDuration = transition_duration, Children = new Drawable[] { - downloadContainer = new Container + new Container { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, - Alpha = 0, Child = new DownloadButton(SetInfo) { Size = new Vector2(height - vertical_padding * 3), @@ -184,17 +197,5 @@ namespace osu.Game.Overlays.Direct }, }); } - - protected override bool OnHover(InputState state) - { - downloadContainer.FadeIn(transition_duration, Easing.InOutQuint); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - downloadContainer.FadeOut(transition_duration, Easing.InOutQuint); - base.OnHoverLost(state); - } } } diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 7d5c0c16cc..5a73aab23e 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -40,6 +40,8 @@ namespace osu.Game.Overlays.Direct protected abstract PlayButton PlayButton { get; } protected abstract Box PreviewBar { get; } + protected virtual bool FadePlayButton => true; + protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -125,6 +127,7 @@ namespace osu.Game.Overlays.Direct { content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); content.MoveToY(-4, hover_transition_time, Easing.OutQuint); + if (FadePlayButton) PlayButton.FadeIn(120, Easing.InOutQuint); return base.OnHover(state); @@ -134,7 +137,7 @@ namespace osu.Game.Overlays.Direct { content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); content.MoveToY(0, hover_transition_time, Easing.OutQuint); - if (!PreviewPlaying) + if (FadePlayButton && !PreviewPlaying) PlayButton.FadeOut(120, Easing.InOutQuint); base.OnHoverLost(state); From f719b9bef58da1e82dce0d702c8f498446dd5865 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 7 Aug 2018 12:20:24 +0900 Subject: [PATCH 02/11] Fix mania scroll direction not being read from database --- osu.Game.Rulesets.Mania/UI/ManiaScrollingInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaScrollingInfo.cs b/osu.Game.Rulesets.Mania/UI/ManiaScrollingInfo.cs index a1cc7cfbc7..624ea13e1b 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaScrollingInfo.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaScrollingInfo.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.UI public ManiaScrollingInfo(ManiaConfigManager config) { config.BindWith(ManiaSetting.ScrollDirection, configDirection); - configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v); + configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true); } } } From 7b8bd7f21c6b1b7f2b36cde8ce57f46b0e9d9f55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Aug 2018 14:49:44 +0900 Subject: [PATCH 03/11] Fix mod selection not restoring when re-entering song select --- osu.Game.Tests/Visual/TestCaseMods.cs | 3 + osu.Game/OsuGame.cs | 5 +- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 70 ++++++++++++---------- osu.Game/Screens/Select/PlaySongSelect.cs | 15 +++-- 4 files changed, 54 insertions(+), 39 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMods.cs b/osu.Game.Tests/Visual/TestCaseMods.cs index cc396a63e3..6330afe860 100644 --- a/osu.Game.Tests/Visual/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/TestCaseMods.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using System.Linq; using System.Collections.Generic; +using osu.Framework.Configuration; using osu.Game.Rulesets.Osu; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.Sprites; @@ -237,6 +238,8 @@ namespace osu.Game.Tests.Visual private class TestModSelectOverlay : ModSelectOverlay { + public new Bindable> SelectedMods => base.SelectedMods; + public ModButton GetModButton(Mod mod) { var section = ModSectionsContainer.Children.Single(s => s.ModType == mod.Type); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 025d5f50e3..69d1236126 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -99,7 +99,7 @@ namespace osu.Game private readonly List overlays = new List(); // todo: move this to SongSelect once Screen has the ability to unsuspend. - public readonly Bindable> SelectedMods = new Bindable>(new List()); + private readonly Bindable> selectedMods = new Bindable>(new List()); public OsuGame(string[] args = null) { @@ -153,6 +153,9 @@ namespace osu.Game dependencies.CacheAs(ruleset); dependencies.CacheAs>(ruleset); + dependencies.CacheAs(selectedMods); + dependencies.CacheAs>>(selectedMods); + // bind config int to database RulesetInfo configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 4745eba68d..3f28b7ccfd 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -39,9 +39,39 @@ namespace osu.Game.Overlays.Mods protected readonly FillFlowContainer ModSectionsContainer; - public readonly Bindable> SelectedMods = new Bindable>(); + protected readonly Bindable> SelectedMods = new Bindable>(); - public readonly IBindable Ruleset = new Bindable(); + protected readonly IBindable Ruleset = new Bindable(); + + [BackgroundDependencyLoader] + private void load(OsuColour colours, IBindable ruleset, AudioManager audio, Bindable> selectedMods) + { + LowMultiplierColour = colours.Red; + HighMultiplierColour = colours.Green; + UnrankedLabel.Colour = colours.Blue; + + Ruleset.BindTo(ruleset); + SelectedMods.BindTo(selectedMods); + + sampleOn = audio.Sample.Get(@"UI/check-on"); + sampleOff = audio.Sample.Get(@"UI/check-off"); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Ruleset.BindValueChanged(rulesetChanged, true); + SelectedMods.BindValueChanged(selectedModsChanged, true); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + Ruleset.UnbindAll(); + SelectedMods.UnbindAll(); + } private void rulesetChanged(RulesetInfo newRuleset) { @@ -51,33 +81,16 @@ namespace osu.Game.Overlays.Mods foreach (ModSection section in ModSectionsContainer.Children) section.Mods = instance.GetModsFor(section.ModType); + + // attempt to re-select any already selected mods. + // this may be the first time we are receiving the ruleset, in which case they will still match. + selectedModsChanged(SelectedMods.Value); + + // write the mods back to the SelectedMods bindable in the case a change was not applicable. + // this generally isn't required as the previous line will perform deselection; just here for safety. refreshSelectedMods(); } - [BackgroundDependencyLoader] - private void load(OsuColour colours, IBindable ruleset, AudioManager audio) - { - SelectedMods.ValueChanged += selectedModsChanged; - - LowMultiplierColour = colours.Red; - HighMultiplierColour = colours.Green; - UnrankedLabel.Colour = colours.Blue; - - Ruleset.BindTo(ruleset); - Ruleset.BindValueChanged(rulesetChanged, true); - - sampleOn = audio.Sample.Get(@"UI/check-on"); - sampleOff = audio.Sample.Get(@"UI/check-off"); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - Ruleset.UnbindAll(); - SelectedMods.UnbindAll(); - } - private void selectedModsChanged(IEnumerable obj) { foreach (ModSection section in ModSectionsContainer.Children) @@ -176,10 +189,7 @@ namespace osu.Game.Overlays.Mods refreshSelectedMods(); } - private void refreshSelectedMods() - { - SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray(); - } + private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray(); public ModSelectOverlay() { diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index a346911ca2..7a832caf41 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -50,13 +50,12 @@ namespace osu.Game.Screens.Select private SampleChannel sampleConfirm; - public readonly Bindable> SelectedMods = new Bindable>(new List()); + private readonly Bindable> selectedMods = new Bindable>(new List()); [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu) + private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, Bindable> selectedMods) { - if (osu != null) SelectedMods.BindTo(osu.SelectedMods); - modSelect.SelectedMods.BindTo(SelectedMods); + if (selectedMods != null) this.selectedMods.BindTo(selectedMods); sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection"); @@ -84,7 +83,7 @@ namespace osu.Game.Screens.Select protected override void UpdateBeatmap(WorkingBeatmap beatmap) { - beatmap.Mods.BindTo(SelectedMods); + beatmap.Mods.BindTo(selectedMods); base.UpdateBeatmap(beatmap); @@ -131,7 +130,7 @@ namespace osu.Game.Screens.Select if (Beatmap.Value.Track != null) Beatmap.Value.Track.Looping = false; - SelectedMods.UnbindAll(); + selectedMods.UnbindAll(); Beatmap.Value.Mods.Value = new Mod[] { }; return false; @@ -147,10 +146,10 @@ namespace osu.Game.Screens.Select var auto = Ruleset.Value.CreateInstance().GetAutoplayMod(); var autoType = auto.GetType(); - var mods = modSelect.SelectedMods.Value; + var mods = selectedMods.Value; if (mods.All(m => m.GetType() != autoType)) { - modSelect.SelectedMods.Value = mods.Append(auto); + selectedMods.Value = mods.Append(auto); removeAutoModOnResume = true; } } From 4cb7063801e561a4e58494f30befec96d413f6eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Aug 2018 16:45:18 +0900 Subject: [PATCH 04/11] Add automated testing of mod preservation/removal --- osu.Game.Tests/Visual/TestCaseMods.cs | 79 +++++++++++++--------- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 6 +- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- 4 files changed, 52 insertions(+), 37 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseMods.cs b/osu.Game.Tests/Visual/TestCaseMods.cs index 6330afe860..ab53dbd968 100644 --- a/osu.Game.Tests/Visual/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/TestCaseMods.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Overlays.Mods; @@ -13,12 +12,11 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using System.Linq; using System.Collections.Generic; +using NUnit.Framework; using osu.Framework.Configuration; -using osu.Game.Rulesets.Osu; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Mods.Sections; -using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.UI; using OpenTK.Graphics; @@ -51,11 +49,6 @@ namespace osu.Game.Tests.Visual private void load(RulesetStore rulesets) { this.rulesets = rulesets; - } - - protected override void LoadComplete() - { - base.LoadComplete(); Add(modSelect = new TestModSelectOverlay { @@ -72,34 +65,25 @@ namespace osu.Game.Tests.Visual Position = new Vector2(0, 25), }); + modDisplay.Current.UnbindBindings(); modDisplay.Current.BindTo(modSelect.SelectedMods); - AddStep("Toggle", modSelect.ToggleVisibility); - AddStep("Hide", modSelect.Hide); AddStep("Show", modSelect.Show); - - foreach (var rulesetInfo in rulesets.AvailableRulesets) - { - Ruleset ruleset = rulesetInfo.CreateInstance(); - AddStep($"switch to {ruleset.Description}", () => Ruleset.Value = rulesetInfo); - - switch (ruleset) - { - case OsuRuleset or: - testOsuMods(or); - break; - case ManiaRuleset mr: - testManiaMods(mr); - break; - } - } + AddStep("Toggle", modSelect.ToggleVisibility); + AddStep("Toggle", modSelect.ToggleVisibility); } - private void testOsuMods(OsuRuleset ruleset) + [Test] + public void TestOsuMods() { - var easierMods = ruleset.GetModsFor(ModType.DifficultyReduction); - var harderMods = ruleset.GetModsFor(ModType.DifficultyIncrease); - var assistMods = ruleset.GetModsFor(ModType.Automation); + var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 0); + AddStep("change ruleset", () => { Ruleset.Value = ruleset; }); + + var instance = ruleset.CreateInstance(); + + var easierMods = instance.GetModsFor(ModType.DifficultyReduction); + var harderMods = instance.GetModsFor(ModType.DifficultyIncrease); + var assistMods = instance.GetModsFor(ModType.Automation); var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail); var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden); @@ -121,9 +105,40 @@ namespace osu.Game.Tests.Visual testUnimplementedMod(autoPilotMod); } - private void testManiaMods(ManiaRuleset ruleset) + [Test] + public void TestManiaMods() { - testRankedText(ruleset.GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom)); + var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 3); + AddStep("change ruleset", () => { Ruleset.Value = ruleset; }); + + testRankedText(ruleset.CreateInstance().GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom)); + } + + [Test] + public void TestRulesetChanges() + { + var rulesetOsu = rulesets.AvailableRulesets.First(r => r.ID == 0); + var rulesetMania = rulesets.AvailableRulesets.First(r => r.ID == 3); + + AddStep("change ruleset to null", () => { Ruleset.Value = null; }); + + var instance = rulesetOsu.CreateInstance(); + var easierMods = instance.GetModsFor(ModType.DifficultyReduction); + var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail); + + AddStep("set mods externally", () => { modDisplay.Current.Value = new[] { noFailMod }; }); + + AddStep("change ruleset to osu", () => { Ruleset.Value = rulesetOsu; }); + + AddAssert("ensure mods still selected", () => modDisplay.Current.Value.Single(m => m is OsuModNoFail) != null); + + AddStep("change ruleset to mania", () => { Ruleset.Value = rulesetMania; }); + + AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any(m => m is OsuModNoFail)); + + AddStep("change ruleset to osu", () => { Ruleset.Value = rulesetOsu; }); + + AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any()); } private void testSingleMod(Mod mod) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 69d1236126..4d9a12943f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -99,7 +99,7 @@ namespace osu.Game private readonly List overlays = new List(); // todo: move this to SongSelect once Screen has the ability to unsuspend. - private readonly Bindable> selectedMods = new Bindable>(new List()); + private readonly Bindable> selectedMods = new Bindable>(new Mod[] { }); public OsuGame(string[] args = null) { diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 3f28b7ccfd..45703ac56d 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -39,11 +39,11 @@ namespace osu.Game.Overlays.Mods protected readonly FillFlowContainer ModSectionsContainer; - protected readonly Bindable> SelectedMods = new Bindable>(); + protected readonly Bindable> SelectedMods = new Bindable>(new Mod[] { }); protected readonly IBindable Ruleset = new Bindable(); - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(OsuColour colours, IBindable ruleset, AudioManager audio, Bindable> selectedMods) { LowMultiplierColour = colours.Red; @@ -51,7 +51,7 @@ namespace osu.Game.Overlays.Mods UnrankedLabel.Colour = colours.Blue; Ruleset.BindTo(ruleset); - SelectedMods.BindTo(selectedMods); + if (selectedMods != null) SelectedMods.BindTo(selectedMods); sampleOn = audio.Sample.Get(@"UI/check-on"); sampleOff = audio.Sample.Get(@"UI/check-off"); diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 7a832caf41..210c03f2d9 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Select private SampleChannel sampleConfirm; - private readonly Bindable> selectedMods = new Bindable>(new List()); + private readonly Bindable> selectedMods = new Bindable>(new Mod[] { }); [BackgroundDependencyLoader(true)] private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, Bindable> selectedMods) From 6379c70a68ae4369483f64b3cb3275a9b85d48c4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 8 Aug 2018 11:28:44 +0900 Subject: [PATCH 05/11] Add some ticks --- osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs index fdc8f362f7..30318464de 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Mania.Tests private Drawable createHoldNoteDisplay(ScrollingDirection direction) { - var note = new HoldNote { StartTime = 999999999, Duration = 1000 }; + var note = new HoldNote { StartTime = 999999999, Duration = 5000 }; note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); return new ScrollingTestContainer(direction) From 31146fbc014f24630438ff1d5b0d96c3ab592bb5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 8 Aug 2018 11:28:55 +0900 Subject: [PATCH 06/11] Add anchor/origin tests --- .../TestCaseNotes.cs | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs index 30318464de..a8b2b20fda 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs @@ -46,15 +46,20 @@ namespace osu.Game.Rulesets.Mania.Tests Spacing = new Vector2(20), Children = new[] { - createNoteDisplay(ScrollingDirection.Down), - createNoteDisplay(ScrollingDirection.Up), - createHoldNoteDisplay(ScrollingDirection.Down), - createHoldNoteDisplay(ScrollingDirection.Up), + createNoteDisplay(ScrollingDirection.Down, 1, out var note1), + createNoteDisplay(ScrollingDirection.Up, 2, out var note2), + createHoldNoteDisplay(ScrollingDirection.Down, 1, out var holdNote1), + createHoldNoteDisplay(ScrollingDirection.Up, 2, out var holdNote2), } }; + + AddAssert("note 1 facing downwards", () => verifyAnchors(note1, Anchor.y2)); + AddAssert("note 2 facing upwards", () => verifyAnchors(note2, Anchor.y0)); + AddAssert("hold note 1 facing downwards", () => verifyAnchors(holdNote1, Anchor.y2)); + AddAssert("hold note 2 facing upwards", () => verifyAnchors(holdNote2, Anchor.y0)); } - private Drawable createNoteDisplay(ScrollingDirection direction) + private Drawable createNoteDisplay(ScrollingDirection direction, int identifier, out DrawableNote hitObject) { var note = new Note { StartTime = 999999999 }; note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); @@ -62,14 +67,14 @@ namespace osu.Game.Rulesets.Mania.Tests return new ScrollingTestContainer(direction) { AutoSizeAxes = Axes.Both, - Child = new NoteContainer(direction, $"note, scrolling {direction.ToString().ToLowerInvariant()}") + Child = new NoteContainer(direction, $"note {identifier}, scrolling {direction.ToString().ToLowerInvariant()}") { - Child = new DrawableNote(note) { AccentColour = Color4.OrangeRed } + Child = hitObject = new DrawableNote(note) { AccentColour = Color4.OrangeRed } } }; } - private Drawable createHoldNoteDisplay(ScrollingDirection direction) + private Drawable createHoldNoteDisplay(ScrollingDirection direction, int identifier, out DrawableHoldNote hitObject) { var note = new HoldNote { StartTime = 999999999, Duration = 5000 }; note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); @@ -77,9 +82,9 @@ namespace osu.Game.Rulesets.Mania.Tests return new ScrollingTestContainer(direction) { AutoSizeAxes = Axes.Both, - Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLowerInvariant()}") + Child = new NoteContainer(direction, $"hold note {identifier}, scrolling {direction.ToString().ToLowerInvariant()}") { - Child = new DrawableHoldNote(note) + Child = hitObject = new DrawableHoldNote(note) { RelativeSizeAxes = Axes.Both, AccentColour = Color4.OrangeRed, @@ -88,6 +93,12 @@ namespace osu.Game.Rulesets.Mania.Tests }; } + private bool verifyAnchors(DrawableHitObject hitObject, Anchor expectedAnchor) + => hitObject.Anchor.HasFlag(expectedAnchor) && hitObject.Origin.HasFlag(expectedAnchor); + + private bool verifyAnchors(DrawableHoldNote holdNote, Anchor expectedAnchor) + => verifyAnchors((DrawableHitObject)holdNote, expectedAnchor) && holdNote.NestedHitObjects.All(n => verifyAnchors(n, expectedAnchor)); + private class NoteContainer : Container { private readonly Container content; From dc7804983938cf6e721f4f1823576df8f968036a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 8 Aug 2018 12:21:44 +0900 Subject: [PATCH 07/11] Add test for propagation of direction through mania stack --- .../ScrollingTestContainer.cs | 22 ++++++++----------- .../TestCaseStage.cs | 21 ++++++++++++++++-- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs b/osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs index 5a93efb0dc..29663c2093 100644 --- a/osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs +++ b/osu.Game.Rulesets.Mania.Tests/ScrollingTestContainer.cs @@ -14,24 +14,20 @@ namespace osu.Game.Rulesets.Mania.Tests /// public class ScrollingTestContainer : Container { - private readonly ScrollingDirection direction; + [Cached(Type = typeof(IScrollingInfo))] + private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo(); public ScrollingTestContainer(ScrollingDirection direction) { - this.direction = direction; + scrollingInfo.Direction.Value = direction; } - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(new ScrollingInfo { Direction = { Value = direction }}); - return dependencies; - } + public void Flip() => scrollingInfo.Direction.Value = scrollingInfo.Direction.Value == ScrollingDirection.Up ? ScrollingDirection.Down : ScrollingDirection.Up; + } - private class ScrollingInfo : IScrollingInfo - { - public readonly Bindable Direction = new Bindable(); - IBindable IScrollingInfo.Direction => Direction; - } + public class TestScrollingInfo : IScrollingInfo + { + public readonly Bindable Direction = new Bindable(); + IBindable IScrollingInfo.Direction => Direction; } } diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs index b1bb7f5187..5c5d955168 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -24,6 +25,8 @@ namespace osu.Game.Rulesets.Mania.Tests private readonly List stages = new List(); + private FillFlowContainer fill; + public TestCaseStage() : base(columns) { @@ -32,7 +35,7 @@ namespace osu.Game.Rulesets.Mania.Tests [BackgroundDependencyLoader] private void load() { - Child = new FillFlowContainer + Child = fill = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, @@ -54,8 +57,22 @@ namespace osu.Game.Rulesets.Mania.Tests AddStep("hold note", createHoldNote); AddStep("minor bar line", () => createBarLine(false)); AddStep("major bar line", () => createBarLine(true)); + + AddAssert("check note anchors", () => notesInStageAreAnchored(stages[0], Anchor.TopCentre)); + AddAssert("check note anchors", () => notesInStageAreAnchored(stages[1], Anchor.BottomCentre)); + + AddStep("flip direction", () => + { + foreach (var c in fill.Children) + c.Flip(); + }); + + AddAssert("check note anchors", () => notesInStageAreAnchored(stages[0], Anchor.BottomCentre)); + AddAssert("check note anchors", () => notesInStageAreAnchored(stages[1], Anchor.TopCentre)); } + private bool notesInStageAreAnchored(ManiaStage stage, Anchor anchor) => stage.Columns.SelectMany(c => c.AllHitObjects).All(o => o.Anchor == anchor); + private void createNote() { foreach (var stage in stages) @@ -101,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Tests } } - private Drawable createStage(ScrollingDirection direction, ManiaAction action) + private ScrollingTestContainer createStage(ScrollingDirection direction, ManiaAction action) { var specialAction = ManiaAction.Special1; From 4453b5facafe6f41ebf1c1f041b180527ba32df4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 8 Aug 2018 12:26:57 +0900 Subject: [PATCH 08/11] Cache mods at PlaySongSelect --- osu.Game/OsuGame.cs | 2 ++ osu.Game/Screens/Select/PlaySongSelect.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4d9a12943f..5923037cd9 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -99,6 +99,8 @@ namespace osu.Game private readonly List overlays = new List(); // todo: move this to SongSelect once Screen has the ability to unsuspend. + [Cached] + [Cached(Type = typeof(IBindable>))] private readonly Bindable> selectedMods = new Bindable>(new Mod[] { }); public OsuGame(string[] args = null) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 210c03f2d9..e914eb365e 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -50,6 +50,8 @@ namespace osu.Game.Screens.Select private SampleChannel sampleConfirm; + [Cached] + [Cached(Type = typeof(IBindable>))] private readonly Bindable> selectedMods = new Bindable>(new Mod[] { }); [BackgroundDependencyLoader(true)] From bfbe00e6eca12dedfda65c1307788a55b5f3d6d8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 8 Aug 2018 15:38:09 +0900 Subject: [PATCH 09/11] Remove multiple caching --- osu.Game/OsuGame.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5923037cd9..a1e385921f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -155,9 +155,6 @@ namespace osu.Game dependencies.CacheAs(ruleset); dependencies.CacheAs>(ruleset); - dependencies.CacheAs(selectedMods); - dependencies.CacheAs>>(selectedMods); - // bind config int to database RulesetInfo configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); From 2a5b9f79ffb81964af128f23a1d6ef4f7660e7e0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 8 Aug 2018 15:49:27 +0900 Subject: [PATCH 10/11] Indent --- osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 5a73aab23e..322db0b7d6 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -128,7 +128,7 @@ namespace osu.Game.Overlays.Direct content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); content.MoveToY(-4, hover_transition_time, Easing.OutQuint); if (FadePlayButton) - PlayButton.FadeIn(120, Easing.InOutQuint); + PlayButton.FadeIn(120, Easing.InOutQuint); return base.OnHover(state); } From b8824a41b583453e7ac6656b0f7e69028cb761fe Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Aug 2018 11:44:53 +0900 Subject: [PATCH 11/11] Fix certain control points not being replaced --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 26f28c86ca..29be751de2 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -354,6 +354,11 @@ namespace osu.Game.Beatmaps.Formats private void handleTimingControlPoint(TimingControlPoint newPoint) { + var existing = beatmap.ControlPointInfo.TimingPointAt(newPoint.Time); + + if (existing.Time == newPoint.Time) + beatmap.ControlPointInfo.TimingPoints.Remove(existing); + beatmap.ControlPointInfo.TimingPoints.Add(newPoint); } @@ -364,7 +369,9 @@ namespace osu.Game.Beatmaps.Formats if (newPoint.EquivalentTo(existing)) return; - beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == newPoint.Time); + if (existing.Time == newPoint.Time) + beatmap.ControlPointInfo.DifficultyPoints.Remove(existing); + beatmap.ControlPointInfo.DifficultyPoints.Add(newPoint); } @@ -375,6 +382,9 @@ namespace osu.Game.Beatmaps.Formats if (newPoint.EquivalentTo(existing)) return; + if (existing.Time == newPoint.Time) + beatmap.ControlPointInfo.EffectPoints.Remove(existing); + beatmap.ControlPointInfo.EffectPoints.Add(newPoint); } @@ -385,6 +395,9 @@ namespace osu.Game.Beatmaps.Formats if (newPoint.EquivalentTo(existing)) return; + if (existing.Time == newPoint.Time) + beatmap.ControlPointInfo.SamplePoints.Remove(existing); + beatmap.ControlPointInfo.SamplePoints.Add(newPoint); }