From 756dbadd6520262f3e150e1bcefa77b1bd7bc4b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Jun 2017 15:22:04 +0900 Subject: [PATCH 1/5] Fix various cases of mouse delta values being incorrect --- .../Handlers/Mouse/OpenTKEventMouseState.cs | 15 +++++++++++++++ .../Input/Handlers/Mouse/OpenTKMouseHandler.cs | 17 +++++++++-------- .../Input/Handlers/Mouse/OpenTKMouseState.cs | 4 ++-- .../Handlers/Mouse/OpenTKPollMouseState.cs | 15 +++++++++++++++ .../Handlers/Mouse/OpenTKRawMouseHandler.cs | 13 +++++++++---- .../osu.Framework.Desktop.csproj | 2 ++ osu.Framework/Input/InputManager.cs | 6 +++++- osu.Framework/Input/MouseState.cs | 10 +++++----- 8 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKEventMouseState.cs create mode 100644 osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKPollMouseState.cs diff --git a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKEventMouseState.cs b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKEventMouseState.cs new file mode 100644 index 0000000000..1874024769 --- /dev/null +++ b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKEventMouseState.cs @@ -0,0 +1,15 @@ +using OpenTK; + +namespace osu.Framework.Desktop.Input.Handlers.Mouse +{ + /// + /// An OpenTK state which came from an event callback. + /// + internal class OpenTKEventMouseState : OpenTKMouseState + { + public OpenTKEventMouseState(OpenTK.Input.MouseState tkState, bool active, Vector2? mappedPosition) + : base(tkState, active, mappedPosition) + { + } + } +} \ No newline at end of file diff --git a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKMouseHandler.cs b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKMouseHandler.cs index 2a3780dee2..d35bbf5d78 100644 --- a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKMouseHandler.cs +++ b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKMouseHandler.cs @@ -44,9 +44,14 @@ public override bool Initialize(GameHost host) if (mouseInWindow || !host.Window.Visible) return; var state = OpenTK.Input.Mouse.GetCursorState(); + + if (state.Equals(lastState)) return; + + lastState = state; + var mapped = host.Window.PointToClient(new Point(state.X, state.Y)); - handleState(state, new Vector2(mapped.X, mapped.Y)); + handleState(new OpenTKPollMouseState(state, host.IsActive, new Vector2(mapped.X, mapped.Y))); }, 0, 1000.0 / 60)); } else @@ -70,16 +75,12 @@ private void handleMouseEvent(object sender, MouseEventArgs e) if (!mouseInWindow) return; - handleState(e.Mouse); + handleState(new OpenTKEventMouseState(e.Mouse, host.IsActive, null)); } - private void handleState(OpenTK.Input.MouseState state, Vector2? mappedPosition = null) + private void handleState(MouseState state) { - if (state.Equals(lastState)) return; - - lastState = state; - - PendingStates.Enqueue(new InputState { Mouse = new OpenTKMouseState(state, host.IsActive, mappedPosition) }); + PendingStates.Enqueue(new InputState { Mouse = state }); FrameStatistics.Increment(StatisticsCounterType.MouseEvents); } diff --git a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKMouseState.cs b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKMouseState.cs index 630ed9e553..c44e342a5c 100644 --- a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKMouseState.cs +++ b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKMouseState.cs @@ -7,13 +7,13 @@ namespace osu.Framework.Desktop.Input.Handlers.Mouse { - internal class OpenTKMouseState : MouseState + internal abstract class OpenTKMouseState : MouseState { public readonly bool WasActive; public override int WheelDelta => WasActive ? base.WheelDelta : 0; - public OpenTKMouseState(OpenTK.Input.MouseState tkState, bool active, Vector2? mappedPosition) + protected OpenTKMouseState(OpenTK.Input.MouseState tkState, bool active, Vector2? mappedPosition) { WasActive = active; diff --git a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKPollMouseState.cs b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKPollMouseState.cs new file mode 100644 index 0000000000..098690227a --- /dev/null +++ b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKPollMouseState.cs @@ -0,0 +1,15 @@ +using OpenTK; + +namespace osu.Framework.Desktop.Input.Handlers.Mouse +{ + /// + /// An OpenTK state which was retrieved via polling. + /// + internal class OpenTKPollMouseState : OpenTKMouseState + { + public OpenTKPollMouseState(OpenTK.Input.MouseState tkState, bool active, Vector2? mappedPosition) + : base(tkState, active, mappedPosition) + { + } + } +} \ No newline at end of file diff --git a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKRawMouseHandler.cs b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKRawMouseHandler.cs index d468571836..58e6788387 100644 --- a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKRawMouseHandler.cs +++ b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKRawMouseHandler.cs @@ -73,13 +73,18 @@ public override bool Initialize(GameHost host) currentPosition = new Vector2(screenPoint.X, screenPoint.Y); } - lastState = state; - // While not focused, let's silently ignore everything but position. - if (!host.Window.Focused) + if (host.Window.Focused) + { + lastState = state; + } + else + { + lastState = null; state = new OpenTK.Input.MouseState(); + } - PendingStates.Enqueue(new InputState { Mouse = new OpenTKMouseState(state, host.IsActive, currentPosition) }); + PendingStates.Enqueue(new InputState { Mouse = new OpenTKPollMouseState(state, host.IsActive, currentPosition) }); FrameStatistics.Increment(StatisticsCounterType.MouseEvents); }, 0, 0)); diff --git a/osu.Framework.Desktop/osu.Framework.Desktop.csproj b/osu.Framework.Desktop/osu.Framework.Desktop.csproj index afce699611..0334286191 100644 --- a/osu.Framework.Desktop/osu.Framework.Desktop.csproj +++ b/osu.Framework.Desktop/osu.Framework.Desktop.csproj @@ -64,6 +64,8 @@ + + diff --git a/osu.Framework/Input/InputManager.cs b/osu.Framework/Input/InputManager.cs index e8315ccbac..fe2ab7cc94 100644 --- a/osu.Framework/Input/InputManager.cs +++ b/osu.Framework/Input/InputManager.cs @@ -186,7 +186,11 @@ protected override void Update() //move above? updateInputQueues(CurrentState); - (s.Mouse as MouseState)?.SetLast(last.Mouse); //necessary for now as last state is used internally for stuff + // we only want to set a last state if both the new and old state are of the same type. + // this avoids giving the new state a false impression of being able to calculate delta values based on a last + // state potentially from a different input source. + if (last.Mouse?.GetType() == s.Mouse?.GetType()) + (s.Mouse as MouseState)?.SetLast(last.Mouse); //necessary for now as last state is used internally for stuff //hover could change even when the mouse state has not. updateHoverEvents(CurrentState); diff --git a/osu.Framework/Input/MouseState.cs b/osu.Framework/Input/MouseState.cs index 718a210894..ccc2af039a 100644 --- a/osu.Framework/Input/MouseState.cs +++ b/osu.Framework/Input/MouseState.cs @@ -10,23 +10,23 @@ namespace osu.Framework.Input { public class MouseState : IMouseState { - public IMouseState LastState; - private const int mouse_button_count = (int)MouseButton.LastButton; public bool[] PressedButtons = new bool[mouse_button_count]; public IMouseState NativeState => this; - public virtual int WheelDelta => Wheel - (LastState?.Wheel ?? 0); + public IMouseState LastState; + + public virtual int WheelDelta => (Wheel - LastState?.Wheel) ?? 0; public int Wheel { get; set; } - public bool HasMainButtonPressed => IsPressed(MouseButton.Left )|| IsPressed(MouseButton.Right); + public bool HasMainButtonPressed => IsPressed(MouseButton.Left) || IsPressed(MouseButton.Right); public bool HasAnyButtonPressed => PressedButtons.Any(b => b); - public Vector2 Delta => Position - (LastState?.Position ?? Vector2.Zero); + public Vector2 Delta => Position - LastPosition; public Vector2 Position { get; protected set; } From eeed2be6e1ad460d72323a895221745648613fb3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Jun 2017 16:40:43 +0900 Subject: [PATCH 2/5] Move LastState to IMouseState --- osu.Framework/Graphics/Drawable.cs | 10 +++++++++- osu.Framework/Input/IMouseState.cs | 4 +++- osu.Framework/Input/InputManager.cs | 9 +++++++-- osu.Framework/Input/MouseState.cs | 13 ++----------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/osu.Framework/Graphics/Drawable.cs b/osu.Framework/Graphics/Drawable.cs index a89444f482..04af3c6b92 100644 --- a/osu.Framework/Graphics/Drawable.cs +++ b/osu.Framework/Graphics/Drawable.cs @@ -1864,11 +1864,14 @@ private struct LocalMouseState : IMouseState { public IMouseState NativeState { get; } + public IMouseState LastState { get; set; } + private readonly Drawable us; public LocalMouseState(IMouseState state, Drawable us) { NativeState = state; + LastState = null; this.us = us; } @@ -1878,7 +1881,12 @@ public LocalMouseState(IMouseState state, Drawable us) public Vector2 LastPosition => us.Parent?.ToLocalSpace(NativeState.LastPosition) ?? NativeState.LastPosition; - public Vector2? PositionMouseDown => NativeState.PositionMouseDown == null ? null : us.Parent?.ToLocalSpace(NativeState.PositionMouseDown.Value) ?? NativeState.PositionMouseDown; + public Vector2? PositionMouseDown + { + get { return NativeState.PositionMouseDown == null ? null : us.Parent?.ToLocalSpace(NativeState.PositionMouseDown.Value) ?? NativeState.PositionMouseDown; } + set { throw new NotImplementedException(); } + } + public bool HasMainButtonPressed => NativeState.HasMainButtonPressed; public int Wheel => NativeState.Wheel; public int WheelDelta => NativeState.WheelDelta; diff --git a/osu.Framework/Input/IMouseState.cs b/osu.Framework/Input/IMouseState.cs index f811a2135b..d2e95b0678 100644 --- a/osu.Framework/Input/IMouseState.cs +++ b/osu.Framework/Input/IMouseState.cs @@ -10,12 +10,14 @@ public interface IMouseState { IMouseState NativeState { get; } + IMouseState LastState { get; set; } + Vector2 Delta { get; } Vector2 Position { get; } Vector2 LastPosition { get; } - Vector2? PositionMouseDown { get; } + Vector2? PositionMouseDown { get; set; } bool HasMainButtonPressed { get; } diff --git a/osu.Framework/Input/InputManager.cs b/osu.Framework/Input/InputManager.cs index fe2ab7cc94..65f3915d2b 100644 --- a/osu.Framework/Input/InputManager.cs +++ b/osu.Framework/Input/InputManager.cs @@ -189,8 +189,13 @@ protected override void Update() // we only want to set a last state if both the new and old state are of the same type. // this avoids giving the new state a false impression of being able to calculate delta values based on a last // state potentially from a different input source. - if (last.Mouse?.GetType() == s.Mouse?.GetType()) - (s.Mouse as MouseState)?.SetLast(last.Mouse); //necessary for now as last state is used internally for stuff + if (last.Mouse != null && s.Mouse != null && last.Mouse.GetType() == s.Mouse.GetType()) + { + //necessary for now as last state is used internally for stuff + last.Mouse.LastState = null; + s.Mouse.LastState = last.Mouse; + s.Mouse.PositionMouseDown = last.Mouse.PositionMouseDown; + } //hover could change even when the mouse state has not. updateHoverEvents(CurrentState); diff --git a/osu.Framework/Input/MouseState.cs b/osu.Framework/Input/MouseState.cs index ccc2af039a..46c89479c8 100644 --- a/osu.Framework/Input/MouseState.cs +++ b/osu.Framework/Input/MouseState.cs @@ -16,7 +16,7 @@ public class MouseState : IMouseState public IMouseState NativeState => this; - public IMouseState LastState; + public IMouseState LastState { get; set; } public virtual int WheelDelta => (Wheel - LastState?.Wheel) ?? 0; @@ -32,16 +32,7 @@ public class MouseState : IMouseState public Vector2 LastPosition => LastState?.Position ?? Position; - public Vector2? PositionMouseDown { get; internal set; } - - public void SetLast(IMouseState last) - { - (last as MouseState)?.SetLast(null); - - LastState = last; - if (last != null) - PositionMouseDown = last.PositionMouseDown; - } + public Vector2? PositionMouseDown { get; set; } public IMouseState Clone() { From a10e87cfa9d1c8d41590bb897fc1b8acf36f3948 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Jun 2017 16:45:40 +0900 Subject: [PATCH 3/5] Add licence headers --- .../Input/Handlers/Mouse/OpenTKEventMouseState.cs | 3 +++ .../Input/Handlers/Mouse/OpenTKPollMouseState.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKEventMouseState.cs b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKEventMouseState.cs index 1874024769..c4b65657a3 100644 --- a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKEventMouseState.cs +++ b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKEventMouseState.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + using OpenTK; namespace osu.Framework.Desktop.Input.Handlers.Mouse diff --git a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKPollMouseState.cs b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKPollMouseState.cs index 098690227a..2b53bf72ad 100644 --- a/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKPollMouseState.cs +++ b/osu.Framework.Desktop/Input/Handlers/Mouse/OpenTKPollMouseState.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + using OpenTK; namespace osu.Framework.Desktop.Input.Handlers.Mouse From 664acca29a81fee2df3cca9d75f5e7a02ef4c0eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Jun 2017 16:50:52 +0900 Subject: [PATCH 4/5] Remove "redundant" parenthesis --- osu.Framework/Input/MouseState.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Framework/Input/MouseState.cs b/osu.Framework/Input/MouseState.cs index 46c89479c8..deba072fb9 100644 --- a/osu.Framework/Input/MouseState.cs +++ b/osu.Framework/Input/MouseState.cs @@ -18,7 +18,7 @@ public class MouseState : IMouseState public IMouseState LastState { get; set; } - public virtual int WheelDelta => (Wheel - LastState?.Wheel) ?? 0; + public virtual int WheelDelta => Wheel - LastState?.Wheel ?? 0; public int Wheel { get; set; } From e8d2fad5b9d3ef37858ba7120ef58cfb347c533a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Jun 2017 16:55:45 +0900 Subject: [PATCH 5/5] Remove comment --- osu.Framework/Input/InputManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Framework/Input/InputManager.cs b/osu.Framework/Input/InputManager.cs index 65f3915d2b..be95676c02 100644 --- a/osu.Framework/Input/InputManager.cs +++ b/osu.Framework/Input/InputManager.cs @@ -191,7 +191,6 @@ protected override void Update() // state potentially from a different input source. if (last.Mouse != null && s.Mouse != null && last.Mouse.GetType() == s.Mouse.GetType()) { - //necessary for now as last state is used internally for stuff last.Mouse.LastState = null; s.Mouse.LastState = last.Mouse; s.Mouse.PositionMouseDown = last.Mouse.PositionMouseDown;