From 28375ed1fcf62d69ef1b2e4231d5e583005327ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 15:03:07 +0900 Subject: [PATCH 01/11] Allow transfer of previously loaded background between WorkingBeatmaps --- osu.Game/Beatmaps/WorkingBeatmap.cs | 3 +++ osu.Game/Database/BeatmapInfo.cs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 616128dab5..589557b088 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -94,6 +94,9 @@ namespace osu.Game.Beatmaps { if (track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo)) other.track = track; + + if (background != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo)) + other.background = background; } public virtual void Dispose() diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index 5097622deb..c2e35d64a8 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -93,5 +93,9 @@ namespace osu.Game.Database public bool AudioEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && BeatmapSet.Path == other.BeatmapSet.Path && (Metadata ?? BeatmapSet.Metadata).AudioFile == (other.Metadata ?? other.BeatmapSet.Metadata).AudioFile; + + public bool BackgroundEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && + BeatmapSet.Path == other.BeatmapSet.Path && + (Metadata ?? BeatmapSet.Metadata).BackgroundFile == (other.Metadata ?? other.BeatmapSet.Metadata).BackgroundFile; } } From b78fa99620bdb66185a6435ed8f4f21a8eb8f581 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 20:31:09 +0900 Subject: [PATCH 02/11] Don't perform a selection if we already have the correct panel selected. --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 06aaea041a..dbaf20ddb8 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -331,6 +331,8 @@ namespace osu.Game.Screens.Select if (panel == null) panel = group.BeatmapPanels.First(); + if (selectedPanel == panel) return; + Trace.Assert(group.BeatmapPanels.Contains(panel), @"Selected panel must be in provided group"); if (selectedGroup != null && selectedGroup != group && selectedGroup.State != BeatmapGroupState.Hidden) From 003cf534411a1ba09c2ce413b4fddfc520b4e4b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 20:43:42 +0900 Subject: [PATCH 03/11] Streamline panel selection event logic. Was previously firing multiple times where it was completely unnecessary. Also had bidirection firing going on. --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 6 ++---- osu.Game/Screens/Select/BeatmapCarousel.cs | 6 ++++-- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 8c1378cae4..11cc6122ac 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps.Drawables /// /// Fires when one of our difficulties was selected. Will fire on first expand. /// - public Action SelectionChanged; + public Action SelectionChanged; /// /// Fires when one of our difficulties is clicked when already selected. Should start playing the map. @@ -89,8 +89,6 @@ namespace osu.Game.Beatmaps.Drawables //we want to make sure one of our children is selected in the case none have been selected yet. if (SelectedPanel == null) BeatmapPanels.First().State = PanelSelectedState.Selected; - else - SelectionChanged?.Invoke(this, SelectedPanel.Beatmap); } private void panelGainedSelection(BeatmapPanel panel) @@ -106,7 +104,7 @@ namespace osu.Game.Beatmaps.Drawables finally { State = BeatmapGroupState.Expanded; - SelectionChanged?.Invoke(this, panel.Beatmap); + SelectionChanged?.Invoke(this, SelectedPanel); } } } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index dbaf20ddb8..c2c5aca0de 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -120,7 +120,7 @@ namespace osu.Game.Screens.Select public void RemoveBeatmap(BeatmapSetInfo info) => removeGroup(groups.Find(b => b.BeatmapSet.ID == info.ID)); - public Action SelectionChanged; + public Action SelectionChanged; public Action StartRequested; @@ -230,7 +230,7 @@ namespace osu.Game.Screens.Select return new BeatmapGroup(beatmapSet, database) { - SelectionChanged = SelectionChanged, + SelectionChanged = (g, p) => selectGroup(g, p), StartRequested = b => StartRequested?.Invoke(), State = BeatmapGroupState.Collapsed }; @@ -345,6 +345,8 @@ namespace osu.Game.Screens.Select float selectedY = computeYPositions(animated); ScrollTo(selectedY, animated); + + SelectionChanged?.Invoke(panel.Beatmap); } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 182158fa5d..5d64525f68 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -300,7 +300,7 @@ namespace osu.Game.Screens.Select /// /// selection has been changed as the result of interaction with the carousel. /// - private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap) + private void selectionChanged(BeatmapInfo beatmap) { bool beatmapSetChange = false; From 45729a8881dab10347765ed7375d5b84e5484a1b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 20:44:16 +0900 Subject: [PATCH 04/11] Add debounce to WorkingBeatmap creation at song select. Improves perceived performance when quickly moving through carousel. --- osu.Game/Screens/Select/SongSelect.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 5d64525f68..94415de667 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -15,6 +15,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Input; using osu.Framework.Screens; +using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Database; @@ -297,6 +298,11 @@ namespace osu.Game.Screens.Select carousel.SelectBeatmap(beatmap?.BeatmapInfo); } + ScheduledDelegate selectionChangedDebounce; + + // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. + private BeatmapInfo selectionChangeNoBounce; + /// /// selection has been changed as the result of interaction with the carousel. /// @@ -306,16 +312,23 @@ namespace osu.Game.Screens.Select if (!beatmap.Equals(Beatmap?.BeatmapInfo)) { - if (beatmap.BeatmapSetInfoID == Beatmap?.BeatmapInfo.BeatmapSetInfoID) + if (beatmap.BeatmapSetInfoID == selectionChangeNoBounce?.BeatmapSetInfoID) sampleChangeDifficulty.Play(); else { sampleChangeBeatmap.Play(); beatmapSetChange = true; } - Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); } - ensurePlayingSelected(beatmapSetChange); + + selectionChangeNoBounce = beatmap; + + selectionChangedDebounce?.Cancel(); + selectionChangedDebounce = Scheduler.AddDelayed(delegate + { + Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); + ensurePlayingSelected(beatmapSetChange); + }, 100); } private void ensurePlayingSelected(bool preview = false) From 59cc5ea00a945914bfe047966b7a1dc2c1e08106 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 20:50:23 +0900 Subject: [PATCH 05/11] CI Fixes. --- osu.Game/Screens/Select/SongSelect.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 94415de667..a6bb65af51 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -17,7 +17,6 @@ using osu.Framework.Input; using osu.Framework.Screens; using osu.Framework.Threading; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.Drawables; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -298,7 +297,7 @@ namespace osu.Game.Screens.Select carousel.SelectBeatmap(beatmap?.BeatmapInfo); } - ScheduledDelegate selectionChangedDebounce; + private ScheduledDelegate selectionChangedDebounce; // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. private BeatmapInfo selectionChangeNoBounce; From 70e81115f4bb9054d512bec61adae041b65e9c71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 21:16:37 +0900 Subject: [PATCH 06/11] Refactor BeatmapInfoWedge to suck a little less. --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 341 ++++++++++---------- 1 file changed, 174 insertions(+), 167 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 61c1f0cc33..6397b5812b 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -74,156 +74,21 @@ namespace osu.Game.Screens.Select } State = Visibility.Visible; - var lastContainer = beatmapInfoContainer; - - float newDepth = lastContainer?.Depth + 1 ?? 0; - - BeatmapInfo beatmapInfo = beatmap.BeatmapInfo; - BeatmapMetadata metadata = beatmap.BeatmapInfo?.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); - - List labels = new List(); - - if (beatmap.Beatmap != null) - { - HitObject lastObject = beatmap.Beatmap.HitObjects.LastOrDefault(); - double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; - - labels.Add(new InfoLabel(new BeatmapStatistic - { - Name = "Length", - Icon = FontAwesome.fa_clock_o, - Content = beatmap.Beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.Beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), - })); - - labels.Add(new InfoLabel(new BeatmapStatistic - { - Name = "BPM", - Icon = FontAwesome.fa_circle, - Content = getBPMRange(beatmap.Beatmap), - })); - - //get statistics fromt he current ruleset. - labels.AddRange(beatmap.BeatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s))); - } - AlwaysPresent = true; + var lastContainer = beatmapInfoContainer; + float newDepth = lastContainer?.Depth + 1 ?? 0; + Add(beatmapInfoContainer = new AsyncLoadWrapper( - new BufferedContainer + new BufferedWedgeInfo(beatmap) { + Shear = -Shear, OnLoadComplete = d => { FadeIn(250); lastContainer?.FadeOut(250); lastContainer?.Expire(); - }, - PixelSnapping = true, - CacheDrawnFrameBuffer = true, - Shear = -Shear, - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - // We will create the white-to-black gradient by modulating transparency and having - // a black backdrop. This results in an sRGB-space gradient and not linear space, - // transitioning from white to black more perceptually uniformly. - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - // We use a container, such that we can set the colour gradient to go across the - // vertices of the masked container instead of the vertices of the (larger) sprite. - new Container - { - RelativeSizeAxes = Axes.Both, - ColourInfo = ColourInfo.GradientVertical(Color4.White, Color4.White.Opacity(0.3f)), - Children = new[] - { - // Zoomed-in and cropped beatmap background - new BeatmapBackgroundSprite(beatmap) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - FillMode = FillMode.Fill, - }, - }, - }, - new DifficultyColourBar(beatmap.BeatmapInfo) - { - RelativeSizeAxes = Axes.Y, - Width = 20, - }, - new FillFlowContainer - { - Name = "Top-aligned metadata", - Anchor = Anchor.TopLeft, - Origin = Anchor.TopLeft, - Direction = FillDirection.Vertical, - Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 20 }, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new OsuSpriteText - { - Font = @"Exo2.0-MediumItalic", - Text = beatmapInfo.Version, - TextSize = 24, - }, - } - }, - new FillFlowContainer - { - Name = "Bottom-aligned metadata", - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Direction = FillDirection.Vertical, - Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 }, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new OsuSpriteText - { - Font = @"Exo2.0-MediumItalic", - Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title, - TextSize = 28, - }, - new OsuSpriteText - { - Font = @"Exo2.0-MediumItalic", - Text = metadata.Artist, - TextSize = 17, - }, - new FillFlowContainer - { - Margin = new MarginPadding { Top = 10 }, - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Children = new[] - { - new OsuSpriteText - { - Font = @"Exo2.0-Medium", - Text = "mapped by ", - TextSize = 15, - }, - new OsuSpriteText - { - Font = @"Exo2.0-Bold", - Text = metadata.Author, - TextSize = 15, - }, - } - }, - new FillFlowContainer - { - Margin = new MarginPadding { Top = 20, Left = 10 }, - Spacing = new Vector2(40, 0), - AutoSizeAxes = Axes.Both, - Children = labels - }, - } - }, } }) { @@ -231,23 +96,164 @@ namespace osu.Game.Screens.Select }); } - private string getBPMRange(Beatmap beatmap) + public class BufferedWedgeInfo : BufferedContainer { - double bpmMax = beatmap.TimingInfo.BPMMaximum; - double bpmMin = beatmap.TimingInfo.BPMMinimum; - - if (Precision.AlmostEquals(bpmMin, bpmMax)) return Math.Round(bpmMin) + "bpm"; - - return Math.Round(bpmMin) + "-" + Math.Round(bpmMax) + "bpm (mostly " + Math.Round(beatmap.TimingInfo.BPMMode) + "bpm)"; - } - - public class InfoLabel : Container - { - public InfoLabel(BeatmapStatistic statistic) + public BufferedWedgeInfo(WorkingBeatmap beatmap) { - AutoSizeAxes = Axes.Both; + BeatmapInfo beatmapInfo = beatmap.BeatmapInfo; + BeatmapMetadata metadata = beatmap.BeatmapInfo?.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); + + List labels = new List(); + + if (beatmap.Beatmap != null) + { + HitObject lastObject = beatmap.Beatmap.HitObjects.LastOrDefault(); + double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + + labels.Add(new InfoLabel(new BeatmapStatistic + { + Name = "Length", + Icon = FontAwesome.fa_clock_o, + Content = beatmap.Beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.Beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), + })); + + labels.Add(new InfoLabel(new BeatmapStatistic + { + Name = "BPM", + Icon = FontAwesome.fa_circle, + Content = getBPMRange(beatmap.Beatmap), + })); + + //get statistics fromt he current ruleset. + labels.AddRange(beatmap.BeatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s))); + } + + PixelSnapping = true; + CacheDrawnFrameBuffer = true; + RelativeSizeAxes = Axes.Both; + Children = new Drawable[] { + // We will create the white-to-black gradient by modulating transparency and having + // a black backdrop. This results in an sRGB-space gradient and not linear space, + // transitioning from white to black more perceptually uniformly. + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + // We use a container, such that we can set the colour gradient to go across the + // vertices of the masked container instead of the vertices of the (larger) sprite. + new Container + { + RelativeSizeAxes = Axes.Both, + ColourInfo = ColourInfo.GradientVertical(Color4.White, Color4.White.Opacity(0.3f)), + Children = new[] + { + // Zoomed-in and cropped beatmap background + new BeatmapBackgroundSprite(beatmap) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fill, + }, + }, + }, + new DifficultyColourBar(beatmap.BeatmapInfo) + { + RelativeSizeAxes = Axes.Y, + Width = 20, + }, + new FillFlowContainer + { + Name = "Top-aligned metadata", + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + Direction = FillDirection.Vertical, + Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 20 }, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new OsuSpriteText + { + Font = @"Exo2.0-MediumItalic", + Text = beatmapInfo.Version, + TextSize = 24, + }, + } + }, + new FillFlowContainer + { + Name = "Bottom-aligned metadata", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Direction = FillDirection.Vertical, + Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 }, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new OsuSpriteText + { + Font = @"Exo2.0-MediumItalic", + Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title, + TextSize = 28, + }, + new OsuSpriteText + { + Font = @"Exo2.0-MediumItalic", + Text = metadata.Artist, + TextSize = 17, + }, + new FillFlowContainer + { + Margin = new MarginPadding { Top = 10 }, + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Children = new[] + { + new OsuSpriteText + { + Font = @"Exo2.0-Medium", + Text = "mapped by ", + TextSize = 15, + }, + new OsuSpriteText + { + Font = @"Exo2.0-Bold", + Text = metadata.Author, + TextSize = 15, + }, + } + }, + new FillFlowContainer + { + Margin = new MarginPadding { Top = 20, Left = 10 }, + Spacing = new Vector2(40, 0), + AutoSizeAxes = Axes.Both, + Children = labels + }, + } + }, + }; + } + + private string getBPMRange(Beatmap beatmap) + { + double bpmMax = beatmap.TimingInfo.BPMMaximum; + double bpmMin = beatmap.TimingInfo.BPMMinimum; + + if (Precision.AlmostEquals(bpmMin, bpmMax)) return Math.Round(bpmMin) + "bpm"; + + return Math.Round(bpmMin) + "-" + Math.Round(bpmMax) + "bpm (mostly " + Math.Round(beatmap.TimingInfo.BPMMode) + "bpm)"; + } + + public class InfoLabel : Container + { + public InfoLabel(BeatmapStatistic statistic) + { + AutoSizeAxes = Axes.Both; + Children = new Drawable[] + { new TextAwesome { Icon = FontAwesome.fa_square, @@ -273,23 +279,23 @@ namespace osu.Game.Screens.Select TextSize = 17, Origin = Anchor.CentreLeft }, - }; - } - } - - private class DifficultyColourBar : DifficultyColouredContainer - { - public DifficultyColourBar(BeatmapInfo beatmap) : base(beatmap) - { + }; + } } - [BackgroundDependencyLoader] - private void load() + private class DifficultyColourBar : DifficultyColouredContainer { - const float full_opacity_ratio = 0.7f; - - Children = new Drawable[] + public DifficultyColourBar(BeatmapInfo beatmap) : base(beatmap) { + } + + [BackgroundDependencyLoader] + private void load() + { + const float full_opacity_ratio = 0.7f; + + Children = new Drawable[] + { new Box { RelativeSizeAxes = Axes.Both, @@ -305,7 +311,8 @@ namespace osu.Game.Screens.Select X = full_opacity_ratio, Width = 1 - full_opacity_ratio, } - }; + }; + } } } } From 4e65da0fd116a05f1ba6cd6a01bc8d7bd5eeb3f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 22:17:35 +0900 Subject: [PATCH 07/11] Fix regression in panel select animation. Currently we are required to update computeYPositions twice per selection. Without doing this, panels are in the wrong place when using keyboard selection. There's still a bit of work to be done to make this work correctly. It's caused by a race condition of state application for panels which have not yet been presented (and get their state applied in LoadComplete which breaks the order of things). --- osu.Game/Screens/Select/BeatmapCarousel.cs | 32 +++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index c2c5aca0de..3710880dfe 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -328,25 +328,31 @@ namespace osu.Game.Screens.Select private void selectGroup(BeatmapGroup group, BeatmapPanel panel = null, bool animated = true) { - if (panel == null) - panel = group.BeatmapPanels.First(); + try + { + if (panel == null) + panel = group.BeatmapPanels.First(); - if (selectedPanel == panel) return; + if (selectedPanel == panel) return; - Trace.Assert(group.BeatmapPanels.Contains(panel), @"Selected panel must be in provided group"); + Trace.Assert(group.BeatmapPanels.Contains(panel), @"Selected panel must be in provided group"); - if (selectedGroup != null && selectedGroup != group && selectedGroup.State != BeatmapGroupState.Hidden) - selectedGroup.State = BeatmapGroupState.Collapsed; + if (selectedGroup != null && selectedGroup != group && selectedGroup.State != BeatmapGroupState.Hidden) + selectedGroup.State = BeatmapGroupState.Collapsed; - group.State = BeatmapGroupState.Expanded; - selectedGroup = group; - panel.State = PanelSelectedState.Selected; - selectedPanel = panel; + group.State = BeatmapGroupState.Expanded; + panel.State = PanelSelectedState.Selected; - float selectedY = computeYPositions(animated); - ScrollTo(selectedY, animated); + selectedPanel = panel; + selectedGroup = group; - SelectionChanged?.Invoke(panel.Beatmap); + SelectionChanged?.Invoke(panel.Beatmap); + } + finally + { + float selectedY = computeYPositions(animated); + ScrollTo(selectedY, animated); + } } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) From a681e3e380695ecd44a3f2bfbf42433e06893f46 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 22:17:42 +0900 Subject: [PATCH 08/11] Remove unused method. --- osu.Game/Screens/Select/SongSelect.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a6bb65af51..d82539967e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -343,11 +343,6 @@ namespace osu.Game.Screens.Select } } - private void selectBeatmap(BeatmapSetInfo beatmapSet = null) - { - carousel.SelectBeatmap(beatmapSet != null ? beatmapSet.Beatmaps.First() : Beatmap?.BeatmapInfo); - } - private void removeBeatmapSet(BeatmapSetInfo beatmapSet) { carousel.RemoveBeatmap(beatmapSet); From 2ece1cbd07a326777246c401c7230fa1aab9c373 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2017 22:23:10 +0900 Subject: [PATCH 09/11] CI Fixes. --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 ++-- osu.Game/Screens/Select/SongSelect.cs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 6397b5812b..44f2aeb0da 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -101,7 +101,7 @@ namespace osu.Game.Screens.Select public BufferedWedgeInfo(WorkingBeatmap beatmap) { BeatmapInfo beatmapInfo = beatmap.BeatmapInfo; - BeatmapMetadata metadata = beatmap.BeatmapInfo?.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); + BeatmapMetadata metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); List labels = new List(); @@ -125,7 +125,7 @@ namespace osu.Game.Screens.Select })); //get statistics fromt he current ruleset. - labels.AddRange(beatmap.BeatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s))); + labels.AddRange(beatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(beatmap).Select(s => new InfoLabel(s))); } PixelSnapping = true; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index d82539967e..08a58ab42c 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; using System.Threading; using OpenTK; using OpenTK.Input; From 2dcb4e9b936492ef04d825f7feb77644fe71cc9e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2017 20:12:09 +0900 Subject: [PATCH 10/11] Fix race condition when attempting to start a beatmap during debounce. --- osu.Game/Screens/Select/SongSelect.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 08a58ab42c..c8b46d5888 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -196,6 +196,11 @@ namespace osu.Game.Screens.Select private void raiseSelect() { + var pendingSelection = selectionChangedDebounce; + selectionChangedDebounce = null; + + pendingSelection?.RunTask(); + if (Beatmap == null) return; OnSelected(); From 1e3847c73c04c352c48ea68c3545c7b440fd4b2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2017 20:28:56 +0900 Subject: [PATCH 11/11] Cancel the existing scheduled task when running it ahead of time. --- osu.Game/Screens/Select/SongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index c8b46d5888..7d0648ac11 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -200,6 +200,7 @@ namespace osu.Game.Screens.Select selectionChangedDebounce = null; pendingSelection?.RunTask(); + pendingSelection?.Cancel(); // cancel the already scheduled task. if (Beatmap == null) return;