mirror of
https://github.com/ppy/osu.git
synced 2025-03-15 17:47:18 +08:00
Use DI to provide dependencies for KPS Calculator and improve input
gathering KPS Calculator now uses DI to retrieve the clocks. Using `HUDOverlay` it is now cached for `KeysPerSecondCounter`s to resolve it. This also allows to make an "Attach" flow like `KeyCounter`.
This commit is contained in:
parent
b2557a8d2d
commit
b52a07c16a
@ -30,6 +30,7 @@ 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.KPSCounter;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
@ -38,7 +39,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// Displays an interactive ruleset gameplay instance.
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject">The type of HitObject contained by this DrawableRuleset.</typeparam>
|
||||
public abstract class DrawableRuleset<TObject> : DrawableRuleset, IProvideCursor, ICanAttachKeyCounter
|
||||
public abstract class DrawableRuleset<TObject> : DrawableRuleset, IProvideCursor, ICanAttachKeyCounter, ICanAttachKpsCalculator
|
||||
where TObject : HitObject
|
||||
{
|
||||
public override event Action<JudgementResult> NewResult;
|
||||
@ -340,6 +341,8 @@ namespace osu.Game.Rulesets.UI
|
||||
public void Attach(KeyCounterDisplay keyCounter) =>
|
||||
(KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(keyCounter);
|
||||
|
||||
public void Attach(KeysPerSecondCalculator kps) => (KeyBindingInputManager as ICanAttachKpsCalculator)?.Attach(kps);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a key conversion input manager. An exception will be thrown if a valid <see cref="RulesetInputManager{T}"/> is not returned.
|
||||
/// </summary>
|
||||
|
@ -20,11 +20,12 @@ using osu.Game.Input.Bindings;
|
||||
using osu.Game.Input.Handlers;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD.KPSCounter;
|
||||
using static osu.Game.Input.Handlers.ReplayInputHandler;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
public abstract class RulesetInputManager<T> : PassThroughInputManager, ICanAttachKeyCounter, IHasReplayHandler, IHasRecordingHandler
|
||||
public abstract class RulesetInputManager<T> : PassThroughInputManager, ICanAttachKeyCounter, IHasReplayHandler, IHasRecordingHandler, ICanAttachKpsCalculator
|
||||
where T : struct
|
||||
{
|
||||
public readonly KeyBindingContainer<T> KeyBindingContainer;
|
||||
@ -186,6 +187,35 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
#endregion
|
||||
|
||||
#region KPS Counter Attachment
|
||||
|
||||
public void Attach(KeysPerSecondCalculator kps)
|
||||
{
|
||||
var listener = new ActionListener();
|
||||
|
||||
KeyBindingContainer.Add(listener);
|
||||
|
||||
kps.Listener = listener;
|
||||
}
|
||||
|
||||
public class ActionListener : KeysPerSecondCalculator.InputListener, IKeyBindingHandler<T>
|
||||
{
|
||||
public override event Action OnNewInput;
|
||||
|
||||
public bool OnPressed(KeyBindingPressEvent<T> e)
|
||||
{
|
||||
OnNewInput?.Invoke();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnReleased(KeyBindingReleaseEvent<T> e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected virtual KeyBindingContainer<T> CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
||||
=> new RulesetKeyBindingContainer(ruleset, variant, unique);
|
||||
|
||||
@ -229,6 +259,11 @@ namespace osu.Game.Rulesets.UI
|
||||
void Attach(KeyCounterDisplay keyCounter);
|
||||
}
|
||||
|
||||
public interface ICanAttachKpsCalculator
|
||||
{
|
||||
void Attach(KeysPerSecondCalculator keysPerSecondCalculator);
|
||||
}
|
||||
|
||||
public class RulesetInputManagerInputState<T> : InputState
|
||||
where T : struct
|
||||
{
|
||||
|
@ -4,55 +4,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Screens.Play.HUD.KPSCounter
|
||||
{
|
||||
public class KeysPerSecondCalculator
|
||||
public class KeysPerSecondCalculator : Component
|
||||
{
|
||||
public static void AddInput()
|
||||
{
|
||||
onNewInput?.Invoke();
|
||||
}
|
||||
|
||||
private readonly List<double> timestamps;
|
||||
private GameplayClock? gameplayClock;
|
||||
private DrawableRuleset? drawableRuleset;
|
||||
|
||||
public GameplayClock? GameplayClock
|
||||
private InputListener? listener;
|
||||
|
||||
[Resolved]
|
||||
private GameplayClock? gameplayClock { get; set; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private DrawableRuleset? drawableRuleset { get; set; }
|
||||
|
||||
public InputListener Listener
|
||||
{
|
||||
get => gameplayClock;
|
||||
set
|
||||
{
|
||||
onResetRequested?.Invoke();
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
gameplayClock = value;
|
||||
}
|
||||
listener = value;
|
||||
listener.OnNewInput += addTimestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public DrawableRuleset? DrawableRuleset
|
||||
{
|
||||
get => drawableRuleset;
|
||||
set
|
||||
{
|
||||
onResetRequested?.Invoke();
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
drawableRuleset = value;
|
||||
baseRate = (drawableRuleset.Mods.FirstOrDefault(m => m is ModRateAdjust) as ModRateAdjust)?.SpeedChange.Value
|
||||
?? 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static event Action? onNewInput;
|
||||
private static event Action? onResetRequested;
|
||||
private event Action? onResetRequested;
|
||||
|
||||
private IClock? workingClock => drawableRuleset?.FrameStableClock;
|
||||
|
||||
@ -81,8 +62,8 @@ namespace osu.Game.Screens.Play.HUD.KPSCounter
|
||||
|
||||
public KeysPerSecondCalculator()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
timestamps = new List<double>();
|
||||
onNewInput += addTimestamp;
|
||||
onResetRequested += cleanUp;
|
||||
}
|
||||
|
||||
@ -90,6 +71,9 @@ namespace osu.Game.Screens.Play.HUD.KPSCounter
|
||||
{
|
||||
timestamps.Clear();
|
||||
maxTime = double.NegativeInfinity;
|
||||
|
||||
if (listener != null)
|
||||
listener.OnNewInput -= addTimestamp;
|
||||
}
|
||||
|
||||
private void addTimestamp()
|
||||
@ -111,5 +95,21 @@ namespace osu.Game.Screens.Play.HUD.KPSCounter
|
||||
double relativeTime = workingClock.CurrentTime - timestamp;
|
||||
return relativeTime >= 0 && relativeTime <= span;
|
||||
}
|
||||
|
||||
~KeysPerSecondCalculator()
|
||||
{
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
public abstract class InputListener : Component
|
||||
{
|
||||
protected InputListener()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Depth = float.MinValue;
|
||||
}
|
||||
|
||||
public abstract event Action? OnNewInput;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,21 +22,15 @@ namespace osu.Game.Screens.Play.HUD.KPSCounter
|
||||
|
||||
private readonly Bindable<bool> valid = new Bindable<bool>();
|
||||
|
||||
private static readonly KeysPerSecondCalculator calculator = new KeysPerSecondCalculator();
|
||||
|
||||
[Resolved]
|
||||
private GameplayClock? gameplayClock
|
||||
{
|
||||
get => calculator.GameplayClock;
|
||||
set => calculator.GameplayClock = value;
|
||||
}
|
||||
private KeysPerSecondCalculator? calculator { get; set; }
|
||||
|
||||
// This is to force the skin editor to show the component only in a Gameplay context
|
||||
[Resolved]
|
||||
private GameplayClock? gameplayClock { get; set; }
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private DrawableRuleset? drawableRuleset
|
||||
{
|
||||
get => calculator.DrawableRuleset;
|
||||
set => calculator.DrawableRuleset = value;
|
||||
}
|
||||
private DrawableRuleset? drawableRuleset { get; set; }
|
||||
|
||||
protected override double RollingDuration => 350;
|
||||
|
||||
@ -59,8 +53,8 @@ namespace osu.Game.Screens.Play.HUD.KPSCounter
|
||||
{
|
||||
base.Update();
|
||||
|
||||
valid.Value = calculator.Ready;
|
||||
Current.Value = calculator.Ready ? calculator.Value : 0;
|
||||
valid.Value = calculator != null && calculator.Ready;
|
||||
Current.Value = calculator != null ? calculator.Ready ? calculator.Value : 0 : 0;
|
||||
}
|
||||
|
||||
protected override IHasText CreateText() => new TextComponent
|
||||
|
@ -22,6 +22,7 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.HUD.KPSCounter;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
@ -49,6 +50,9 @@ namespace osu.Game.Screens.Play
|
||||
public readonly HoldForMenuButton HoldToQuit;
|
||||
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
||||
|
||||
[Cached]
|
||||
private readonly KeysPerSecondCalculator keysPerSecondCalculator;
|
||||
|
||||
public Bindable<bool> ShowHealthBar = new Bindable<bool>(true);
|
||||
|
||||
private readonly DrawableRuleset drawableRuleset;
|
||||
@ -122,7 +126,8 @@ namespace osu.Game.Screens.Play
|
||||
KeyCounter = CreateKeyCounter(),
|
||||
HoldToQuit = CreateHoldForMenuButton(),
|
||||
}
|
||||
}
|
||||
},
|
||||
keysPerSecondCalculator = new KeysPerSecondCalculator()
|
||||
};
|
||||
}
|
||||
|
||||
@ -260,6 +265,7 @@ namespace osu.Game.Screens.Play
|
||||
protected virtual void BindDrawableRuleset(DrawableRuleset drawableRuleset)
|
||||
{
|
||||
(drawableRuleset as ICanAttachKeyCounter)?.Attach(KeyCounter);
|
||||
(drawableRuleset as ICanAttachKpsCalculator)?.Attach(keysPerSecondCalculator);
|
||||
|
||||
replayLoaded.BindTo(drawableRuleset.HasReplayLoaded);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Screens.Play.HUD.KPSCounter;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -56,7 +55,6 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public void Increment()
|
||||
{
|
||||
KeysPerSecondCalculator.AddInput();
|
||||
if (!IsCounting)
|
||||
return;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user