1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 02:22:56 +08:00

Merge branch 'realm-clean-up' into realm-block-timeout-assert-failure

This commit is contained in:
Dean Herbert 2022-01-25 13:58:14 +09:00
commit 9ad4d66e4d
51 changed files with 212 additions and 230 deletions

View File

@ -29,7 +29,7 @@ namespace osu.Game.Benchmarks
realm = new RealmAccess(storage, "client"); realm = new RealmAccess(storage, "client");
realm.Run(realm => realm.Run(r =>
{ {
realm.Write(c => c.Add(TestResources.CreateTestBeatmapSetInfo(rulesets: new[] { new OsuRuleset().RulesetInfo }))); realm.Write(c => c.Add(TestResources.CreateTestBeatmapSetInfo(rulesets: new[] { new OsuRuleset().RulesetInfo })));
}); });
@ -41,9 +41,9 @@ namespace osu.Game.Benchmarks
[Benchmark] [Benchmark]
public void BenchmarkDirectPropertyRead() public void BenchmarkDirectPropertyRead()
{ {
realm.Run(realm => realm.Run(r =>
{ {
var beatmapSet = realm.All<BeatmapSetInfo>().First(); var beatmapSet = r.All<BeatmapSetInfo>().First();
for (int i = 0; i < ReadsPerFetch; i++) for (int i = 0; i < ReadsPerFetch; i++)
{ {
@ -119,9 +119,9 @@ namespace osu.Game.Benchmarks
[Benchmark] [Benchmark]
public void BenchmarkDetachedPropertyRead() public void BenchmarkDetachedPropertyRead()
{ {
realm.Run(realm => realm.Run(r =>
{ {
var beatmapSet = realm.All<BeatmapSetInfo>().First().Detach(); var beatmapSet = r.All<BeatmapSetInfo>().First().Detach();
for (int i = 0; i < ReadsPerFetch; i++) for (int i = 0; i < ReadsPerFetch; i++)
{ {

View File

@ -60,11 +60,11 @@ namespace osu.Game.Tests.Database
KeyBindingContainer testContainer = new TestKeyBindingContainer(); KeyBindingContainer testContainer = new TestKeyBindingContainer();
// Add some excess bindings for an action which only supports 1. // Add some excess bindings for an action which only supports 1.
realm.Write(realm => realm.Write(r =>
{ {
realm.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.A))); r.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.A)));
realm.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.S))); r.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.S)));
realm.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.D))); r.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.D)));
}); });
Assert.That(queryCount(GlobalAction.Back), Is.EqualTo(3)); Assert.That(queryCount(GlobalAction.Back), Is.EqualTo(3));
@ -76,9 +76,9 @@ namespace osu.Game.Tests.Database
private int queryCount(GlobalAction? match = null) private int queryCount(GlobalAction? match = null)
{ {
return realm.Run(realm => return realm.Run(r =>
{ {
var results = realm.All<RealmKeyBinding>(); var results = r.All<RealmKeyBinding>();
if (match.HasValue) if (match.HasValue)
results = results.Where(k => k.ActionInt == (int)match.Value); results = results.Where(k => k.ActionInt == (int)match.Value);
return results.Count(); return results.Count();

View File

@ -45,8 +45,8 @@ namespace osu.Game.Tests.Online
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audio, GameHost host) private void load(AudioManager audio, GameHost host)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.CacheAs<BeatmapManager>(beatmaps = new TestBeatmapManager(LocalStorage, Access, rulesets, API, audio, Resources, host, Beatmap.Default)); Dependencies.CacheAs<BeatmapManager>(beatmaps = new TestBeatmapManager(LocalStorage, Realm, rulesets, API, audio, Resources, host, Beatmap.Default));
Dependencies.CacheAs<BeatmapModelDownloader>(beatmapDownloader = new TestBeatmapModelDownloader(beatmaps, API, host)); Dependencies.CacheAs<BeatmapModelDownloader>(beatmapDownloader = new TestBeatmapModelDownloader(beatmaps, API, host));
} }
@ -60,8 +60,8 @@ namespace osu.Game.Tests.Online
testBeatmapInfo = getTestBeatmapInfo(testBeatmapFile); testBeatmapInfo = getTestBeatmapInfo(testBeatmapFile);
testBeatmapSet = testBeatmapInfo.BeatmapSet; testBeatmapSet = testBeatmapInfo.BeatmapSet;
Access.Write(r => r.RemoveAll<BeatmapSetInfo>()); Realm.Write(r => r.RemoveAll<BeatmapSetInfo>());
Access.Write(r => r.RemoveAll<BeatmapInfo>()); Realm.Write(r => r.RemoveAll<BeatmapInfo>());
selectedItem.Value = new PlaylistItem selectedItem.Value = new PlaylistItem
{ {

View File

@ -47,10 +47,10 @@ namespace osu.Game.Tests.Visual.Background
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(new OsuConfigManager(LocalStorage)); Dependencies.Cache(new OsuConfigManager(LocalStorage));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
manager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); manager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();

View File

@ -36,9 +36,9 @@ namespace osu.Game.Tests.Visual.Collections
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host) private void load(GameHost host)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Access, rulesets, null, Audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesets, null, Audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();

View File

@ -47,9 +47,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
} }
public override void SetUpSteps() public override void SetUpSteps()

View File

@ -43,9 +43,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
} }
[Test] [Test]

View File

@ -61,9 +61,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Access, rulesets, API, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
} }
public override void SetUpSteps() public override void SetUpSteps()

View File

@ -42,9 +42,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
beatmaps = new List<BeatmapInfo>(); beatmaps = new List<BeatmapInfo>();

View File

@ -38,9 +38,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();

View File

@ -33,9 +33,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
} }
[SetUp] [SetUp]

View File

@ -38,9 +38,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Access, rulesets, API, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
} }
public override void SetUpSteps() public override void SetUpSteps()

View File

@ -40,9 +40,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
} }

View File

@ -41,9 +41,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
} }

View File

@ -34,9 +34,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
var beatmapSet = TestResources.CreateTestBeatmapSetInfo(); var beatmapSet = TestResources.CreateTestBeatmapSetInfo();

View File

@ -42,9 +42,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
} }
public override void SetUpSteps() public override void SetUpSteps()

View File

@ -40,9 +40,9 @@ namespace osu.Game.Tests.Visual.Playlists
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Access, rulesets, API, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, API, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
} }
[SetUpSteps] [SetUpSteps]

View File

@ -42,9 +42,9 @@ namespace osu.Game.Tests.Visual.Ranking
{ {
base.LoadComplete(); base.LoadComplete();
realm.Run(realm => realm.Run(r =>
{ {
var beatmapInfo = realm.All<BeatmapInfo>() var beatmapInfo = r.All<BeatmapInfo>()
.Filter($"{nameof(BeatmapInfo.Ruleset)}.{nameof(RulesetInfo.OnlineID)} = $0", 0) .Filter($"{nameof(BeatmapInfo.Ruleset)}.{nameof(RulesetInfo.OnlineID)} = $0", 0)
.FirstOrDefault(); .FirstOrDefault();

View File

@ -42,10 +42,10 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.Cache(rulesetStore = new RulesetStore(Access)); dependencies.Cache(rulesetStore = new RulesetStore(Realm));
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Access, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default)); dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, Access, Scheduler)); dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, Realm, Scheduler));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
return dependencies; return dependencies;
} }

View File

@ -36,9 +36,9 @@ namespace osu.Game.Tests.Visual.SongSelect
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host) private void load(GameHost host)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Access, rulesets, null, Audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesets, null, Audio, Resources, host, Beatmap.Default));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();

View File

@ -47,9 +47,9 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
// These DI caches are required to ensure for interactive runs this test scene doesn't nuke all user beatmaps in the local install. // These DI caches are required to ensure for interactive runs this test scene doesn't nuke all user beatmaps in the local install.
// At a point we have isolated interactive test runs enough, this can likely be removed. // At a point we have isolated interactive test runs enough, this can likely be removed.
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, defaultBeatmap = Beatmap.Default)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, defaultBeatmap = Beatmap.Default));
Dependencies.Cache(music = new MusicController()); Dependencies.Cache(music = new MusicController());

View File

@ -28,10 +28,10 @@ namespace osu.Game.Tests.Visual.SongSelect
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
Dependencies.Cache(rulesets = new RulesetStore(Access)); Dependencies.Cache(rulesets = new RulesetStore(Realm));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(scoreManager = new ScoreManager(rulesets, () => beatmapManager, LocalStorage, Access, Scheduler)); Dependencies.Cache(scoreManager = new ScoreManager(rulesets, () => beatmapManager, LocalStorage, Realm, Scheduler));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
} }

View File

@ -87,10 +87,10 @@ namespace osu.Game.Tests.Visual.UserInterface
{ {
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.Cache(rulesetStore = new RulesetStore(Access)); dependencies.Cache(rulesetStore = new RulesetStore(Realm));
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Access, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default)); dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(dependencies.Get<RulesetStore>(), () => beatmapManager, LocalStorage, Access, Scheduler)); dependencies.Cache(scoreManager = new ScoreManager(dependencies.Get<RulesetStore>(), () => beatmapManager, LocalStorage, Realm, Scheduler));
Dependencies.Cache(Access); Dependencies.Cache(Realm);
var imported = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).GetResultSafely(); var imported = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).GetResultSafely();
@ -122,10 +122,10 @@ namespace osu.Game.Tests.Visual.UserInterface
[SetUp] [SetUp]
public void Setup() => Schedule(() => public void Setup() => Schedule(() =>
{ {
realm.Run(realm => realm.Run(r =>
{ {
// Due to soft deletions, we can re-use deleted scores between test runs // Due to soft deletions, we can re-use deleted scores between test runs
scoreManager.Undelete(realm.All<ScoreInfo>().Where(s => s.DeletePending).ToList()); scoreManager.Undelete(r.All<ScoreInfo>().Where(s => s.DeletePending).ToList());
}); });
leaderboard.Scores = null; leaderboard.Scores = null;

View File

@ -119,12 +119,12 @@ namespace osu.Game.Beatmaps
/// <param name="beatmapInfo">The beatmap difficulty to hide.</param> /// <param name="beatmapInfo">The beatmap difficulty to hide.</param>
public void Hide(BeatmapInfo beatmapInfo) public void Hide(BeatmapInfo beatmapInfo)
{ {
realm.Run(realm => realm.Run(r =>
{ {
using (var transaction = realm.BeginWrite()) using (var transaction = r.BeginWrite())
{ {
if (!beatmapInfo.IsManaged) if (!beatmapInfo.IsManaged)
beatmapInfo = realm.Find<BeatmapInfo>(beatmapInfo.ID); beatmapInfo = r.Find<BeatmapInfo>(beatmapInfo.ID);
beatmapInfo.Hidden = true; beatmapInfo.Hidden = true;
transaction.Commit(); transaction.Commit();
@ -138,12 +138,12 @@ namespace osu.Game.Beatmaps
/// <param name="beatmapInfo">The beatmap difficulty to restore.</param> /// <param name="beatmapInfo">The beatmap difficulty to restore.</param>
public void Restore(BeatmapInfo beatmapInfo) public void Restore(BeatmapInfo beatmapInfo)
{ {
realm.Run(realm => realm.Run(r =>
{ {
using (var transaction = realm.BeginWrite()) using (var transaction = r.BeginWrite())
{ {
if (!beatmapInfo.IsManaged) if (!beatmapInfo.IsManaged)
beatmapInfo = realm.Find<BeatmapInfo>(beatmapInfo.ID); beatmapInfo = r.Find<BeatmapInfo>(beatmapInfo.ID);
beatmapInfo.Hidden = false; beatmapInfo.Hidden = false;
transaction.Commit(); transaction.Commit();
@ -153,11 +153,11 @@ namespace osu.Game.Beatmaps
public void RestoreAll() public void RestoreAll()
{ {
realm.Run(realm => realm.Run(r =>
{ {
using (var transaction = realm.BeginWrite()) using (var transaction = r.BeginWrite())
{ {
foreach (var beatmap in realm.All<BeatmapInfo>().Where(b => b.Hidden)) foreach (var beatmap in r.All<BeatmapInfo>().Where(b => b.Hidden))
beatmap.Hidden = false; beatmap.Hidden = false;
transaction.Commit(); transaction.Commit();
@ -171,10 +171,10 @@ namespace osu.Game.Beatmaps
/// <returns>A list of available <see cref="BeatmapSetInfo"/>.</returns> /// <returns>A list of available <see cref="BeatmapSetInfo"/>.</returns>
public List<BeatmapSetInfo> GetAllUsableBeatmapSets() public List<BeatmapSetInfo> GetAllUsableBeatmapSets()
{ {
return realm.Run(realm => return realm.Run(r =>
{ {
realm.Refresh(); r.Refresh();
return realm.All<BeatmapSetInfo>().Where(b => !b.DeletePending).Detach(); return r.All<BeatmapSetInfo>().Where(b => !b.DeletePending).Detach();
}); });
} }
@ -240,9 +240,9 @@ namespace osu.Game.Beatmaps
public void Delete(Expression<Func<BeatmapSetInfo, bool>>? filter = null, bool silent = false) public void Delete(Expression<Func<BeatmapSetInfo, bool>>? filter = null, bool silent = false)
{ {
realm.Run(realm => realm.Run(r =>
{ {
var items = realm.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected); var items = r.All<BeatmapSetInfo>().Where(s => !s.DeletePending && !s.Protected);
if (filter != null) if (filter != null)
items = items.Where(filter); items = items.Where(filter);
@ -253,7 +253,7 @@ namespace osu.Game.Beatmaps
public void UndeleteAll() public void UndeleteAll()
{ {
realm.Run(realm => beatmapModelManager.Undelete(realm.All<BeatmapSetInfo>().Where(s => s.DeletePending).ToList())); realm.Run(r => beatmapModelManager.Undelete(r.All<BeatmapSetInfo>().Where(s => s.DeletePending).ToList()));
} }
public void Undelete(List<BeatmapSetInfo> items, bool silent = false) public void Undelete(List<BeatmapSetInfo> items, bool silent = false)
@ -312,9 +312,9 @@ namespace osu.Game.Beatmaps
// If we seem to be missing files, now is a good time to re-fetch. // If we seem to be missing files, now is a good time to re-fetch.
if (importedBeatmap?.BeatmapSet?.Files.Count == 0) if (importedBeatmap?.BeatmapSet?.Files.Count == 0)
{ {
realm.Run(realm => realm.Run(r =>
{ {
var refetch = realm.Find<BeatmapInfo>(importedBeatmap.ID)?.Detach(); var refetch = r.Find<BeatmapInfo>(importedBeatmap.ID)?.Detach();
if (refetch != null) if (refetch != null)
importedBeatmap = refetch; importedBeatmap = refetch;

View File

@ -98,12 +98,12 @@ namespace osu.Game.Beatmaps
/// <returns>The first result for the provided query, or null if no results were found.</returns> /// <returns>The first result for the provided query, or null if no results were found.</returns>
public BeatmapInfo? QueryBeatmap(Expression<Func<BeatmapInfo, bool>> query) public BeatmapInfo? QueryBeatmap(Expression<Func<BeatmapInfo, bool>> query)
{ {
return Access.Run(realm => realm.All<BeatmapInfo>().FirstOrDefault(query)?.Detach()); return Realm.Run(realm => realm.All<BeatmapInfo>().FirstOrDefault(query)?.Detach());
} }
public void Update(BeatmapSetInfo item) public void Update(BeatmapSetInfo item)
{ {
Access.Write(realm => Realm.Write(realm =>
{ {
var existing = realm.Find<BeatmapSetInfo>(item.ID); var existing = realm.Find<BeatmapSetInfo>(item.ID);
item.CopyChangesToRealm(existing); item.CopyChangesToRealm(existing);

View File

@ -101,15 +101,15 @@ namespace osu.Game.Database
{ {
using (var ef = efContextFactory.Get()) using (var ef = efContextFactory.Get())
{ {
realm.Write(realm => realm.Write(r =>
{ {
// Before beginning, ensure realm is in an empty state. // Before beginning, ensure realm is in an empty state.
// Migrations which are half-completed could lead to issues if the user tries a second time. // Migrations which are half-completed could lead to issues if the user tries a second time.
// Note that we only do this for beatmaps and scores since the other migrations are yonks old. // Note that we only do this for beatmaps and scores since the other migrations are yonks old.
realm.RemoveAll<BeatmapSetInfo>(); r.RemoveAll<BeatmapSetInfo>();
realm.RemoveAll<BeatmapInfo>(); r.RemoveAll<BeatmapInfo>();
realm.RemoveAll<BeatmapMetadata>(); r.RemoveAll<BeatmapMetadata>();
realm.RemoveAll<ScoreInfo>(); r.RemoveAll<ScoreInfo>();
}); });
migrateSettings(ef); migrateSettings(ef);
@ -158,11 +158,11 @@ namespace osu.Game.Database
int count = existingBeatmapSets.Count(); int count = existingBeatmapSets.Count();
realm.Run(realm => realm.Run(r =>
{ {
log($"Found {count} beatmaps in EF"); log($"Found {count} beatmaps in EF");
var transaction = realm.BeginWrite(); var transaction = r.BeginWrite();
int written = 0; int written = 0;
try try
@ -172,7 +172,7 @@ namespace osu.Game.Database
if (++written % 1000 == 0) if (++written % 1000 == 0)
{ {
transaction.Commit(); transaction.Commit();
transaction = realm.BeginWrite(); transaction = r.BeginWrite();
log($"Migrated {written}/{count} beatmaps..."); log($"Migrated {written}/{count} beatmaps...");
} }
@ -186,11 +186,11 @@ namespace osu.Game.Database
Protected = beatmapSet.Protected, Protected = beatmapSet.Protected,
}; };
migrateFiles(beatmapSet, realm, realmBeatmapSet); migrateFiles(beatmapSet, r, realmBeatmapSet);
foreach (var beatmap in beatmapSet.Beatmaps) foreach (var beatmap in beatmapSet.Beatmaps)
{ {
var ruleset = realm.Find<RulesetInfo>(beatmap.RulesetInfo.ShortName); var ruleset = r.Find<RulesetInfo>(beatmap.RulesetInfo.ShortName);
var metadata = getBestMetadata(beatmap.Metadata, beatmapSet.Metadata); var metadata = getBestMetadata(beatmap.Metadata, beatmapSet.Metadata);
var realmBeatmap = new BeatmapInfo(ruleset, new BeatmapDifficulty(beatmap.BaseDifficulty), metadata) var realmBeatmap = new BeatmapInfo(ruleset, new BeatmapDifficulty(beatmap.BaseDifficulty), metadata)
@ -225,7 +225,7 @@ namespace osu.Game.Database
realmBeatmapSet.Beatmaps.Add(realmBeatmap); realmBeatmapSet.Beatmaps.Add(realmBeatmap);
} }
realm.Add(realmBeatmapSet); r.Add(realmBeatmapSet);
} }
} }
finally finally
@ -280,11 +280,11 @@ namespace osu.Game.Database
int count = existingScores.Count(); int count = existingScores.Count();
realm.Run(realm => realm.Run(r =>
{ {
log($"Found {count} scores in EF"); log($"Found {count} scores in EF");
var transaction = realm.BeginWrite(); var transaction = r.BeginWrite();
int written = 0; int written = 0;
try try
@ -294,12 +294,12 @@ namespace osu.Game.Database
if (++written % 1000 == 0) if (++written % 1000 == 0)
{ {
transaction.Commit(); transaction.Commit();
transaction = realm.BeginWrite(); transaction = r.BeginWrite();
log($"Migrated {written}/{count} scores..."); log($"Migrated {written}/{count} scores...");
} }
var beatmap = realm.All<BeatmapInfo>().First(b => b.Hash == score.BeatmapInfo.Hash); var beatmap = r.All<BeatmapInfo>().First(b => b.Hash == score.BeatmapInfo.Hash);
var ruleset = realm.Find<RulesetInfo>(score.Ruleset.ShortName); var ruleset = r.Find<RulesetInfo>(score.Ruleset.ShortName);
var user = new RealmUser var user = new RealmUser
{ {
OnlineID = score.User.OnlineID, OnlineID = score.User.OnlineID,
@ -329,9 +329,9 @@ namespace osu.Game.Database
APIMods = score.APIMods, APIMods = score.APIMods,
}; };
migrateFiles(score, realm, realmScore); migrateFiles(score, r, realmScore);
realm.Add(realmScore); r.Add(realmScore);
} }
} }
finally finally
@ -369,13 +369,13 @@ namespace osu.Game.Database
break; break;
} }
realm.Run(realm => realm.Run(r =>
{ {
using (var transaction = realm.BeginWrite()) using (var transaction = r.BeginWrite())
{ {
// only migrate data if the realm database is empty. // only migrate data if the realm database is empty.
// note that this cannot be written as: `realm.All<SkinInfo>().All(s => s.Protected)`, because realm does not support `.All()`. // note that this cannot be written as: `r.All<SkinInfo>().All(s => s.Protected)`, because realm does not support `.All()`.
if (!realm.All<SkinInfo>().Any(s => !s.Protected)) if (!r.All<SkinInfo>().Any(s => !s.Protected))
{ {
log($"Migrating {existingSkins.Count} skins"); log($"Migrating {existingSkins.Count} skins");
@ -390,9 +390,9 @@ namespace osu.Game.Database
InstantiationInfo = skin.InstantiationInfo, InstantiationInfo = skin.InstantiationInfo,
}; };
migrateFiles(skin, realm, realmSkin); migrateFiles(skin, r, realmSkin);
realm.Add(realmSkin); r.Add(realmSkin);
if (skin.ID == userSkinInt) if (skin.ID == userSkinInt)
userSkinChoice.Value = realmSkin.ID.ToString(); userSkinChoice.Value = realmSkin.ID.ToString();
@ -428,12 +428,12 @@ namespace osu.Game.Database
log("Beginning settings migration to realm"); log("Beginning settings migration to realm");
realm.Run(realm => realm.Run(r =>
{ {
using (var transaction = realm.BeginWrite()) using (var transaction = r.BeginWrite())
{ {
// only migrate data if the realm database is empty. // only migrate data if the realm database is empty.
if (!realm.All<RealmRulesetSetting>().Any()) if (!r.All<RealmRulesetSetting>().Any())
{ {
log($"Migrating {existingSettings.Count} settings"); log($"Migrating {existingSettings.Count} settings");
@ -447,7 +447,7 @@ namespace osu.Game.Database
if (string.IsNullOrEmpty(shortName)) if (string.IsNullOrEmpty(shortName))
continue; continue;
realm.Add(new RealmRulesetSetting r.Add(new RealmRulesetSetting
{ {
Key = dkb.Key, Key = dkb.Key,
Value = dkb.StringValue, Value = dkb.StringValue,

View File

@ -30,7 +30,7 @@ using Realms.Exceptions;
namespace osu.Game.Database namespace osu.Game.Database
{ {
/// <summary> /// <summary>
/// A factory which provides both the main (update thread bound) realm context and creates contexts for async usage. /// A factory which provides safe access to the realm storage backend.
/// </summary> /// </summary>
public class RealmAccess : IDisposable public class RealmAccess : IDisposable
{ {
@ -57,9 +57,9 @@ namespace osu.Game.Database
private const int schema_version = 13; private const int schema_version = 13;
/// <summary> /// <summary>
/// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking context creation during blocking periods. /// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking realm retrieval during blocking periods.
/// </summary> /// </summary>
private readonly SemaphoreSlim realmCreationLock = new SemaphoreSlim(1); private readonly SemaphoreSlim realmRetrievalLock = new SemaphoreSlim(1);
private readonly ThreadLocal<bool> currentThreadCanCreateRealmInstances = new ThreadLocal<bool>(); private readonly ThreadLocal<bool> currentThreadCanCreateRealmInstances = new ThreadLocal<bool>();
@ -76,7 +76,7 @@ namespace osu.Game.Database
/// <summary> /// <summary>
/// Holds a map of functions registered via <see cref="RegisterForNotifications{T}"/> and a coinciding action which when triggered, /// Holds a map of functions registered via <see cref="RegisterForNotifications{T}"/> and a coinciding action which when triggered,
/// fires a change set event with an empty collection. This is used to inform subscribers when a realm context goes away, and ensure they don't use invalidated /// fires a change set event with an empty collection. This is used to inform subscribers when the main realm instance gets recycled, and ensure they don't use invalidated
/// managed realm objects from a previous firing. /// managed realm objects from a previous firing.
/// </summary> /// </summary>
private readonly Dictionary<Func<Realm, IDisposable?>, Action> notificationsResetMap = new Dictionary<Func<Realm, IDisposable?>, Action>(); private readonly Dictionary<Func<Realm, IDisposable?>, Action> notificationsResetMap = new Dictionary<Func<Realm, IDisposable?>, Action>();
@ -364,7 +364,7 @@ namespace osu.Game.Database
{ {
if (!currentThreadCanCreateRealmInstances.Value) if (!currentThreadCanCreateRealmInstances.Value)
{ {
realmCreationLock.Wait(); realmRetrievalLock.Wait();
currentThreadCanCreateRealmInstances.Value = true; currentThreadCanCreateRealmInstances.Value = true;
tookSemaphoreLock = true; tookSemaphoreLock = true;
} }
@ -383,7 +383,7 @@ namespace osu.Game.Database
{ {
if (tookSemaphoreLock) if (tookSemaphoreLock)
{ {
realmCreationLock.Release(); realmRetrievalLock.Release();
currentThreadCanCreateRealmInstances.Value = false; currentThreadCanCreateRealmInstances.Value = false;
} }
} }
@ -589,14 +589,14 @@ namespace osu.Game.Database
try try
{ {
realmCreationLock.Wait(); realmRetrievalLock.Wait();
lock (realmLock) lock (realmLock)
{ {
if (updateRealm == null) if (updateRealm == null)
{ {
// null context means the update thread has not yet retrieved its context. // null realm means the update thread has not yet retrieved its instance.
// we don't need to worry about reviving the update context in this case, so don't bother with the SynchronizationContext. // we don't need to worry about reviving the update instance in this case, so don't bother with the SynchronizationContext.
Debug.Assert(!ThreadSafety.IsUpdateThread); Debug.Assert(!ThreadSafety.IsUpdateThread);
} }
else else
@ -648,7 +648,7 @@ namespace osu.Game.Database
void restoreOperation() void restoreOperation()
{ {
Logger.Log(@"Restoring realm operations.", LoggingTarget.Database); Logger.Log(@"Restoring realm operations.", LoggingTarget.Database);
realmCreationLock.Release(); realmRetrievalLock.Release();
// Post back to the update thread to revive any subscriptions. // Post back to the update thread to revive any subscriptions.
syncContext?.Post(_ => ensureUpdateRealm(), null); syncContext?.Post(_ => ensureUpdateRealm(), null);
} }
@ -668,9 +668,9 @@ namespace osu.Game.Database
if (!isDisposed) if (!isDisposed)
{ {
// intentionally block context creation indefinitely. this ensures that nothing can start consuming a new context after disposal. // intentionally block realm retrieval indefinitely. this ensures that nothing can start consuming a new instance after disposal.
realmCreationLock.Wait(); realmRetrievalLock.Wait();
realmCreationLock.Dispose(); realmRetrievalLock.Dispose();
isDisposed = true; isDisposed = true;
} }

View File

@ -51,10 +51,7 @@ namespace osu.Game.Database
return; return;
} }
realm.Run(realm => realm.Run(r => perform(retrieveFromID(r, ID)));
{
perform(retrieveFromID(realm, ID));
});
} }
/// <summary> /// <summary>
@ -66,9 +63,9 @@ namespace osu.Game.Database
if (!IsManaged) if (!IsManaged)
return perform(data); return perform(data);
return realm.Run(realm => return realm.Run(r =>
{ {
var returnData = perform(retrieveFromID(realm, ID)); var returnData = perform(retrieveFromID(r, ID));
if (returnData is RealmObjectBase realmObject && realmObject.IsManaged) if (returnData is RealmObjectBase realmObject && realmObject.IsManaged)
throw new InvalidOperationException(@$"Managed realm objects should not exit the scope of {nameof(PerformRead)}."); throw new InvalidOperationException(@$"Managed realm objects should not exit the scope of {nameof(PerformRead)}.");

View File

@ -55,7 +55,7 @@ namespace osu.Game.Input.Bindings
protected override void LoadComplete() protected override void LoadComplete()
{ {
realmSubscription = realm.RegisterForNotifications(realm => queryRealmKeyBindings(), (sender, changes, error) => realmSubscription = realm.RegisterForNotifications(r => queryRealmKeyBindings(), (sender, changes, error) =>
{ {
// The first fire of this is a bit redundant as this is being called in base.LoadComplete, // The first fire of this is a bit redundant as this is being called in base.LoadComplete,
// but this is safest in case the subscription is restored after a context recycle. // but this is safest in case the subscription is restored after a context recycle.

View File

@ -56,21 +56,21 @@ namespace osu.Game.Input
/// <param name="rulesets">The rulesets to populate defaults from.</param> /// <param name="rulesets">The rulesets to populate defaults from.</param>
public void Register(KeyBindingContainer container, IEnumerable<RulesetInfo> rulesets) public void Register(KeyBindingContainer container, IEnumerable<RulesetInfo> rulesets)
{ {
realm.Run(realm => realm.Run(r =>
{ {
using (var transaction = realm.BeginWrite()) using (var transaction = r.BeginWrite())
{ {
// intentionally flattened to a list rather than querying against the IQueryable, as nullable fields being queried against aren't indexed. // intentionally flattened to a list rather than querying against the IQueryable, as nullable fields being queried against aren't indexed.
// this is much faster as a result. // this is much faster as a result.
var existingBindings = realm.All<RealmKeyBinding>().ToList(); var existingBindings = r.All<RealmKeyBinding>().ToList();
insertDefaults(realm, existingBindings, container.DefaultKeyBindings); insertDefaults(r, existingBindings, container.DefaultKeyBindings);
foreach (var ruleset in rulesets) foreach (var ruleset in rulesets)
{ {
var instance = ruleset.CreateInstance(); var instance = ruleset.CreateInstance();
foreach (int variant in instance.AvailableVariants) foreach (int variant in instance.AvailableVariants)
insertDefaults(realm, existingBindings, instance.GetDefaultKeyBindings(variant), ruleset.ShortName, variant); insertDefaults(r, existingBindings, instance.GetDefaultKeyBindings(variant), ruleset.ShortName, variant);
} }
transaction.Commit(); transaction.Commit();

View File

@ -42,7 +42,7 @@ namespace osu.Game.Online
// Used to interact with manager classes that don't support interface types. Will eventually be replaced. // Used to interact with manager classes that don't support interface types. Will eventually be replaced.
var beatmapSetInfo = new BeatmapSetInfo { OnlineID = TrackedItem.OnlineID }; var beatmapSetInfo = new BeatmapSetInfo { OnlineID = TrackedItem.OnlineID };
realmSubscription = realm.RegisterForNotifications(realm => realm.All<BeatmapSetInfo>().Where(s => s.OnlineID == TrackedItem.OnlineID && !s.DeletePending), (items, changes, ___) => realmSubscription = realm.RegisterForNotifications(r => r.All<BeatmapSetInfo>().Where(s => s.OnlineID == TrackedItem.OnlineID && !s.DeletePending), (items, changes, ___) =>
{ {
if (items.Any()) if (items.Any())
Schedule(() => UpdateState(DownloadState.LocallyAvailable)); Schedule(() => UpdateState(DownloadState.LocallyAvailable));

View File

@ -78,7 +78,7 @@ namespace osu.Game.Online.Rooms
// handles changes to hash that didn't occur from the import process (ie. a user editing the beatmap in the editor, somehow). // handles changes to hash that didn't occur from the import process (ie. a user editing the beatmap in the editor, somehow).
realmSubscription?.Dispose(); realmSubscription?.Dispose();
realmSubscription = realm.RegisterForNotifications(realm => filteredBeatmaps(), (items, changes, ___) => realmSubscription = realm.RegisterForNotifications(r => filteredBeatmaps(), (items, changes, ___) =>
{ {
if (changes == null) if (changes == null)
return; return;

View File

@ -47,7 +47,7 @@ namespace osu.Game.Online
Downloader.DownloadBegan += downloadBegan; Downloader.DownloadBegan += downloadBegan;
Downloader.DownloadFailed += downloadFailed; Downloader.DownloadFailed += downloadFailed;
realmSubscription = realm.RegisterForNotifications(realm => realm.All<ScoreInfo>().Where(s => ((s.OnlineID > 0 && s.OnlineID == TrackedItem.OnlineID) || s.Hash == TrackedItem.Hash) && !s.DeletePending), (items, changes, ___) => realmSubscription = realm.RegisterForNotifications(r => r.All<ScoreInfo>().Where(s => ((s.OnlineID > 0 && s.OnlineID == TrackedItem.OnlineID) || s.Hash == TrackedItem.Hash) && !s.DeletePending), (items, changes, ___) =>
{ {
if (items.Any()) if (items.Any())
Schedule(() => UpdateState(DownloadState.LocallyAvailable)); Schedule(() => UpdateState(DownloadState.LocallyAvailable));

View File

@ -30,16 +30,7 @@ namespace osu.Game.Overlays
[Resolved] [Resolved]
private BeatmapManager beatmaps { get; set; } private BeatmapManager beatmaps { get; set; }
public IBindableList<BeatmapSetInfo> BeatmapSets public IBindableList<BeatmapSetInfo> BeatmapSets => beatmapSets;
{
get
{
if (LoadState < LoadState.Ready)
throw new InvalidOperationException($"{nameof(BeatmapSets)} should not be accessed before the music controller is loaded.");
return beatmapSets;
}
}
/// <summary> /// <summary>
/// Point in time after which the current track will be restarted on triggering a "previous track" action. /// Point in time after which the current track will be restarted on triggering a "previous track" action.
@ -88,13 +79,7 @@ namespace osu.Game.Overlays
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
beatmapSubscription = realm.RegisterForNotifications(r => queryRealmBeatmapSets(), beatmapsChanged);
// ensure we're ready before completing async load.
// probably not a good way of handling this (as there is a period we aren't watching for changes until the realm subscription finishes up.
foreach (var s in queryRealmBeatmapSets())
beatmapSets.Add(s.Detach());
beatmapSubscription = realm.RegisterForNotifications(realm => queryRealmBeatmapSets(), beatmapsChanged);
} }
private void beatmapsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet changes, Exception error) private void beatmapsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet changes, Exception error)

View File

@ -386,10 +386,10 @@ namespace osu.Game.Overlays.Settings.Sections.Input
private void updateStoreFromButton(KeyButton button) private void updateStoreFromButton(KeyButton button)
{ {
realm.Run(realm => realm.Run(r =>
{ {
var binding = realm.Find<RealmKeyBinding>(((IHasGuidPrimaryKey)button.KeyBinding).ID); var binding = r.Find<RealmKeyBinding>(((IHasGuidPrimaryKey)button.KeyBinding).ID);
realm.Write(() => binding.KeyCombinationString = button.KeyBinding.KeyCombinationString); r.Write(() => binding.KeyCombinationString = button.KeyBinding.KeyCombinationString);
}); });
} }

View File

@ -83,7 +83,7 @@ namespace osu.Game.Overlays.Settings.Sections
skinDropdown.Current = dropdownBindable; skinDropdown.Current = dropdownBindable;
realmSubscription = realm.RegisterForNotifications(realm => queryRealmSkins(), (sender, changes, error) => realmSubscription = realm.RegisterForNotifications(r => queryRealmSkins(), (sender, changes, error) =>
{ {
// The first fire of this is a bit redundant due to the call below, // The first fire of this is a bit redundant due to the call below,
// but this is safest in case the subscription is restored after a context recycle. // but this is safest in case the subscription is restored after a context recycle.

View File

@ -56,11 +56,11 @@ namespace osu.Game.Rulesets.Configuration
pendingWrites.Clear(); pendingWrites.Clear();
} }
realm?.Write(realm => realm?.Write(r =>
{ {
foreach (var c in changed) foreach (var c in changed)
{ {
var setting = realm.All<RealmRulesetSetting>().First(s => s.RulesetName == rulesetName && s.Variant == variant && s.Key == c.ToString()); var setting = r.All<RealmRulesetSetting>().First(s => s.RulesetName == rulesetName && s.Variant == variant && s.Key == c.ToString());
setting.Value = ConfigStore[c].ToString(); setting.Value = ConfigStore[c].ToString();
} }

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets
{ {
public class RulesetStore : IDisposable, IRulesetStore public class RulesetStore : IDisposable, IRulesetStore
{ {
private readonly RealmAccess realm; private readonly RealmAccess realmAccess;
private const string ruleset_library_prefix = @"osu.Game.Rulesets"; private const string ruleset_library_prefix = @"osu.Game.Rulesets";
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets
public RulesetStore(RealmAccess realm, Storage? storage = null) public RulesetStore(RealmAccess realm, Storage? storage = null)
{ {
this.realm = realm; realmAccess = realm;
// On android in release configuration assemblies are loaded from the apk directly into memory. // On android in release configuration assemblies are loaded from the apk directly into memory.
// We cannot read assemblies from cwd, so should check loaded assemblies instead. // We cannot read assemblies from cwd, so should check loaded assemblies instead.
@ -100,7 +100,7 @@ namespace osu.Game.Rulesets
private void addMissingRulesets() private void addMissingRulesets()
{ {
realm.Write(realm => realmAccess.Write(realm =>
{ {
var rulesets = realm.All<RulesetInfo>(); var rulesets = realm.All<RulesetInfo>();

View File

@ -51,7 +51,7 @@ namespace osu.Game.Scoring
/// <returns>The first result for the provided query, or null if no results were found.</returns> /// <returns>The first result for the provided query, or null if no results were found.</returns>
public ScoreInfo Query(Expression<Func<ScoreInfo, bool>> query) public ScoreInfo Query(Expression<Func<ScoreInfo, bool>> query)
{ {
return realm.Run(realm => realm.All<ScoreInfo>().FirstOrDefault(query)?.Detach()); return realm.Run(r => r.All<ScoreInfo>().FirstOrDefault(query)?.Detach());
} }
/// <summary> /// <summary>
@ -254,9 +254,9 @@ namespace osu.Game.Scoring
public void Delete([CanBeNull] Expression<Func<ScoreInfo, bool>> filter = null, bool silent = false) public void Delete([CanBeNull] Expression<Func<ScoreInfo, bool>> filter = null, bool silent = false)
{ {
realm.Run(realm => realm.Run(r =>
{ {
var items = realm.All<ScoreInfo>() var items = r.All<ScoreInfo>()
.Where(s => !s.DeletePending); .Where(s => !s.DeletePending);
if (filter != null) if (filter != null)

View File

@ -74,7 +74,7 @@ namespace osu.Game.Scoring
public override bool IsAvailableLocally(ScoreInfo model) public override bool IsAvailableLocally(ScoreInfo model)
{ {
return Access.Run(realm => realm.All<ScoreInfo>().Any(s => s.OnlineID == model.OnlineID)); return Realm.Run(realm => realm.All<ScoreInfo>().Any(s => s.OnlineID == model.OnlineID));
} }
} }
} }

View File

@ -179,7 +179,7 @@ namespace osu.Game.Screens.Select
if (!loadedTestBeatmaps) if (!loadedTestBeatmaps)
{ {
realm.Run(realm => loadBeatmapSets(getBeatmapSets(realm))); realm.Run(r => loadBeatmapSets(getBeatmapSets(r)));
} }
} }
@ -191,12 +191,12 @@ namespace osu.Game.Screens.Select
base.LoadComplete(); base.LoadComplete();
subscriptionSets = realm.RegisterForNotifications(getBeatmapSets, beatmapSetsChanged); subscriptionSets = realm.RegisterForNotifications(getBeatmapSets, beatmapSetsChanged);
subscriptionBeatmaps = realm.RegisterForNotifications(realm => realm.All<BeatmapInfo>().Where(b => !b.Hidden), beatmapsChanged); subscriptionBeatmaps = realm.RegisterForNotifications(r => r.All<BeatmapInfo>().Where(b => !b.Hidden), beatmapsChanged);
// Can't use main subscriptions because we can't lookup deleted indices. // Can't use main subscriptions because we can't lookup deleted indices.
// https://github.com/realm/realm-dotnet/discussions/2634#discussioncomment-1605595. // https://github.com/realm/realm-dotnet/discussions/2634#discussioncomment-1605595.
subscriptionDeletedSets = realm.RegisterForNotifications(realm => realm.All<BeatmapSetInfo>().Where(s => s.DeletePending && !s.Protected), deletedBeatmapSetsChanged); subscriptionDeletedSets = realm.RegisterForNotifications(r => r.All<BeatmapSetInfo>().Where(s => s.DeletePending && !s.Protected), deletedBeatmapSetsChanged);
subscriptionHiddenBeatmaps = realm.RegisterForNotifications(realm => realm.All<BeatmapInfo>().Where(b => b.Hidden), beatmapsChanged); subscriptionHiddenBeatmaps = realm.RegisterForNotifications(r => r.All<BeatmapInfo>().Where(b => b.Hidden), beatmapsChanged);
} }
private void deletedBeatmapSetsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet changes, Exception error) private void deletedBeatmapSetsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet changes, Exception error)

View File

@ -48,8 +48,8 @@ namespace osu.Game.Screens.Select.Carousel
ruleset.BindValueChanged(_ => ruleset.BindValueChanged(_ =>
{ {
scoreSubscription?.Dispose(); scoreSubscription?.Dispose();
scoreSubscription = realm.RegisterForNotifications(realm => scoreSubscription = realm.RegisterForNotifications(r =>
realm.All<ScoreInfo>() r.All<ScoreInfo>()
.Filter($"{nameof(ScoreInfo.User)}.{nameof(RealmUser.OnlineID)} == $0" .Filter($"{nameof(ScoreInfo.User)}.{nameof(RealmUser.OnlineID)} == $0"
+ $" && {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $1" + $" && {nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} == $1"
+ $" && {nameof(ScoreInfo.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $2" + $" && {nameof(ScoreInfo.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $2"

View File

@ -113,8 +113,8 @@ namespace osu.Game.Screens.Select.Leaderboards
if (beatmapInfo == null) if (beatmapInfo == null)
return; return;
scoreSubscription = realm.RegisterForNotifications(realm => scoreSubscription = realm.RegisterForNotifications(r =>
realm.All<ScoreInfo>() r.All<ScoreInfo>()
.Filter($"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} = $0", beatmapInfo.ID), .Filter($"{nameof(ScoreInfo.BeatmapInfo)}.{nameof(BeatmapInfo.ID)} = $0", beatmapInfo.ID),
(_, changes, ___) => (_, changes, ___) =>
{ {
@ -150,9 +150,9 @@ namespace osu.Game.Screens.Select.Leaderboards
if (Scope == BeatmapLeaderboardScope.Local) if (Scope == BeatmapLeaderboardScope.Local)
{ {
realm.Run(realm => realm.Run(r =>
{ {
var scores = realm.All<ScoreInfo>() var scores = r.All<ScoreInfo>()
.AsEnumerable() .AsEnumerable()
// TODO: update to use a realm filter directly (or at least figure out the beatmap part to reduce scope). // TODO: update to use a realm filter directly (or at least figure out the beatmap part to reduce scope).
.Where(s => !s.DeletePending && s.BeatmapInfo.ID == fetchBeatmapInfo.ID && s.Ruleset.OnlineID == ruleset.Value.ID); .Where(s => !s.DeletePending && s.BeatmapInfo.ID == fetchBeatmapInfo.ID && s.Ruleset.OnlineID == ruleset.Value.ID);

View File

@ -87,12 +87,12 @@ namespace osu.Game.Skinning
}; };
// Ensure the default entries are present. // Ensure the default entries are present.
realm.Write(realm => realm.Write(r =>
{ {
foreach (var skin in defaultSkins) foreach (var skin in defaultSkins)
{ {
if (realm.Find<SkinInfo>(skin.SkinInfo.ID) == null) if (r.Find<SkinInfo>(skin.SkinInfo.ID) == null)
realm.Add(skin.SkinInfo.Value); r.Add(skin.SkinInfo.Value);
} }
}); });
@ -289,9 +289,9 @@ namespace osu.Game.Skinning
public void Delete([CanBeNull] Expression<Func<SkinInfo, bool>> filter = null, bool silent = false) public void Delete([CanBeNull] Expression<Func<SkinInfo, bool>> filter = null, bool silent = false)
{ {
realm.Run(realm => realm.Run(r =>
{ {
var items = realm.All<SkinInfo>() var items = r.All<SkinInfo>()
.Where(s => !s.Protected && !s.DeletePending); .Where(s => !s.Protected && !s.DeletePending);
if (filter != null) if (filter != null)
items = items.Where(filter); items = items.Where(filter);

View File

@ -205,7 +205,7 @@ namespace osu.Game.Skinning
private void populateMissingHashes() private void populateMissingHashes()
{ {
Access.Run(realm => Realm.Run(realm =>
{ {
var skinsWithoutHashes = realm.All<SkinInfo>().Where(i => !i.Protected && string.IsNullOrEmpty(i.Hash)).ToArray(); var skinsWithoutHashes = realm.All<SkinInfo>().Where(i => !i.Protected && string.IsNullOrEmpty(i.Hash)).ToArray();

View File

@ -165,7 +165,7 @@ namespace osu.Game.Stores
public override bool IsAvailableLocally(BeatmapSetInfo model) public override bool IsAvailableLocally(BeatmapSetInfo model)
{ {
return Access.Run(realm => realm.All<BeatmapInfo>().Any(b => b.OnlineID == model.OnlineID)); return Realm.Run(realm => realm.All<BeatmapInfo>().Any(b => b.OnlineID == model.OnlineID));
} }
public override string HumanisedModelName => "beatmap"; public override string HumanisedModelName => "beatmap";

View File

@ -59,7 +59,7 @@ namespace osu.Game.Stores
protected readonly RealmFileStore Files; protected readonly RealmFileStore Files;
protected readonly RealmAccess Access; protected readonly RealmAccess Realm;
/// <summary> /// <summary>
/// Fired when the user requests to view the resulting import. /// Fired when the user requests to view the resulting import.
@ -73,7 +73,7 @@ namespace osu.Game.Stores
protected RealmArchiveModelImporter(Storage storage, RealmAccess realm) protected RealmArchiveModelImporter(Storage storage, RealmAccess realm)
{ {
Access = realm; Realm = realm;
Files = new RealmFileStore(realm, storage); Files = new RealmFileStore(realm, storage);
} }
@ -320,7 +320,7 @@ namespace osu.Game.Stores
/// <param name="cancellationToken">An optional cancellation token.</param> /// <param name="cancellationToken">An optional cancellation token.</param>
public virtual Task<ILive<TModel>?> Import(TModel item, ArchiveReader? archive = null, bool lowPriority = false, CancellationToken cancellationToken = default) public virtual Task<ILive<TModel>?> Import(TModel item, ArchiveReader? archive = null, bool lowPriority = false, CancellationToken cancellationToken = default)
{ {
return Access.Run(realm => return Realm.Run(realm =>
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
@ -352,7 +352,7 @@ namespace osu.Game.Stores
transaction.Commit(); transaction.Commit();
} }
return Task.FromResult((ILive<TModel>?)existing.ToLive(Access)); return Task.FromResult((ILive<TModel>?)existing.ToLive(Realm));
} }
LogForModel(item, @"Found existing (optimised) but failed pre-check."); LogForModel(item, @"Found existing (optimised) but failed pre-check.");
@ -387,7 +387,7 @@ namespace osu.Game.Stores
existing.DeletePending = false; existing.DeletePending = false;
transaction.Commit(); transaction.Commit();
return Task.FromResult((ILive<TModel>?)existing.ToLive(Access)); return Task.FromResult((ILive<TModel>?)existing.ToLive(Realm));
} }
LogForModel(item, @"Found existing but failed re-use check."); LogForModel(item, @"Found existing but failed re-use check.");
@ -413,7 +413,7 @@ namespace osu.Game.Stores
throw; throw;
} }
return Task.FromResult((ILive<TModel>?)item.ToLive(Access)); return Task.FromResult((ILive<TModel>?)item.ToLive(Realm));
}); });
} }

View File

@ -45,7 +45,7 @@ namespace osu.Game.Stores
// This method should be removed as soon as all the surrounding pieces support non-detached operations. // This method should be removed as soon as all the surrounding pieces support non-detached operations.
if (!item.IsManaged) if (!item.IsManaged)
{ {
var managed = Access.Realm.Find<TModel>(item.ID); var managed = Realm.Realm.Find<TModel>(item.ID);
managed.Realm.Write(() => operation(managed)); managed.Realm.Write(() => operation(managed));
item.Files.Clear(); item.Files.Clear();
@ -165,7 +165,7 @@ namespace osu.Game.Stores
public bool Delete(TModel item) public bool Delete(TModel item)
{ {
return Access.Run(realm => return Realm.Run(realm =>
{ {
if (!item.IsManaged) if (!item.IsManaged)
item = realm.Find<TModel>(item.ID); item = realm.Find<TModel>(item.ID);
@ -180,7 +180,7 @@ namespace osu.Game.Stores
public void Undelete(TModel item) public void Undelete(TModel item)
{ {
Access.Run(realm => Realm.Run(realm =>
{ {
if (!item.IsManaged) if (!item.IsManaged)
item = realm.Find<TModel>(item.ID); item = realm.Find<TModel>(item.ID);

View File

@ -92,10 +92,10 @@ namespace osu.Game.Stores
int removedFiles = 0; int removedFiles = 0;
// can potentially be run asynchronously, although we will need to consider operation order for disk deletion vs realm removal. // can potentially be run asynchronously, although we will need to consider operation order for disk deletion vs realm removal.
realm.Write(realm => realm.Write(r =>
{ {
// TODO: consider using a realm native query to avoid iterating all files (https://github.com/realm/realm-dotnet/issues/2659#issuecomment-927823707) // TODO: consider using a realm native query to avoid iterating all files (https://github.com/realm/realm-dotnet/issues/2659#issuecomment-927823707)
var files = realm.All<RealmFile>().ToList(); var files = r.All<RealmFile>().ToList();
foreach (var file in files) foreach (var file in files)
{ {
@ -108,7 +108,7 @@ namespace osu.Game.Stores
{ {
removedFiles++; removedFiles++;
Storage.Delete(file.GetStoragePath()); Storage.Delete(file.GetStoragePath());
realm.Remove(file); r.Remove(file);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual
working = CreateWorkingBeatmap(Ruleset.Value); working = CreateWorkingBeatmap(Ruleset.Value);
if (IsolateSavingFromDatabase) if (IsolateSavingFromDatabase)
Dependencies.CacheAs<BeatmapManager>(testBeatmapManager = new TestBeatmapManager(LocalStorage, Access, rulesets, null, audio, Resources, host, Beatmap.Default)); Dependencies.CacheAs<BeatmapManager>(testBeatmapManager = new TestBeatmapManager(LocalStorage, Realm, rulesets, null, audio, Resources, host, Beatmap.Default));
} }
protected override void LoadComplete() protected override void LoadComplete()

View File

@ -75,9 +75,9 @@ namespace osu.Game.Tests.Visual
/// <remarks> /// <remarks>
/// In interactive runs (ie. VisualTests) this will use the user's database if <see cref="UseFreshStoragePerRun"/> is not set to <c>true</c>. /// In interactive runs (ie. VisualTests) this will use the user's database if <see cref="UseFreshStoragePerRun"/> is not set to <c>true</c>.
/// </remarks> /// </remarks>
protected RealmAccess Access => contextFactory.Value; protected RealmAccess Realm => realm.Value;
private Lazy<RealmAccess> contextFactory; private Lazy<RealmAccess> realm;
/// <summary> /// <summary>
/// Whether a fresh storage should be initialised per test (method) run. /// Whether a fresh storage should be initialised per test (method) run.
@ -119,7 +119,7 @@ namespace osu.Game.Tests.Visual
Resources = parent.Get<OsuGameBase>().Resources; Resources = parent.Get<OsuGameBase>().Resources;
contextFactory = new Lazy<RealmAccess>(() => new RealmAccess(LocalStorage, "client")); realm = new Lazy<RealmAccess>(() => new RealmAccess(LocalStorage, "client"));
RecycleLocalStorage(false); RecycleLocalStorage(false);