Merge pull request #16607 from peppy/key-binding-container-notification-fix

Fix `DatabasedKeyBindingContainer` re-querying realm on receiving notification
This commit is contained in:
Dan Balasescu
2022-01-25 21:40:21 +09:00
committed by GitHub

View File

@ -8,6 +8,7 @@ using osu.Framework.Allocation;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using Realms;
namespace osu.Game.Input.Bindings namespace osu.Game.Input.Bindings
{ {
@ -46,37 +47,32 @@ namespace osu.Game.Input.Bindings
throw new InvalidOperationException($"{nameof(variant)} can not be null when a non-null {nameof(ruleset)} is provided."); throw new InvalidOperationException($"{nameof(variant)} can not be null when a non-null {nameof(ruleset)} is provided.");
} }
private IQueryable<RealmKeyBinding> queryRealmKeyBindings()
{
string rulesetName = ruleset?.ShortName;
return realm.Realm.All<RealmKeyBinding>()
.Where(b => b.RulesetName == rulesetName && b.Variant == variant);
}
protected override void LoadComplete() 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, // 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.
ReloadMappings(); reloadMappings(sender.AsQueryable());
}); });
base.LoadComplete(); base.LoadComplete();
} }
protected override void Dispose(bool isDisposing) protected override void ReloadMappings() => reloadMappings(queryRealmKeyBindings(realm.Realm));
{
base.Dispose(isDisposing);
realmSubscription?.Dispose(); private IQueryable<RealmKeyBinding> queryRealmKeyBindings(Realm realm)
{
string rulesetName = ruleset?.ShortName;
return realm.All<RealmKeyBinding>()
.Where(b => b.RulesetName == rulesetName && b.Variant == variant);
} }
protected override void ReloadMappings() private void reloadMappings(IQueryable<RealmKeyBinding> realmKeyBindings)
{ {
var defaults = DefaultKeyBindings.ToList(); var defaults = DefaultKeyBindings.ToList();
List<RealmKeyBinding> newBindings = queryRealmKeyBindings().Detach() List<RealmKeyBinding> newBindings = realmKeyBindings.Detach()
// this ordering is important to ensure that we read entries from the database in the order // 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 // enforced by DefaultKeyBindings. allow for song select to handle actions that may otherwise
// have been eaten by the music controller due to query order. // have been eaten by the music controller due to query order.
@ -91,5 +87,12 @@ namespace osu.Game.Input.Bindings
else else
KeyBindings = newBindings; KeyBindings = newBindings;
} }
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
realmSubscription?.Dispose();
}
} }
} }