1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:07:52 +08:00

Merge pull request #9539 from peppy/fix-carousel-filter-application

Fix correct filter criteria not being applied to beatmap carousel if beatmaps take too long to load
This commit is contained in:
Dan Balasescu 2020-07-13 21:25:43 +09:00 committed by GitHub
commit c13064efc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 17 deletions

View File

@ -80,9 +80,9 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test] [Test]
public void TestRecommendedSelection() public void TestRecommendedSelection()
{ {
loadBeatmaps(); loadBeatmaps(carouselAdjust: carousel => carousel.GetRecommendedBeatmap = beatmaps => beatmaps.LastOrDefault());
AddStep("set recommendation function", () => carousel.GetRecommendedBeatmap = beatmaps => beatmaps.LastOrDefault()); AddStep("select last", () => carousel.SelectBeatmap(carousel.BeatmapSets.Last().Beatmaps.Last()));
// check recommended was selected // check recommended was selected
advanceSelection(direction: 1, diff: false); advanceSelection(direction: 1, diff: false);
@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
loadBeatmaps(); loadBeatmaps();
advanceSelection(direction: 1, diff: false); AddStep("select first", () => carousel.SelectBeatmap(carousel.BeatmapSets.First().Beatmaps.First()));
waitForSelection(1, 1); waitForSelection(1, 1);
advanceSelection(direction: 1, diff: true); advanceSelection(direction: 1, diff: true);
@ -707,9 +707,9 @@ namespace osu.Game.Tests.Visual.SongSelect
checkVisibleItemCount(true, 15); checkVisibleItemCount(true, 15);
} }
private void loadBeatmaps(List<BeatmapSetInfo> beatmapSets = null, Func<FilterCriteria> initialCriteria = null) private void loadBeatmaps(List<BeatmapSetInfo> beatmapSets = null, Func<FilterCriteria> initialCriteria = null, Action<BeatmapCarousel> carouselAdjust = null)
{ {
createCarousel(); createCarousel(carouselAdjust);
if (beatmapSets == null) if (beatmapSets == null)
{ {
@ -730,17 +730,21 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep("Wait for load", () => changed); AddUntilStep("Wait for load", () => changed);
} }
private void createCarousel(Container target = null) private void createCarousel(Action<BeatmapCarousel> carouselAdjust = null, Container target = null)
{ {
AddStep("Create carousel", () => AddStep("Create carousel", () =>
{ {
selectedSets.Clear(); selectedSets.Clear();
eagerSelectedIDs.Clear(); eagerSelectedIDs.Clear();
(target ?? this).Child = carousel = new TestBeatmapCarousel carousel = new TestBeatmapCarousel
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}; };
carouselAdjust?.Invoke(carousel);
(target ?? this).Child = carousel;
}); });
} }

View File

@ -95,7 +95,6 @@ namespace osu.Game.Screens.Select
CarouselRoot newRoot = new CarouselRoot(this); CarouselRoot newRoot = new CarouselRoot(this);
beatmapSets.Select(createCarouselSet).Where(g => g != null).ForEach(newRoot.AddChild); beatmapSets.Select(createCarouselSet).Where(g => g != null).ForEach(newRoot.AddChild);
newRoot.Filter(activeCriteria);
// preload drawables as the ctor overhead is quite high currently. // preload drawables as the ctor overhead is quite high currently.
_ = newRoot.Drawables; _ = newRoot.Drawables;
@ -108,6 +107,9 @@ namespace osu.Game.Screens.Select
itemsCache.Invalidate(); itemsCache.Invalidate();
scrollPositionCache.Invalidate(); scrollPositionCache.Invalidate();
// apply any pending filter operation that may have been delayed (see applyActiveCriteria's scheduling behaviour when BeatmapSetsLoaded is false).
FlushPendingFilterOperations();
// Run on late scheduler want to ensure this runs after all pending UpdateBeatmapSet / RemoveBeatmapSet operations are run. // Run on late scheduler want to ensure this runs after all pending UpdateBeatmapSet / RemoveBeatmapSet operations are run.
SchedulerAfterChildren.Add(() => SchedulerAfterChildren.Add(() =>
{ {
@ -321,6 +323,9 @@ namespace osu.Game.Screens.Select
/// <returns>True if a selection could be made, else False.</returns> /// <returns>True if a selection could be made, else False.</returns>
public bool SelectNextRandom() public bool SelectNextRandom()
{ {
if (!AllowSelection)
return false;
var visibleSets = beatmapSets.Where(s => !s.Filtered.Value).ToList(); var visibleSets = beatmapSets.Where(s => !s.Filtered.Value).ToList();
if (!visibleSets.Any()) if (!visibleSets.Any())
return false; return false;
@ -427,7 +432,19 @@ namespace osu.Game.Screens.Select
private void applyActiveCriteria(bool debounce, bool alwaysResetScrollPosition = true) private void applyActiveCriteria(bool debounce, bool alwaysResetScrollPosition = true)
{ {
if (root.Children.Any() != true) return; PendingFilter?.Cancel();
PendingFilter = null;
if (debounce)
PendingFilter = Scheduler.AddDelayed(perform, 250);
else
{
// if initial load is not yet finished, this will be run inline in loadBeatmapSets to ensure correct order of operation.
if (!BeatmapSetsLoaded)
PendingFilter = Schedule(perform);
else
perform();
}
void perform() void perform()
{ {
@ -439,14 +456,6 @@ namespace osu.Game.Screens.Select
if (alwaysResetScrollPosition || !scroll.UserScrolling) if (alwaysResetScrollPosition || !scroll.UserScrolling)
ScrollToSelected(); ScrollToSelected();
} }
PendingFilter?.Cancel();
PendingFilter = null;
if (debounce)
PendingFilter = Scheduler.AddDelayed(perform, 250);
else
perform();
} }
private float? scrollTarget; private float? scrollTarget;