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

Merge pull request #11817 from peppy/fix-collection-dropdown-cross-thread-manipulation

Fix potential crash from cross-thread drawable manipulation in CollectionFilterDropdown
This commit is contained in:
Dan Balasescu 2021-02-19 10:06:42 +09:00 committed by GitHub
commit 6240d3964c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 12 deletions

View File

@ -29,6 +29,14 @@ namespace osu.Game.Collections
/// </summary>
protected virtual bool ShowManageCollectionsItem => true;
private readonly BindableWithCurrent<CollectionFilterMenuItem> current = new BindableWithCurrent<CollectionFilterMenuItem>();
public new Bindable<CollectionFilterMenuItem> Current
{
get => current.Current;
set => current.Current = value;
}
private readonly IBindableList<BeatmapCollection> collections = new BindableList<BeatmapCollection>();
private readonly IBindableList<BeatmapInfo> beatmaps = new BindableList<BeatmapInfo>();
private readonly BindableList<CollectionFilterMenuItem> filters = new BindableList<CollectionFilterMenuItem>();
@ -36,25 +44,28 @@ namespace osu.Game.Collections
[Resolved(CanBeNull = true)]
private ManageCollectionsDialog manageCollectionsDialog { get; set; }
[Resolved(CanBeNull = true)]
private CollectionManager collectionManager { get; set; }
public CollectionFilterDropdown()
{
ItemSource = filters;
}
[BackgroundDependencyLoader(permitNulls: true)]
private void load([CanBeNull] CollectionManager collectionManager)
{
if (collectionManager != null)
collections.BindTo(collectionManager.Collections);
collections.CollectionChanged += (_, __) => collectionsChanged();
collectionsChanged();
Current.Value = new AllBeatmapsCollectionFilterMenuItem();
}
protected override void LoadComplete()
{
base.LoadComplete();
if (collectionManager != null)
collections.BindTo(collectionManager.Collections);
// Dropdown has logic which triggers a change on the bindable with every change to the contained items.
// This is not desirable here, as it leads to multiple filter operations running even though nothing has changed.
// An extra bindable is enough to subvert this behaviour.
base.Current = Current;
collections.BindCollectionChanged((_, __) => collectionsChanged(), true);
Current.BindValueChanged(filterChanged, true);
}

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using JetBrains.Annotations;
using osu.Framework.Bindables;
@ -9,7 +10,7 @@ namespace osu.Game.Collections
/// <summary>
/// A <see cref="BeatmapCollection"/> filter.
/// </summary>
public class CollectionFilterMenuItem
public class CollectionFilterMenuItem : IEquatable<CollectionFilterMenuItem>
{
/// <summary>
/// The collection to filter beatmaps from.
@ -33,6 +34,11 @@ namespace osu.Game.Collections
Collection = collection;
CollectionName = Collection?.Name.GetBoundCopy() ?? new Bindable<string>("All beatmaps");
}
public bool Equals(CollectionFilterMenuItem other)
=> other != null && CollectionName.Value == other.CollectionName.Value;
public override int GetHashCode() => CollectionName.Value.GetHashCode();
}
public class AllBeatmapsCollectionFilterMenuItem : CollectionFilterMenuItem

View File

@ -44,7 +44,7 @@ namespace osu.Game.Screens.Select
Sort = sortMode.Value,
AllowConvertedBeatmaps = showConverted.Value,
Ruleset = ruleset.Value,
Collection = collectionDropdown?.Current.Value.Collection
Collection = collectionDropdown?.Current.Value?.Collection
};
if (!minimumStars.IsDefault)