1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-09 04:13:39 +08:00

Move realm refetches of beatmap in song select wedges off of update thread

From local testing on release build (such that online beatmaps are
accessible) with a large database it seems that maybe this'll help with
recurrent complaints of 'stutters'.

Co-authored-by: Dean Herbert <pe@ppy.sh>
This commit is contained in:
Bartłomiej Dach
2025-10-10 08:48:18 +02:00
Unverified
parent 1f2928bf2f
commit 85bbe13aa9
2 changed files with 65 additions and 27 deletions
@@ -3,6 +3,8 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@@ -402,24 +404,40 @@ namespace osu.Game.Screens.SelectV2
updateSubWedgeVisibility();
}
private CancellationTokenSource? userTagsCancellationSource;
private void updateUserTags()
{
string[] tags = realm.Run(r =>
{
// need to refetch because `beatmap.Value.BeatmapInfo` is not going to have the latest tags
r.Refresh();
var refetchedBeatmap = r.Find<BeatmapInfo>(beatmap.Value.BeatmapInfo.ID);
return refetchedBeatmap?.Metadata.UserTags.ToArray() ?? [];
});
userTagsCancellationSource?.Cancel();
userTagsCancellationSource = new CancellationTokenSource();
if (tags.Length == 0)
{
userTags.FadeOut(transition_duration, Easing.OutQuint);
return;
}
var token = userTagsCancellationSource.Token;
userTags.FadeIn(transition_duration, Easing.OutQuint);
userTags.Tags = (tags, t => songSelect?.Search($@"tag=""{t}""!"));
Task.Run(() =>
{
string[] tags = realm.Run(r =>
{
// need to refetch because `beatmap.Value.BeatmapInfo` is not going to have the latest tags
r.Refresh();
var refetchedBeatmap = r.Find<BeatmapInfo>(beatmap.Value.BeatmapInfo.ID);
return refetchedBeatmap?.Metadata.UserTags.ToArray() ?? [];
});
Schedule(() =>
{
if (token.IsCancellationRequested)
return;
if (tags.Length == 0)
{
userTags.FadeOut(transition_duration, Easing.OutQuint);
return;
}
userTags.FadeIn(transition_duration, Easing.OutQuint);
userTags.Tags = (tags, t => songSelect?.Search($@"tag=""{t}""!"));
});
}, token);
}
}
}
+33 -13
View File
@@ -278,8 +278,13 @@ namespace osu.Game.Screens.SelectV2
}, token);
}
private CancellationTokenSource? onlineDisplayCancellationSource;
private void updateOnlineDisplay()
{
onlineDisplayCancellationSource?.Cancel();
onlineDisplayCancellationSource = null;
if (onlineLookupResult.Value?.Status != SongSelect.BeatmapSetLookupStatus.Completed)
{
playCount.Value = null;
@@ -291,20 +296,35 @@ namespace osu.Game.Screens.SelectV2
playCount.Value = new StatisticPlayCount.Data(onlineBeatmap?.PlayCount ?? -1, onlineBeatmap?.UserPlayCount ?? -1);
favouriteButton.SetBeatmapSet(onlineLookupResult.Value.Result);
// the online fetch may have also updated the beatmap's status.
// this needs to be checked against the *local* beatmap model rather than the online one, because it's not known here whether the status change has occurred or not
// (think scenarios like the beatmap being locally modified).
// it also has to be handled explicitly like this because the working beatmap's `BeatmapInfo` will not receive these updates due to being detached
// (and because of https://github.com/ppy/osu/blob/4b73afd1957a9161e2956fc4191c8114d9958372/osu.Game/Screens/SelectV2/SongSelect.cs#L487-L488
// which prevents working beatmap refetches caused by changes to the realm model of perceived low importance).
var status = realm.Run(r =>
onlineDisplayCancellationSource = new CancellationTokenSource();
var token = onlineDisplayCancellationSource.Token;
Task.Run(() =>
{
r.Refresh();
var refetchedBeatmap = r.Find<BeatmapInfo>(working.Value.BeatmapInfo.ID);
return refetchedBeatmap?.Status;
});
if (status != null)
statusPill.Status = status.Value;
// the online fetch may have also updated the beatmap's status.
// this needs to be checked against the *local* beatmap model rather than the online one, because it's not known here whether the status change has occurred or not
// (think scenarios like the beatmap being locally modified).
// it also has to be handled explicitly like this because the working beatmap's `BeatmapInfo` will not receive these updates due to being detached
// (and because of https://github.com/ppy/osu/blob/4b73afd1957a9161e2956fc4191c8114d9958372/osu.Game/Screens/SelectV2/SongSelect.cs#L487-L488
// which prevents working beatmap refetches caused by changes to the realm model of perceived low importance).
var status = realm.Run(r =>
{
r.Refresh();
var refetchedBeatmap = r.Find<BeatmapInfo>(working.Value.BeatmapInfo.ID);
return refetchedBeatmap?.Status;
});
if (status != null)
{
Schedule(() =>
{
if (token.IsCancellationRequested)
return;
statusPill.Status = status.Value;
});
}
}, token);
}
}
}