1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-23 19:07:20 +08:00

Add loading overlay and refine filter flow

This commit is contained in:
Dean Herbert 2025-01-14 20:23:53 +09:00
parent cc8941a94a
commit 900237c1ed
No known key found for this signature in database
2 changed files with 28 additions and 13 deletions

View File

@ -6,14 +6,16 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Pooling;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Multiplayer;
using osu.Game.Screens.Select;
using osuTK.Graphics;
namespace osu.Game.Screens.SelectV2
{
@ -24,6 +26,8 @@ namespace osu.Game.Screens.SelectV2
private readonly DrawablePool<BeatmapCarouselPanel> carouselPanelPool = new DrawablePool<BeatmapCarouselPanel>(100);
private readonly LoadingLayer loading;
public BeatmapCarousel()
{
DebounceDelay = 100;
@ -36,6 +40,8 @@ namespace osu.Game.Screens.SelectV2
};
AddInternal(carouselPanelPool);
AddInternal(loading = new LoadingLayer(dimBackground: true));
}
[BackgroundDependencyLoader]
@ -87,7 +93,14 @@ namespace osu.Game.Screens.SelectV2
public void Filter(FilterCriteria criteria)
{
Criteria = criteria;
QueueFilter();
FilterAsync().FireAndForget();
}
protected override async Task FilterAsync()
{
loading.Show();
await base.FilterAsync().ConfigureAwait(true);
loading.Hide();
}
}
}

View File

@ -27,7 +27,7 @@ namespace osu.Game.Screens.SelectV2
public abstract partial class Carousel<T> : CompositeDrawable
{
/// <summary>
/// A collection of filters which should be run each time a <see cref="QueueFilter"/> is executed.
/// A collection of filters which should be run each time a <see cref="FilterAsync"/> is executed.
/// </summary>
protected IEnumerable<ICarouselFilter> Filters { get; init; } = Enumerable.Empty<ICarouselFilter>();
@ -75,7 +75,7 @@ namespace osu.Game.Screens.SelectV2
/// <summary>
/// All items which are to be considered for display in this carousel.
/// Mutating this list will automatically queue a <see cref="QueueFilter"/>.
/// Mutating this list will automatically queue a <see cref="FilterAsync"/>.
/// </summary>
/// <remarks>
/// Note that an <see cref="ICarouselFilter"/> may add new items which are displayed but not tracked in this list.
@ -125,13 +125,13 @@ namespace osu.Game.Screens.SelectV2
}
};
Items.BindCollectionChanged((_, _) => QueueFilter());
Items.BindCollectionChanged((_, _) => FilterAsync());
}
/// <summary>
/// Queue an asynchronous filter operation.
/// </summary>
public void QueueFilter() => Scheduler.AddOnce(() => filterTask = performFilter());
protected virtual Task FilterAsync() => filterTask = performFilter();
/// <summary>
/// Create a drawable for the given carousel item so it can be displayed.
@ -159,6 +159,7 @@ namespace osu.Game.Screens.SelectV2
{
Debug.Assert(SynchronizationContext.Current != null);
Stopwatch stopwatch = Stopwatch.StartNew();
var cts = new CancellationTokenSource();
lock (this)
@ -167,19 +168,20 @@ namespace osu.Game.Screens.SelectV2
cancellationSource = cts;
}
Stopwatch stopwatch = Stopwatch.StartNew();
if (DebounceDelay > 0)
{
log($"Filter operation queued, waiting for {DebounceDelay} ms debounce");
await Task.Delay(DebounceDelay, cts.Token).ConfigureAwait(true);
}
// Copy must be performed on update thread for now (see ConfigureAwait above).
// Could potentially be optimised in the future if it becomes an issue.
IEnumerable<CarouselItem> items = new List<CarouselItem>(Items.Select(CreateCarouselItemForModel));
await Task.Run(async () =>
{
try
{
if (DebounceDelay > 0)
{
log($"Filter operation queued, waiting for {DebounceDelay} ms debounce");
await Task.Delay(DebounceDelay, cts.Token).ConfigureAwait(false);
}
foreach (var filter in Filters)
{
log($"Performing {filter.GetType().ReadableName()}");