From fb2f1224b315a77adce9b2270f33a636601965e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Jul 2017 05:58:58 +0900 Subject: [PATCH] Fix carousel filter debounce causing a race condition Clicking a ruleset button on toolbar would schedule a delayed filter of carousel, which could in turn trigger a beatmap change after pushing a Player. This resolves that by forcing any pending operations to complete. --- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 ++++ osu.Game/Screens/Select/SongSelect.cs | 13 ++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 0dc5d8074d..96069d8d18 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -232,6 +232,8 @@ namespace osu.Game.Screens.Select public bool AllowSelection = true; + public bool PendingFilter => filterTask?.Completed == false; + public void Filter(FilterCriteria newCriteria = null, bool debounce = true) { if (newCriteria != null) @@ -263,6 +265,8 @@ namespace osu.Game.Screens.Select }; filterTask?.Cancel(); + filterTask = null; + if (debounce) filterTask = Scheduler.AddDelayed(perform, 250); else diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9e1d230124..59bbb3b3e9 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -198,13 +198,16 @@ namespace osu.Game.Screens.Select private void carouselRaisedStart() { - var pendingSelection = selectionChangedDebounce; - selectionChangedDebounce = null; + if (carousel.PendingFilter) + // if we have a pending filter operation, we want to run it now. + // it could change selection (ie. if the ruleset has been changed). + carousel.Filter(null, false); - if (pendingSelection?.Completed == false) + if (selectionChangedDebounce?.Completed == false) { - pendingSelection.RunTask(); - pendingSelection.Cancel(); // cancel the already scheduled task. + selectionChangedDebounce.RunTask(); + selectionChangedDebounce.Cancel(); // cancel the already scheduled task. + selectionChangedDebounce = null; } OnSelected();