1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:17:51 +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]
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
advanceSelection(direction: 1, diff: false);
@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{
loadBeatmaps();
advanceSelection(direction: 1, diff: false);
AddStep("select first", () => carousel.SelectBeatmap(carousel.BeatmapSets.First().Beatmaps.First()));
waitForSelection(1, 1);
advanceSelection(direction: 1, diff: true);
@ -707,9 +707,9 @@ namespace osu.Game.Tests.Visual.SongSelect
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)
{
@ -730,17 +730,21 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep("Wait for load", () => changed);
}
private void createCarousel(Container target = null)
private void createCarousel(Action<BeatmapCarousel> carouselAdjust = null, Container target = null)
{
AddStep("Create carousel", () =>
{
selectedSets.Clear();
eagerSelectedIDs.Clear();
(target ?? this).Child = carousel = new TestBeatmapCarousel
carousel = new TestBeatmapCarousel
{
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);
beatmapSets.Select(createCarouselSet).Where(g => g != null).ForEach(newRoot.AddChild);
newRoot.Filter(activeCriteria);
// preload drawables as the ctor overhead is quite high currently.
_ = newRoot.Drawables;
@ -108,6 +107,9 @@ namespace osu.Game.Screens.Select
itemsCache.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.
SchedulerAfterChildren.Add(() =>
{
@ -321,6 +323,9 @@ namespace osu.Game.Screens.Select
/// <returns>True if a selection could be made, else False.</returns>
public bool SelectNextRandom()
{
if (!AllowSelection)
return false;
var visibleSets = beatmapSets.Where(s => !s.Filtered.Value).ToList();
if (!visibleSets.Any())
return false;
@ -427,7 +432,19 @@ namespace osu.Game.Screens.Select
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()
{
@ -439,14 +456,6 @@ namespace osu.Game.Screens.Select
if (alwaysResetScrollPosition || !scroll.UserScrolling)
ScrollToSelected();
}
PendingFilter?.Cancel();
PendingFilter = null;
if (debounce)
PendingFilter = Scheduler.AddDelayed(perform, 250);
else
perform();
}
private float? scrollTarget;