Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix several breakages with migration operation #30151

Merged
merged 5 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion osu.Game/Database/DetachedBeatmapStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private void beatmapSetsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeS
{
if (changes == null)
{
if (detachedBeatmapSets.Count > 0 && sender.Count == 0)
if (sender is RealmResetEmptySet<BeatmapSetInfo>)
{
// Usually we'd reset stuff here, but doing so triggers a silly flow which ends up deadlocking realm.
// Additionally, user should not be at song select when realm is blocking all operations in the first place.
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Database/RealmAccess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ public IDisposable RegisterForNotifications<T>(Func<Realm, IQueryable<T>> query,
lock (notificationsResetMap)
{
// Store an action which is used when blocking to ensure consumers don't use results of a stale changeset firing.
notificationsResetMap.Add(action, () => callback(new EmptyRealmSet<T>(), null));
notificationsResetMap.Add(action, () => callback(new RealmResetEmptySet<T>(), null));
}

return RegisterCustomSubscription(action);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@

namespace osu.Game.Database
{
public class EmptyRealmSet<T> : IRealmCollection<T>
/// <summary>
/// This can arrive in <see cref="RealmAccess.RegisterForNotifications{T}"/> callbacks to imply that realm access has been reset.
/// </summary>
/// <remarks>
/// Usually implies that the original database may return soon and the callback can usually be silently ignored.
///</remarks>
public class RealmResetEmptySet<T> : IRealmCollection<T>
{
private IList<T> emptySet => Array.Empty<T>();

Expand Down
1 change: 0 additions & 1 deletion osu.Game/OsuGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1137,7 +1137,6 @@ protected override void LoadComplete()
loadComponentSingleFile(new MedalOverlay(), topMostOverlayContent.Add);

loadComponentSingleFile(new BackgroundDataStoreProcessor(), Add);
loadComponentSingleFile(new DetachedBeatmapStore(), Add, true);

Add(difficultyRecommender);
Add(externalLinkOpener = new ExternalLinkOpener());
Expand Down
9 changes: 8 additions & 1 deletion osu.Game/OsuGameBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,10 @@ private void load(ReadableKeyCombinationProvider keyCombinationProvider, Framewo
dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore));
base.Content.Add(previewTrackManager);

var detachedBeatmapStore = new DetachedBeatmapStore();
base.Content.Add(detachedBeatmapStore);
dependencies.CacheAs(detachedBeatmapStore);

base.Content.Add(MusicController = new MusicController());
dependencies.CacheAs(MusicController);

Expand Down Expand Up @@ -541,7 +545,10 @@ public bool Migrate(string path)
realmBlocker = realm.BlockAllOperations("migration");
success = true;
}
catch { }
catch (Exception ex)
{
Logger.Log($"Attempting to block all operations failed: {ex}", LoggingTarget.Database);
}

readyToRun.Set();
}, false);
Expand Down
24 changes: 13 additions & 11 deletions osu.Game/Overlays/MusicController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
Expand Down Expand Up @@ -62,8 +63,7 @@ public partial class MusicController : CompositeDrawable

public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000));

[Resolved]
private RealmAccess realm { get; set; } = null!;
private IBindableList<BeatmapSetInfo> detachedBeatmaps = null!;

private BindableNumber<double> sampleVolume = null!;

Expand All @@ -76,13 +76,15 @@ public partial class MusicController : CompositeDrawable
private int randomHistoryDirection;

[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuConfigManager configManager)
private void load(AudioManager audio, OsuConfigManager configManager, DetachedBeatmapStore detachedBeatmapStore, CancellationToken? cancellationToken)
{
AddInternal(audioDuckFilter = new AudioFilter(audio.TrackMixer));
audio.Tracks.AddAdjustment(AdjustableProperty.Volume, audioDuckVolume);
sampleVolume = audio.VolumeSample.GetBoundCopy();

configManager.BindWith(OsuSetting.RandomSelectAlgorithm, randomSelectAlgorithm);

detachedBeatmaps = detachedBeatmapStore.GetDetachedBeatmaps(cancellationToken);
}

protected override void LoadComplete()
Expand Down Expand Up @@ -255,8 +257,8 @@ private PreviousTrackResult prev(bool allowProtectedTracks)
playableSet = getNextRandom(-1, allowProtectedTracks);
else
{
playableSet = getBeatmapSets().AsEnumerable().TakeWhile(i => !i.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Protected || allowProtectedTracks)
?? getBeatmapSets().AsEnumerable().LastOrDefault(s => !s.Protected || allowProtectedTracks);
playableSet = getBeatmapSets().TakeWhile(i => !i.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Protected || allowProtectedTracks)
?? getBeatmapSets().LastOrDefault(s => !s.Protected || allowProtectedTracks);
}

if (playableSet != null)
Expand Down Expand Up @@ -351,10 +353,10 @@ private bool next(bool allowProtectedTracks)
playableSet = getNextRandom(1, allowProtectedTracks);
else
{
playableSet = getBeatmapSets().AsEnumerable().SkipWhile(i => !i.Equals(current?.BeatmapSetInfo))
playableSet = getBeatmapSets().SkipWhile(i => !i.Equals(current?.BeatmapSetInfo))
.Where(i => !i.Protected || allowProtectedTracks)
.ElementAtOrDefault(1)
?? getBeatmapSets().AsEnumerable().FirstOrDefault(i => !i.Protected || allowProtectedTracks);
?? getBeatmapSets().FirstOrDefault(i => !i.Protected || allowProtectedTracks);
}

var playableBeatmap = playableSet?.Beatmaps.FirstOrDefault();
Expand All @@ -373,7 +375,7 @@ private bool next(bool allowProtectedTracks)
{
BeatmapSetInfo result;

var possibleSets = getBeatmapSets().AsEnumerable().Where(s => !s.Protected || allowProtectedTracks).ToArray();
var possibleSets = getBeatmapSets().Where(s => !s.Protected || allowProtectedTracks).ToArray();

if (possibleSets.Length == 0)
return null;
Expand Down Expand Up @@ -432,7 +434,7 @@ private void restartTrack()

private TrackChangeDirection? queuedDirection;

private IQueryable<BeatmapSetInfo> getBeatmapSets() => realm.Realm.All<BeatmapSetInfo>().Where(s => !s.DeletePending);
private IEnumerable<BeatmapSetInfo> getBeatmapSets() => detachedBeatmaps.Where(s => !s.DeletePending);

private void changeBeatmap(WorkingBeatmap newWorking)
{
Expand All @@ -459,8 +461,8 @@ private void changeBeatmap(WorkingBeatmap newWorking)
else
{
// figure out the best direction based on order in playlist.
int last = getBeatmapSets().AsEnumerable().TakeWhile(b => !b.Equals(current.BeatmapSetInfo)).Count();
int next = getBeatmapSets().AsEnumerable().TakeWhile(b => !b.Equals(newWorking.BeatmapSetInfo)).Count();
int last = getBeatmapSets().TakeWhile(b => !b.Equals(current.BeatmapSetInfo)).Count();
int next = getBeatmapSets().TakeWhile(b => !b.Equals(newWorking.BeatmapSetInfo)).Count();

direction = last > next ? TrackChangeDirection.Prev : TrackChangeDirection.Next;
}
Expand Down
Loading