1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 05:42:56 +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); 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 readonly HashSet<Guid> setsRequiringRemoval = new HashSet<Guid>();
private void beatmapSetsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet? changes) private void beatmapSetsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet? changes)
@ -280,6 +280,7 @@ namespace osu.Game.Screens.Select
{ {
realmBeatmapSets.Clear(); realmBeatmapSets.Clear();
realmBeatmapSets.AddRange(sender.Select(r => r.ID)); realmBeatmapSets.AddRange(sender.Select(r => r.ID));
setsRequiringRemoval.Clear(); setsRequiringRemoval.Clear();
setsRequiringUpdate.Clear(); setsRequiringUpdate.Clear();
@ -289,18 +290,24 @@ namespace osu.Game.Screens.Select
{ {
foreach (int i in changes.DeletedIndices.OrderDescending()) foreach (int i in changes.DeletedIndices.OrderDescending())
{ {
setsRequiringRemoval.Add(realmBeatmapSets[i]); Guid id = realmBeatmapSets[i];
setsRequiringRemoval.Add(id);
setsRequiringUpdate.Remove(id);
realmBeatmapSets.RemoveAt(i); realmBeatmapSets.RemoveAt(i);
} }
foreach (int i in changes.InsertedIndices) foreach (int i in changes.InsertedIndices)
{ {
realmBeatmapSets.Insert(i, sender[i].ID); Guid id = sender[i].ID;
setsRequiringUpdate.Add(sender[i].Detach());
realmBeatmapSets.Insert(i, id);
setsRequiringUpdate.Add(id);
} }
foreach (int i in changes.NewModifiedIndices) foreach (int i in changes.NewModifiedIndices)
setsRequiringUpdate.Add(sender[i].Detach()); setsRequiringUpdate.Add(sender[i].ID);
} }
Scheduler.AddOnce(processBeatmapChanges); Scheduler.AddOnce(processBeatmapChanges);
@ -316,7 +323,7 @@ namespace osu.Game.Screens.Select
{ {
foreach (var set in setsRequiringRemoval) removeBeatmapSet(set); 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) 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. // 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. // 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. // 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()) 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. // 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 set in setsRequiringUpdate)
{ {
foreach (var beatmapInfo in set.Beatmaps) foreach (var beatmapInfo in fetchFromID(set)!.Beatmaps)
{ {
if (!((IBeatmapMetadataInfo)beatmapInfo.Metadata).Equals(SelectedBeatmapInfo.Metadata)) continue; 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. // 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. // 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(); setsRequiringRemoval.Clear();
setsRequiringUpdate.Clear(); setsRequiringUpdate.Clear();
BeatmapSetInfo? fetchFromID(Guid id) => realm.Realm.Find<BeatmapSetInfo>(id);
} }
private void beatmapsChanged(IRealmCollection<BeatmapInfo> sender, ChangeSet? changes) private void beatmapsChanged(IRealmCollection<BeatmapInfo> sender, ChangeSet? changes)