diff --git a/osu.Game/Screens/Utility/CircleGameplay.cs b/osu.Game/Screens/Utility/CircleGameplay.cs index c55c10dcb8..bc3342fa3f 100644 --- a/osu.Game/Screens/Utility/CircleGameplay.cs +++ b/osu.Game/Screens/Utility/CircleGameplay.cs @@ -8,13 +8,14 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osu.Framework.Input.States; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; +using osu.Game.Screens.Utility.SampleComponents; using osuTK; using osuTK.Graphics; @@ -141,7 +142,7 @@ namespace osu.Game.Screens.Utility unstableRate.Text = $"{hitEvents.CalculateUnstableRate():N1}"; } - public class SampleHitCircle : CompositeDrawable + public class SampleHitCircle : LatencySampleComponent { public HitEvent? HitEvent; @@ -198,6 +199,8 @@ namespace osu.Game.Screens.Utility }; } + protected override bool OnHover(HoverEvent e) => true; + protected override bool OnMouseDown(MouseDownEvent e) { if (HitEvent != null) @@ -206,6 +209,37 @@ namespace osu.Game.Screens.Utility if (Math.Abs(Clock.CurrentTime - HitTime) > 200) return false; + attemptHit(); + return true; + } + + protected override bool OnKeyDown(KeyDownEvent e) + { + if (!IsActive.Value) + return false; + + if (IsHovered) + attemptHit(); + return base.OnKeyDown(e); + } + + protected override void UpdateAtLimitedRate(InputState inputState) + { + if (HitEvent == null) + { + approach.Scale = new Vector2(1 + (float)MathHelper.Clamp((HitTime - Clock.CurrentTime) / approach_rate_milliseconds.Value, 0, 100)); + Alpha = (float)MathHelper.Clamp((Clock.CurrentTime - HitTime + 600) / 400, 0, 1); + + if (Clock.CurrentTime > HitTime + 200) + Expire(); + } + } + + private void attemptHit() => Schedule(() => + { + if (HitEvent != null) + return; + approach.Expire(); circle @@ -220,23 +254,7 @@ namespace osu.Game.Screens.Utility Hit?.Invoke(HitEvent.Value); this.Delay(200).Expire(); - - return true; - } - - protected override void Update() - { - base.Update(); - - if (HitEvent == null) - { - approach.Scale = new Vector2(1 + (float)MathHelper.Clamp((HitTime - Clock.CurrentTime) / approach_rate_milliseconds.Value, 0, 100)); - Alpha = (float)MathHelper.Clamp((Clock.CurrentTime - HitTime + 600) / 400, 0, 1); - - if (Clock.CurrentTime > HitTime + 200) - Expire(); - } - } + }); } } } diff --git a/osu.Game/Screens/Utility/LatencyArea.cs b/osu.Game/Screens/Utility/LatencyArea.cs index 5b48a10a49..21688f0b0c 100644 --- a/osu.Game/Screens/Utility/LatencyArea.cs +++ b/osu.Game/Screens/Utility/LatencyArea.cs @@ -16,6 +16,7 @@ using osuTK.Input; namespace osu.Game.Screens.Utility { + [Cached] public class LatencyArea : CompositeDrawable { [Resolved] @@ -82,11 +83,11 @@ namespace osu.Game.Screens.Utility case LatencyVisualMode.Simple: visualContent.Children = new Drawable[] { - new LatencyMovableBox(IsActiveArea) + new LatencyMovableBox { RelativeSizeAxes = Axes.Both, }, - new LatencyCursorContainer(IsActiveArea) + new LatencyCursorContainer { RelativeSizeAxes = Axes.Both, }, @@ -100,7 +101,7 @@ namespace osu.Game.Screens.Utility { RelativeSizeAxes = Axes.Both, }, - new LatencyCursorContainer(IsActiveArea) + new LatencyCursorContainer { RelativeSizeAxes = Axes.Both, }, @@ -114,7 +115,7 @@ namespace osu.Game.Screens.Utility { RelativeSizeAxes = Axes.Both, }, - new LatencyCursorContainer(IsActiveArea) + new LatencyCursorContainer { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game/Screens/Utility/SampleComponents/LatencyCursorContainer.cs b/osu.Game/Screens/Utility/SampleComponents/LatencyCursorContainer.cs index 753310c3b3..e4c2b504cb 100644 --- a/osu.Game/Screens/Utility/SampleComponents/LatencyCursorContainer.cs +++ b/osu.Game/Screens/Utility/SampleComponents/LatencyCursorContainer.cs @@ -3,31 +3,25 @@ #nullable enable using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; using osu.Framework.Input.Events; +using osu.Framework.Input.States; using osu.Game.Overlays; using osuTK; using osuTK.Input; namespace osu.Game.Screens.Utility.SampleComponents { - public class LatencyCursorContainer : CompositeDrawable + public class LatencyCursorContainer : LatencySampleComponent { private Circle cursor = null!; - private InputManager inputManager = null!; - - private readonly BindableBool isActive; [Resolved] private OverlayColourProvider overlayColourProvider { get; set; } = null!; - public LatencyCursorContainer(BindableBool isActive) + public LatencyCursorContainer() { - this.isActive = isActive; Masking = true; } @@ -41,27 +35,23 @@ namespace osu.Game.Screens.Utility.SampleComponents Origin = Anchor.Centre, Colour = overlayColourProvider.Colour2, }; - - inputManager = GetContainingInputManager(); } protected override bool OnHover(HoverEvent e) => false; - protected override void Update() + protected override void UpdateAtLimitedRate(InputState inputState) { - cursor.Colour = inputManager.CurrentState.Mouse.IsPressed(MouseButton.Left) ? overlayColourProvider.Content1 : overlayColourProvider.Colour2; + cursor.Colour = inputState.Mouse.IsPressed(MouseButton.Left) ? overlayColourProvider.Content1 : overlayColourProvider.Colour2; - if (isActive.Value) + if (IsActive.Value) { - cursor.Position = ToLocalSpace(inputManager.CurrentState.Mouse.Position); + cursor.Position = ToLocalSpace(inputState.Mouse.Position); cursor.Alpha = 1; } else { cursor.Alpha = 0; } - - base.Update(); } } } diff --git a/osu.Game/Screens/Utility/SampleComponents/LatencyMovableBox.cs b/osu.Game/Screens/Utility/SampleComponents/LatencyMovableBox.cs index 418d45489f..56c8aa2ed5 100644 --- a/osu.Game/Screens/Utility/SampleComponents/LatencyMovableBox.cs +++ b/osu.Game/Screens/Utility/SampleComponents/LatencyMovableBox.cs @@ -2,47 +2,31 @@ // See the LICENCE file in the repository root for full licence text. #nullable enable -using osu.Framework.Allocation; -using osu.Framework.Bindables; + using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; using osu.Framework.Input.Events; -using osu.Game.Overlays; +using osu.Framework.Input.States; using osuTK; using osuTK.Input; namespace osu.Game.Screens.Utility.SampleComponents { - public class LatencyMovableBox : CompositeDrawable + public class LatencyMovableBox : LatencySampleComponent { private Box box = null!; - private InputManager inputManager = null!; - - private readonly BindableBool isActive; - - [Resolved] - private OverlayColourProvider overlayColourProvider { get; set; } = null!; - - public LatencyMovableBox(BindableBool isActive) - { - this.isActive = isActive; - } protected override void LoadComplete() { base.LoadComplete(); - inputManager = GetContainingInputManager(); - InternalChild = box = new Box { Size = new Vector2(40), RelativePositionAxes = Axes.Both, Position = new Vector2(0.5f), Origin = Anchor.Centre, - Colour = overlayColourProvider.Colour1, + Colour = OverlayColourProvider.Colour1, }; } @@ -50,14 +34,12 @@ namespace osu.Game.Screens.Utility.SampleComponents private double? lastFrameTime; - protected override void Update() + protected override void UpdateAtLimitedRate(InputState inputState) { - base.Update(); - - if (!isActive.Value) + if (!IsActive.Value) { lastFrameTime = null; - box.Colour = overlayColourProvider.Colour1; + box.Colour = OverlayColourProvider.Colour1; return; } @@ -65,9 +47,9 @@ namespace osu.Game.Screens.Utility.SampleComponents { float movementAmount = (float)(Clock.CurrentTime - lastFrameTime) / 400; - var buttons = inputManager.CurrentState.Keyboard.Keys; + var buttons = inputState.Keyboard.Keys; - box.Colour = buttons.HasAnyButtonPressed ? overlayColourProvider.Content1 : overlayColourProvider.Colour1; + box.Colour = buttons.HasAnyButtonPressed ? OverlayColourProvider.Content1 : OverlayColourProvider.Colour1; foreach (var key in buttons) { diff --git a/osu.Game/Screens/Utility/SampleComponents/LatencySampleComponent.cs b/osu.Game/Screens/Utility/SampleComponents/LatencySampleComponent.cs new file mode 100644 index 0000000000..03f6b46852 --- /dev/null +++ b/osu.Game/Screens/Utility/SampleComponents/LatencySampleComponent.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable enable + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Framework.Input.States; +using osu.Game.Overlays; + +namespace osu.Game.Screens.Utility.SampleComponents +{ + public abstract class LatencySampleComponent : CompositeDrawable + { + protected readonly BindableBool IsActive = new BindableBool(); + + private InputManager inputManager = null!; + + [Resolved] + private LatencyArea latencyArea { get; set; } = null!; + + [Resolved] + protected OverlayColourProvider OverlayColourProvider { get; private set; } = null!; + + protected override void LoadComplete() + { + base.LoadComplete(); + + inputManager = GetContainingInputManager(); + IsActive.BindTo(latencyArea.IsActiveArea); + } + + protected sealed override void Update() + { + base.Update(); + UpdateAtLimitedRate(inputManager.CurrentState); + } + + protected abstract void UpdateAtLimitedRate(InputState inputState); + } +}