1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 02:42:54 +08:00

Fix deleted beatmap sets potentially reappearing due to pending update requests

This commit is contained in:
Dean Herbert 2024-07-09 17:04:51 +09:00
parent 63b4327978
commit 920c0e4d25
No known key found for this signature in database

View File

@ -267,7 +267,7 @@ namespace osu.Game.Screens.Select
subscriptionBeatmaps = realm.RegisterForNotifications(r => r.All<BeatmapInfo>().Where(b => !b.Hidden), beatmapsChanged);
}
private readonly HashSet<BeatmapSetInfo> setsRequiringUpdate = new HashSet<BeatmapSetInfo>();
private readonly HashSet<Guid> setsRequiringUpdate = new HashSet<Guid>();
private readonly HashSet<Guid> setsRequiringRemoval = new HashSet<Guid>();
private void beatmapSetsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet? changes)
@ -280,6 +280,7 @@ namespace osu.Game.Screens.Select
{
realmBeatmapSets.Clear();
realmBeatmapSets.AddRange(sender.Select(r => r.ID));
setsRequiringRemoval.Clear();
setsRequiringUpdate.Clear();
@ -289,18 +290,24 @@ namespace osu.Game.Screens.Select
{
foreach (int i in changes.DeletedIndices.OrderDescending())
{
setsRequiringRemoval.Add(realmBeatmapSets[i]);
Guid id = realmBeatmapSets[i];
setsRequiringRemoval.Add(id);
setsRequiringUpdate.Remove(id);
realmBeatmapSets.RemoveAt(i);
}
foreach (int i in changes.InsertedIndices)
{
realmBeatmapSets.Insert(i, sender[i].ID);
setsRequiringUpdate.Add(sender[i].Detach());
Guid id = sender[i].ID;
realmBeatmapSets.Insert(i, id);
setsRequiringUpdate.Add(id);
}
foreach (int i in changes.NewModifiedIndices)
setsRequiringUpdate.Add(sender[i].Detach());
setsRequiringUpdate.Add(sender[i].ID);
}
Scheduler.AddOnce(processBeatmapChanges);
@ -316,7 +323,7 @@ namespace osu.Game.Screens.Select
{
foreach (var set in setsRequiringRemoval) removeBeatmapSet(set);
foreach (var set in setsRequiringUpdate) updateBeatmapSet(set);
foreach (var set in setsRequiringUpdate) updateBeatmapSet(fetchFromID(set)!);
if (setsRequiringRemoval.Count > 0 && SelectedBeatmapInfo != null)
{
@ -326,7 +333,7 @@ namespace osu.Game.Screens.Select
// To handle the beatmap update flow, attempt to track selection changes across delete-insert transactions.
// When an update occurs, the previous beatmap set is either soft or hard deleted.
// Check if the current selection was potentially deleted by re-querying its validity.
bool selectedSetMarkedDeleted = realm.Run(r => r.Find<BeatmapSetInfo>(SelectedBeatmapSet.ID)?.DeletePending != false);
bool selectedSetMarkedDeleted = fetchFromID(SelectedBeatmapSet.ID)?.DeletePending != false;
if (selectedSetMarkedDeleted && setsRequiringUpdate.Any())
{
@ -334,7 +341,7 @@ namespace osu.Game.Screens.Select
// This relies on the full update operation being in a single transaction, so please don't change that.
foreach (var set in setsRequiringUpdate)
{
foreach (var beatmapInfo in set.Beatmaps)
foreach (var beatmapInfo in fetchFromID(set)!.Beatmaps)
{
if (!((IBeatmapMetadataInfo)beatmapInfo.Metadata).Equals(SelectedBeatmapInfo.Metadata)) continue;
@ -349,7 +356,7 @@ namespace osu.Game.Screens.Select
// If a direct selection couldn't be made, it's feasible that the difficulty name (or beatmap metadata) changed.
// Let's attempt to follow set-level selection anyway.
SelectBeatmap(setsRequiringUpdate.First().Beatmaps.First());
SelectBeatmap(fetchFromID(setsRequiringUpdate.First())!.Beatmaps.First());
}
}
}
@ -361,6 +368,8 @@ namespace osu.Game.Screens.Select
setsRequiringRemoval.Clear();
setsRequiringUpdate.Clear();
BeatmapSetInfo? fetchFromID(Guid id) => realm.Realm.Find<BeatmapSetInfo>(id);
}
private void beatmapsChanged(IRealmCollection<BeatmapInfo> sender, ChangeSet? changes)