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

Use IKeyBinding for all key binding usages (and add update flow via primary key)

This commit is contained in:
Dean Herbert 2021-01-08 15:49:01 +09:00
parent a77519c6bd
commit 8765aaf9e6
11 changed files with 72 additions and 52 deletions

View File

@ -244,7 +244,7 @@ namespace osu.Game.Tests.Visual.Gameplay
internal class TestKeyBindingContainer : KeyBindingContainer<TestAction> internal class TestKeyBindingContainer : KeyBindingContainer<TestAction>
{ {
public override IEnumerable<KeyBinding> DefaultKeyBindings => new[] public override IEnumerable<IKeyBinding> DefaultKeyBindings => new[]
{ {
new KeyBinding(InputKey.MouseLeft, TestAction.Down), new KeyBinding(InputKey.MouseLeft, TestAction.Down),
}; };

View File

@ -179,7 +179,7 @@ namespace osu.Game.Tests.Visual.Gameplay
internal class TestKeyBindingContainer : KeyBindingContainer<TestAction> internal class TestKeyBindingContainer : KeyBindingContainer<TestAction>
{ {
public override IEnumerable<KeyBinding> DefaultKeyBindings => new[] public override IEnumerable<IKeyBinding> DefaultKeyBindings => new[]
{ {
new KeyBinding(InputKey.MouseLeft, TestAction.Down), new KeyBinding(InputKey.MouseLeft, TestAction.Down),
}; };

View File

@ -298,7 +298,7 @@ namespace osu.Game.Tests.Visual.Gameplay
internal class TestKeyBindingContainer : KeyBindingContainer<TestAction> internal class TestKeyBindingContainer : KeyBindingContainer<TestAction>
{ {
public override IEnumerable<KeyBinding> DefaultKeyBindings => new[] public override IEnumerable<IKeyBinding> DefaultKeyBindings => new[]
{ {
new KeyBinding(InputKey.MouseLeft, TestAction.Down), new KeyBinding(InputKey.MouseLeft, TestAction.Down),
}; };

View File

@ -8,7 +8,7 @@ using osu.Game.Database;
namespace osu.Game.Input.Bindings namespace osu.Game.Input.Bindings
{ {
[Table("KeyBinding")] [Table("KeyBinding")]
public class DatabasedKeyBinding : KeyBinding, IHasPrimaryKey public class DatabasedKeyBinding : IKeyBinding, IHasPrimaryKey
{ {
public int ID { get; set; } public int ID { get; set; }
@ -17,17 +17,23 @@ namespace osu.Game.Input.Bindings
public int? Variant { get; set; } public int? Variant { get; set; }
[Column("Keys")] [Column("Keys")]
public string KeysString public string KeysString { get; set; }
{
get => KeyCombination.ToString();
private set => KeyCombination = value;
}
[Column("Action")] [Column("Action")]
public int IntAction public int IntAction { get; set; }
[NotMapped]
public KeyCombination KeyCombination
{ {
get => (int)Action; get => KeysString;
set => Action = value; set => KeysString = value.ToString();
}
[NotMapped]
public object Action
{
get => IntAction;
set => IntAction = (int)value;
} }
} }
} }

View File

@ -23,7 +23,7 @@ namespace osu.Game.Input.Bindings
[Resolved] [Resolved]
private IKeyBindingStore store { get; set; } private IKeyBindingStore store { get; set; }
public override IEnumerable<KeyBinding> DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings(variant ?? 0); public override IEnumerable<IKeyBinding> DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings(variant ?? 0);
/// <summary> /// <summary>
/// Create a new instance. /// Create a new instance.

View File

@ -21,7 +21,7 @@ namespace osu.Game.Input.Bindings
handler = game; handler = game;
} }
public override IEnumerable<KeyBinding> DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings).Concat(EditorKeyBindings); public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings).Concat(EditorKeyBindings);
public IEnumerable<KeyBinding> GlobalKeyBindings => new[] public IEnumerable<KeyBinding> GlobalKeyBindings => new[]
{ {

View File

@ -8,14 +8,27 @@ using Realms;
namespace osu.Game.Input.Bindings namespace osu.Game.Input.Bindings
{ {
[MapTo("KeyBinding")] [MapTo("KeyBinding")]
public class RealmKeyBinding : RealmObject, IHasGuidPrimaryKey public class RealmKeyBinding : RealmObject, IHasGuidPrimaryKey, IKeyBinding
{ {
[PrimaryKey]
public string ID { get; set; } public string ID { get; set; }
public int? RulesetID { get; set; } public int? RulesetID { get; set; }
public int? Variant { get; set; } public int? Variant { get; set; }
KeyCombination IKeyBinding.KeyCombination
{
get => KeyCombination;
set => KeyCombination = value.ToString();
}
object IKeyBinding.Action
{
get => Action;
set => Action = (int)value;
}
public int Action { get; set; } public int Action { get; set; }
public string KeyCombination { get; set; } public string KeyCombination { get; set; }

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Game.Database;
using osu.Game.Input.Bindings; using osu.Game.Input.Bindings;
namespace osu.Game.Input namespace osu.Game.Input
@ -27,14 +28,14 @@ namespace osu.Game.Input
/// <param name="rulesetId">The ruleset's internal ID.</param> /// <param name="rulesetId">The ruleset's internal ID.</param>
/// <param name="variant">An optional variant.</param> /// <param name="variant">An optional variant.</param>
/// <returns></returns> /// <returns></returns>
List<KeyBinding> Query(int? rulesetId = null, int? variant = null); List<IKeyBinding> Query(int? rulesetId = null, int? variant = null);
/// <summary> /// <summary>
/// Retrieve <see cref="KeyBinding"/>s for the specified action. /// Retrieve <see cref="IKeyBinding"/>s for the specified action.
/// </summary> /// </summary>
/// <param name="action">The action to lookup.</param> /// <param name="action">The action to lookup.</param>
List<KeyBinding> Query<T>(T action) where T : Enum; List<IKeyBinding> Query<T>(T action) where T : Enum;
public void Update(KeyBinding buttonKeyBinding) => throw new NotImplementedException(); void Update(IHasGuidPrimaryKey keyBinding, Action<IKeyBinding> modification);
} }
} }

View File

@ -49,16 +49,21 @@ namespace osu.Game.Input
} }
} }
public List<KeyBinding> Query(int? rulesetId = null, int? variant = null) public List<IKeyBinding> Query(int? rulesetId = null, int? variant = null)
=> query(rulesetId, variant).OfType<KeyBinding>().ToList(); => query(rulesetId, variant).OfType<IKeyBinding>().ToList();
public List<KeyBinding> Query<T>(T action) where T : Enum public List<IKeyBinding> Query<T>(T action) where T : Enum
{ {
int lookup = (int)(object)action; int lookup = (int)(object)action;
return query(null, null).Where(rkb => (int)rkb.Action == lookup).OfType<KeyBinding>().ToList(); return query(null, null).Where(rkb => (int)rkb.Action == lookup).OfType<IKeyBinding>().ToList();
} }
private void insertDefaults(IEnumerable<KeyBinding> defaults, int? rulesetId = null, int? variant = null) public void Update(IHasGuidPrimaryKey keyBinding, Action<IKeyBinding> modification)
{
throw new NotImplementedException();
}
private void insertDefaults(IEnumerable<IKeyBinding> defaults, int? rulesetId = null, int? variant = null)
{ {
using (var usage = ContextFactory.GetForWrite()) using (var usage = ContextFactory.GetForWrite())
{ {
@ -98,11 +103,11 @@ namespace osu.Game.Input
private List<DatabasedKeyBinding> query(int? rulesetId = null, int? variant = null) => private List<DatabasedKeyBinding> query(int? rulesetId = null, int? variant = null) =>
ContextFactory.Get().DatabasedKeyBinding.Where(b => b.RulesetID == rulesetId && b.Variant == variant).ToList(); ContextFactory.Get().DatabasedKeyBinding.Where(b => b.RulesetID == rulesetId && b.Variant == variant).ToList();
public void Update(KeyBinding keyBinding) public void Update(DatabasedKeyBinding keyBinding)
{ {
using (ContextFactory.GetForWrite()) using (ContextFactory.GetForWrite())
{ {
var dbKeyBinding = (DatabasedKeyBinding)keyBinding; var dbKeyBinding = keyBinding;
Refresh(ref dbKeyBinding); Refresh(ref dbKeyBinding);
if (dbKeyBinding.KeyCombination.Equals(keyBinding.KeyCombination)) if (dbKeyBinding.KeyCombination.Equals(keyBinding.KeyCombination))

View File

@ -37,9 +37,9 @@ namespace osu.Game.Input
/// <returns>A set of display strings for all the user's key configuration for the action.</returns> /// <returns>A set of display strings for all the user's key configuration for the action.</returns>
public IEnumerable<string> GetReadableKeyCombinationsFor(GlobalAction globalAction) public IEnumerable<string> GetReadableKeyCombinationsFor(GlobalAction globalAction)
{ {
foreach (var action in query().Where(b => (GlobalAction)b.KeyBinding.Action == globalAction)) foreach (var action in query().Where(b => (GlobalAction)b.Action == globalAction))
{ {
string str = action.KeyBinding.KeyCombination.ReadableString(); string str = ((IKeyBinding)action).KeyCombination.ReadableString();
// even if found, the readable string may be empty for an unbound action. // even if found, the readable string may be empty for an unbound action.
if (str.Length > 0) if (str.Length > 0)
@ -49,14 +49,14 @@ namespace osu.Game.Input
public void Register(KeyBindingContainer manager) => insertDefaults(manager.DefaultKeyBindings); public void Register(KeyBindingContainer manager) => insertDefaults(manager.DefaultKeyBindings);
private void insertDefaults(IEnumerable<KeyBinding> defaults, int? rulesetId = null, int? variant = null) private void insertDefaults(IEnumerable<IKeyBinding> defaults, int? rulesetId = null, int? variant = null)
{ {
using (var usage = ContextFactory.GetForWrite()) using (var usage = ContextFactory.GetForWrite())
{ {
// compare counts in database vs defaults // compare counts in database vs defaults
foreach (var group in defaults.GroupBy(k => k.Action)) foreach (var group in defaults.GroupBy(k => k.Action))
{ {
int count = query(rulesetId, variant).Count(k => (int)k.KeyBinding.Action == (int)group.Key); int count = query(rulesetId, variant).Count(k => k.Action == (int)group.Key);
int aimCount = group.Count(); int aimCount = group.Count();
if (aimCount <= count) if (aimCount <= count)
@ -87,32 +87,26 @@ namespace osu.Game.Input
/// <param name="rulesetId">The ruleset's internal ID.</param> /// <param name="rulesetId">The ruleset's internal ID.</param>
/// <param name="variant">An optional variant.</param> /// <param name="variant">An optional variant.</param>
/// <returns></returns> /// <returns></returns>
private List<RealmKeyBinding> query(int? rulesetId = null, int? variant = null) => private IQueryable<RealmKeyBinding> query(int? rulesetId = null, int? variant = null) =>
ContextFactory.Get().All<RealmKeyBinding>().Where(b => b.RulesetID == rulesetId && b.Variant == variant).ToList(); ContextFactory.Get().All<RealmKeyBinding>().Where(b => b.RulesetID == rulesetId && b.Variant == variant);
public List<KeyBinding> Query(int? rulesetId = null, int? variant = null) public List<IKeyBinding> Query(int? rulesetId = null, int? variant = null)
=> query(rulesetId, variant).Select(k => k.KeyBinding).ToList(); => query(rulesetId, variant).ToList().Select(r => r.Detach()).ToList<IKeyBinding>();
public List<KeyBinding> Query<T>(T action) public List<IKeyBinding> Query<T>(T action)
where T : Enum where T : Enum
{ {
int lookup = (int)(object)action; int lookup = (int)(object)action;
return query(null, null).Where(rkb => rkb.Action == lookup).Select(k => k.KeyBinding).ToList(); return query(null, null).Where(rkb => rkb.Action == lookup).ToList().Select(r => r.Detach()).ToList<IKeyBinding>();
} }
public void Update(KeyBinding keyBinding) public void Update(IHasGuidPrimaryKey keyBinding, Action<IKeyBinding> modification)
{ {
using (ContextFactory.GetForWrite()) using (var realm = ContextFactory.GetForWrite())
{ {
//todo: fix var realmKeyBinding = realm.Context.Find<RealmKeyBinding>(keyBinding.ID);
// var dbKeyBinding = (RealmKeyBinding)keyBinding; modification(realmKeyBinding);
// Refresh(ref dbKeyBinding);
//
// if (dbKeyBinding.KeyCombination.Equals(keyBinding.KeyCombination))
// return;
//
// dbKeyBinding.KeyCombination = keyBinding.KeyCombination;
} }
KeyBindingChanged?.Invoke(); KeyBindingChanged?.Invoke();

View File

@ -12,6 +12,7 @@ using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Database;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
@ -25,7 +26,7 @@ namespace osu.Game.Overlays.KeyBinding
public class KeyBindingRow : Container, IFilterable public class KeyBindingRow : Container, IFilterable
{ {
private readonly object action; private readonly object action;
private readonly IEnumerable<Framework.Input.Bindings.KeyBinding> bindings; private readonly IEnumerable<IKeyBinding> bindings;
private const float transition_time = 150; private const float transition_time = 150;
@ -53,7 +54,7 @@ namespace osu.Game.Overlays.KeyBinding
public IEnumerable<string> FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend((string)text.Text); public IEnumerable<string> FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend((string)text.Text);
public KeyBindingRow(object action, IEnumerable<Framework.Input.Bindings.KeyBinding> bindings) public KeyBindingRow(object action, IEnumerable<IKeyBinding> bindings)
{ {
this.action = action; this.action = action;
this.bindings = bindings; this.bindings = bindings;
@ -126,7 +127,7 @@ namespace osu.Game.Overlays.KeyBinding
{ {
var button = buttons[i++]; var button = buttons[i++];
button.UpdateKeyCombination(d); button.UpdateKeyCombination(d);
store.Update(button.KeyBinding); store.Update((IHasGuidPrimaryKey)button.KeyBinding, k => k.KeyCombination = button.KeyBinding.KeyCombination);
} }
} }
@ -285,7 +286,7 @@ namespace osu.Game.Overlays.KeyBinding
{ {
if (bindTarget != null) if (bindTarget != null)
{ {
store.Update(bindTarget.KeyBinding); store.Update((IHasGuidPrimaryKey)bindTarget.KeyBinding, k => k.KeyCombination = bindTarget.KeyBinding.KeyCombination);
bindTarget.IsBinding = false; bindTarget.IsBinding = false;
Schedule(() => Schedule(() =>
@ -359,7 +360,7 @@ namespace osu.Game.Overlays.KeyBinding
public class KeyButton : Container public class KeyButton : Container
{ {
public readonly Framework.Input.Bindings.KeyBinding KeyBinding; public readonly IKeyBinding KeyBinding;
private readonly Box box; private readonly Box box;
public readonly OsuSpriteText Text; public readonly OsuSpriteText Text;
@ -381,7 +382,7 @@ namespace osu.Game.Overlays.KeyBinding
} }
} }
public KeyButton(Framework.Input.Bindings.KeyBinding keyBinding) public KeyButton(IKeyBinding keyBinding)
{ {
KeyBinding = keyBinding; KeyBinding = keyBinding;