From 1f9cf00db89f7a80027e665d86a3cfd8e1891b31 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Jan 2022 16:44:44 +0900 Subject: [PATCH] Fix `DatabasedKeyBindingContainer` re-querying realm on receiving notification --- .../Bindings/DatabasedKeyBindingContainer.cs | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs index 3e4a9759a3..ba129b93e5 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs @@ -8,6 +8,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Database; using osu.Game.Rulesets; +using Realms; namespace osu.Game.Input.Bindings { @@ -46,41 +47,36 @@ public DatabasedKeyBindingContainer(RulesetInfo ruleset = null, int? variant = n throw new InvalidOperationException($"{nameof(variant)} can not be null when a non-null {nameof(ruleset)} is provided."); } - private IQueryable queryRealmKeyBindings() - { - string rulesetName = ruleset?.ShortName; - return realm.Realm.All() - .Where(b => b.RulesetName == rulesetName && b.Variant == variant); - } - protected override void LoadComplete() { - realmSubscription = realm.RegisterForNotifications(r => queryRealmKeyBindings(), (sender, changes, error) => + realmSubscription = realm.RegisterForNotifications(queryRealmKeyBindings, (sender, changes, error) => { // 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. - ReloadMappings(); + reloadMappings(sender.AsQueryable()); }); base.LoadComplete(); } - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); + protected override void ReloadMappings() => reloadMappings(queryRealmKeyBindings(realm.Realm)); - realmSubscription?.Dispose(); + private IQueryable queryRealmKeyBindings(Realm realm) + { + string rulesetName = ruleset?.ShortName; + return realm.All() + .Where(b => b.RulesetName == rulesetName && b.Variant == variant); } - protected override void ReloadMappings() + private void reloadMappings(IQueryable realmKeyBindings) { var defaults = DefaultKeyBindings.ToList(); - List newBindings = queryRealmKeyBindings().Detach() - // this ordering is important to ensure that we read entries from the database in the order - // enforced by DefaultKeyBindings. allow for song select to handle actions that may otherwise - // have been eaten by the music controller due to query order. - .OrderBy(b => defaults.FindIndex(d => (int)d.Action == b.ActionInt)).ToList(); + List newBindings = realmKeyBindings.Detach() + // this ordering is important to ensure that we read entries from the database in the order + // enforced by DefaultKeyBindings. allow for song select to handle actions that may otherwise + // have been eaten by the music controller due to query order. + .OrderBy(b => defaults.FindIndex(d => (int)d.Action == b.ActionInt)).ToList(); // In the case no bindings were found in the database, presume this usage is for a non-databased ruleset. // This actually should never be required and can be removed if it is ever deemed to cause a problem. @@ -91,5 +87,12 @@ protected override void ReloadMappings() else KeyBindings = newBindings; } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + realmSubscription?.Dispose(); + } } }