1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-30 13:30:57 +08:00

Merge pull request #33332 from peppy/song-select-v2-fix-double-filter

SongSelectV2: Fix carousel filtering twice on entering song select
This commit is contained in:
Bartłomiej Dach
2025-05-30 12:29:32 +02:00
committed by GitHub
Unverified
5 changed files with 40 additions and 7 deletions
@@ -149,6 +149,8 @@ namespace osu.Game.Tests.Visual.SongSelectV2
TextAnchor = Anchor.CentreLeft,
},
};
Carousel.Filter(new FilterCriteria());
});
// Prefer title sorting so that order of carousel panels match order of BeatmapSets bindable.
@@ -171,7 +173,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
{
AddStep(description, () =>
{
var criteria = Carousel.Criteria;
var criteria = Carousel.Criteria ?? new FilterCriteria();
apply?.Invoke(criteria);
Carousel.Filter(criteria);
});
@@ -362,7 +364,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
""");
createHeader("carousel");
stats.AddParagraph($"""
sorting: {Carousel.IsFiltering}
filtering: {Carousel.IsFiltering} (total {Carousel.FilterCount} times)
tracked: {Carousel.ItemsTracked}
displayable: {Carousel.DisplayableItems}
displayed: {Carousel.VisibleItems}
@@ -78,6 +78,15 @@ namespace osu.Game.Tests.Visual.SongSelectV2
AddUntilStep("wait for results screen", () => Stack.CurrentScreen is ResultsScreen);
}
[Test]
public void TestSingleFilterWhenEntering()
{
ImportBeatmapForRuleset(0);
LoadSongSelect();
AddAssert("single filter", () => Carousel.FilterCount, () => Is.EqualTo(1));
}
[Test]
public void TestCookieDoesNothingIfNothingSelected()
{
+7
View File
@@ -71,6 +71,11 @@ namespace osu.Game.Graphics.Carousel
/// </summary>
public bool IsFiltering => !filterTask.IsCompleted;
/// <summary>
/// The number of times filter operations have been triggered.
/// </summary>
internal int FilterCount { get; private set; }
/// <summary>
/// The number of displayable items currently being tracked (before filtering).
/// </summary>
@@ -187,6 +192,8 @@ namespace osu.Game.Graphics.Carousel
/// <param name="clearExistingPanels">Whether all existing drawable panels should be reset post filter.</param>
protected virtual Task<IEnumerable<CarouselItem>> FilterAsync(bool clearExistingPanels = false)
{
FilterCount++;
if (clearExistingPanels)
filterReusesPanels.Invalidate();
+13 -4
View File
@@ -7,6 +7,7 @@ using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -90,9 +91,9 @@ namespace osu.Game.Screens.SelectV2
Filters = new ICarouselFilter[]
{
matching = new BeatmapCarouselFilterMatching(() => Criteria),
new BeatmapCarouselFilterSorting(() => Criteria),
grouping = new BeatmapCarouselFilterGrouping(() => Criteria),
matching = new BeatmapCarouselFilterMatching(() => Criteria!),
new BeatmapCarouselFilterSorting(() => Criteria!),
grouping = new BeatmapCarouselFilterGrouping(() => Criteria!),
};
AddInternal(loading = new LoadingLayer());
@@ -483,7 +484,7 @@ namespace osu.Game.Screens.SelectV2
#region Filtering
public FilterCriteria Criteria { get; private set; } = new FilterCriteria();
public FilterCriteria? Criteria { get; private set; }
private ScheduledDelegate? loadingDebounce;
@@ -509,6 +510,14 @@ namespace osu.Game.Screens.SelectV2
}));
}
protected override Task<IEnumerable<CarouselItem>> FilterAsync(bool clearExistingPanels = false)
{
if (Criteria == null)
return Task.FromResult(Enumerable.Empty<CarouselItem>());
return base.FilterAsync(clearExistingPanels);
}
#endregion
#region Drawable pooling
+7 -1
View File
@@ -562,12 +562,18 @@ namespace osu.Game.Screens.SelectV2
private void criteriaChanged(FilterCriteria criteria)
{
// The first filter needs to be applied immediately as this triggers the initial carousel load.
double filterDelay = filterDebounce == null ? 0 : filter_delay;
filterDebounce?.Cancel();
filterDebounce = Scheduler.AddDelayed(() => { carousel.Filter(criteria); }, filter_delay);
filterDebounce = Scheduler.AddDelayed(() => { carousel.Filter(criteria); }, filterDelay);
}
private void newItemsPresented(IEnumerable<CarouselItem> carouselItems)
{
if (carousel.Criteria == null)
return;
int count = carousel.MatchedBeatmapsCount;
if (count == 0)