diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs
index e0a1533c4b..57f5f54d8f 100644
--- a/osu.Game/Rulesets/UI/DrawableRuleset.cs
+++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs
@@ -30,6 +30,8 @@ using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Screens.Play;
+using osu.Game.Screens.Play.HUD;
+using osu.Game.Screens.Play.HUD.ClicksPerSecond;
using osuTK;
namespace osu.Game.Rulesets.UI
@@ -38,7 +40,7 @@ namespace osu.Game.Rulesets.UI
/// Displays an interactive ruleset gameplay instance.
///
/// The type of HitObject contained by this DrawableRuleset.
- public abstract partial class DrawableRuleset : DrawableRuleset, IProvideCursor, IKeybindingEventsEmitter
+ public abstract partial class DrawableRuleset : DrawableRuleset, IProvideCursor, ICanAttachHUDPieces
where TObject : HitObject
{
public override event Action NewResult;
@@ -327,8 +329,11 @@ namespace osu.Game.Rulesets.UI
/// The representing .
public abstract DrawableHitObject CreateDrawableRepresentation(TObject h);
- public void Attach(IKeybindingListener skinComponent) =>
- (KeyBindingInputManager as IKeybindingEventsEmitter)?.Attach(skinComponent);
+ public void Attach(KeyCounterController keyCounter) =>
+ (KeyBindingInputManager as ICanAttachHUDPieces)?.Attach(keyCounter);
+
+ public void Attach(ClicksPerSecondCalculator calculator) =>
+ (KeyBindingInputManager as ICanAttachHUDPieces)?.Attach(calculator);
///
/// Creates a key conversion input manager. An exception will be thrown if a valid is not returned.
diff --git a/osu.Game/Rulesets/UI/IKeybindingListener.cs b/osu.Game/Rulesets/UI/IKeybindingListener.cs
deleted file mode 100644
index f38ce8643e..0000000000
--- a/osu.Game/Rulesets/UI/IKeybindingListener.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-#nullable disable
-using System.Collections.Generic;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Input.Bindings;
-using osu.Framework.Input.Events;
-
-namespace osu.Game.Rulesets.UI
-{
- ///
- /// Listens to events emitted by an .
- /// Alternative to for classes that need to not depend on type parameters.
- ///
- public interface IKeybindingListener
- {
- ///
- /// This class or a member of this class can already handle keybindings.
- /// Signals to the that and
- /// don't necessarily need to be called.
- ///
- ///
- /// This is usually true for s and s that need to
- /// pass s events to children that can already handle them.
- ///
- public bool CanHandleKeybindings { get; }
-
- ///
- /// Prepares this class to receive events.
- ///
- /// The list of possible actions that can occur.
- /// The type actions, commonly enums.
- public void Setup(IEnumerable actions) where T : struct;
-
- ///
- /// Called when an action is pressed.
- ///
- /// The event containing information about the pressed action.
- /// The type of binding, commonly enums.
- public void OnPressed(KeyBindingPressEvent action) where T : struct;
-
- ///
- /// Called when an action is released.
- ///
- /// The event containing information about the released action.
- /// The type of binding, commonly enums.
- public void OnReleased(KeyBindingReleaseEvent action) where T : struct;
- }
-}
diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs
index 44c1f00cf7..2c403139b6 100644
--- a/osu.Game/Rulesets/UI/RulesetInputManager.cs
+++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs
@@ -19,11 +19,13 @@ using osu.Game.Input;
using osu.Game.Input.Bindings;
using osu.Game.Input.Handlers;
using osu.Game.Rulesets.Scoring;
+using osu.Game.Screens.Play.HUD;
+using osu.Game.Screens.Play.HUD.ClicksPerSecond;
using static osu.Game.Input.Handlers.ReplayInputHandler;
namespace osu.Game.Rulesets.UI
{
- public abstract partial class RulesetInputManager : PassThroughInputManager, IKeybindingEventsEmitter, IHasReplayHandler, IHasRecordingHandler
+ public abstract partial class RulesetInputManager : PassThroughInputManager, ICanAttachHUDPieces, IHasReplayHandler, IHasRecordingHandler
where T : struct
{
protected override bool AllowRightClickFromLongTouch => false;
@@ -64,7 +66,6 @@ namespace osu.Game.Rulesets.UI
InternalChild = KeyBindingContainer =
CreateKeyBindingContainer(ruleset, variant, unique)
.WithChild(content = new Container { RelativeSizeAxes = Axes.Both });
- KeyBindingContainer.Add(actionListener = new ActionListener());
}
[BackgroundDependencyLoader(true)]
@@ -157,49 +158,47 @@ namespace osu.Game.Rulesets.UI
#endregion
- #region Component attachement
+ #region Key Counter Attachment
- private readonly ActionListener actionListener;
-
- public void Attach(IKeybindingListener skinComponent)
+ public void Attach(KeyCounterController keyCounter)
{
- skinComponent.Setup(KeyBindingContainer.DefaultKeyBindings
+ KeyBindingContainer.Add(keyCounter);
+
+ keyCounter.AddRange(KeyBindingContainer.DefaultKeyBindings
.Select(b => b.GetAction())
.Distinct()
- .OrderBy(a => a));
+ .OrderBy(action => action)
+ .Select(action => new KeyCounterActionTrigger(action)));
+ }
- if (skinComponent.CanHandleKeybindings && skinComponent is Drawable component)
- {
- try
- {
- KeyBindingContainer.Add(component);
- return;
- }
- catch (Exception)
- {
- return;
- }
- }
+ #endregion
- actionListener.OnPressedEvent += skinComponent.OnPressed;
- actionListener.OnReleasedEvent += skinComponent.OnReleased;
+ #region Keys per second Counter Attachment
+
+ public void Attach(ClicksPerSecondCalculator calculator)
+ {
+ var listener = new ActionListener(calculator);
+
+ KeyBindingContainer.Add(listener);
}
private partial class ActionListener : Component, IKeyBindingHandler
{
- public event Action> OnPressedEvent;
+ private readonly ClicksPerSecondCalculator calculator;
- public event Action> OnReleasedEvent;
+ public ActionListener(ClicksPerSecondCalculator calculator)
+ {
+ this.calculator = calculator;
+ }
public bool OnPressed(KeyBindingPressEvent e)
{
- OnPressedEvent?.Invoke(e);
+ calculator.AddInputTimestamp();
return false;
}
public void OnReleased(KeyBindingReleaseEvent e)
{
- OnReleasedEvent?.Invoke(e);
}
}
@@ -240,11 +239,17 @@ namespace osu.Game.Rulesets.UI
}
///
- /// Sends events to a
+ /// Supports attaching various HUD pieces.
+ /// Keys will be populated automatically and a receptor will be injected inside.
///
- public interface IKeybindingEventsEmitter
+ public interface ICanAttachHUDPieces
+ {
+ void Attach(KeyCounterController keyCounter);
+ void Attach(ClicksPerSecondCalculator calculator);
+ }
+
+ public interface IAttachableSkinComponent
{
- void Attach(IKeybindingListener component);
}
public class RulesetInputManagerInputState : InputState
diff --git a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs
index e0e93cb66e..3e55e11f1c 100644
--- a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs
+++ b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs
@@ -4,12 +4,11 @@
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
-using osu.Framework.Input.Events;
using osu.Game.Rulesets.UI;
namespace osu.Game.Screens.Play.HUD.ClicksPerSecond
{
- public partial class ClicksPerSecondCalculator : Component, IKeybindingListener
+ public partial class ClicksPerSecondCalculator : Component, IAttachableSkinComponent
{
private readonly List timestamps = new List();
@@ -54,21 +53,5 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond
Value = count;
}
-
- #region IKeybindingListener
-
- bool IKeybindingListener.CanHandleKeybindings => false;
-
- void IKeybindingListener.Setup(IEnumerable actions)
- {
- }
-
- void IKeybindingListener.OnPressed(KeyBindingPressEvent action) => AddInputTimestamp();
-
- void IKeybindingListener.OnReleased(KeyBindingReleaseEvent action)
- {
- }
-
- #endregion
}
}
diff --git a/osu.Game/Screens/Play/HUD/KeyCounterController.cs b/osu.Game/Screens/Play/HUD/KeyCounterController.cs
index 2e678e55fc..0fa02afbb4 100644
--- a/osu.Game/Screens/Play/HUD/KeyCounterController.cs
+++ b/osu.Game/Screens/Play/HUD/KeyCounterController.cs
@@ -3,16 +3,14 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Input.Events;
using osu.Game.Rulesets.UI;
namespace osu.Game.Screens.Play.HUD
{
- public partial class KeyCounterController : CompositeComponent, IKeybindingListener
+ public partial class KeyCounterController : CompositeComponent, IAttachableSkinComponent
{
public readonly Bindable IsCounting = new BindableBool(true);
@@ -38,22 +36,5 @@ namespace osu.Game.Screens.Play.HUD
public override bool HandleNonPositionalInput => true;
public override bool HandlePositionalInput => true;
-
- #region IKeybindingListener
-
- bool IKeybindingListener.CanHandleKeybindings => true;
-
- void IKeybindingListener.Setup(IEnumerable actions)
- => AddRange(actions.Select(a => new KeyCounterActionTrigger(a)));
-
- void IKeybindingListener.OnPressed(KeyBindingPressEvent action)
- {
- }
-
- void IKeybindingListener.OnReleased(KeyBindingReleaseEvent action)
- {
- }
-
- #endregion
}
}
diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs
index b74b5d835a..21636ac04c 100644
--- a/osu.Game/Screens/Play/HUDOverlay.cs
+++ b/osu.Game/Screens/Play/HUDOverlay.cs
@@ -10,7 +10,6 @@ using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.EnumExtensions;
-using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Bindings;
@@ -103,8 +102,6 @@ namespace osu.Game.Screens.Play
private readonly List hideTargets;
- private readonly IEnumerable actionInjectionCandidates;
-
public HUDOverlay(DrawableRuleset drawableRuleset, IReadOnlyList mods, bool alwaysShowLeaderboard = true)
{
Drawable rulesetComponents;
@@ -166,8 +163,6 @@ namespace osu.Game.Screens.Play
hideTargets = new List { mainComponents, rulesetComponents, topRightElements };
- actionInjectionCandidates = new IKeybindingListener[] { clicksPerSecondCalculator, KeyCounter };
-
if (!alwaysShowLeaderboard)
hideTargets.Add(LeaderboardFlow);
}
@@ -324,8 +319,11 @@ namespace osu.Game.Screens.Play
protected virtual void BindDrawableRuleset(DrawableRuleset drawableRuleset)
{
- if (drawableRuleset is IKeybindingEventsEmitter attachTarget)
- actionInjectionCandidates.ForEach(attachTarget.Attach);
+ if (drawableRuleset is ICanAttachHUDPieces attachTarget)
+ {
+ attachTarget.Attach(KeyCounter);
+ attachTarget.Attach(clicksPerSecondCalculator);
+ }
replayLoaded.BindTo(drawableRuleset.HasReplayLoaded);
}