From ced3d03bdb3ce866d832e03fb212865140905a9a Mon Sep 17 00:00:00 2001 From: Thomas Leyh Date: Sun, 24 Jul 2016 08:14:18 +0200 Subject: Add project files. --- V3/Input/IInputManager.cs | 34 +++++++++ V3/Input/IKeyEvent.cs | 20 ++++++ V3/Input/IMouseEvent.cs | 34 +++++++++ V3/Input/IMouseEventHandler.cs | 14 ++++ V3/Input/Internal/InputManager.cs | 141 ++++++++++++++++++++++++++++++++++++++ V3/Input/Internal/KeyEvent.cs | 32 +++++++++ V3/Input/Internal/MouseEvent.cs | 57 +++++++++++++++ V3/Input/MouseButton.cs | 9 +++ 8 files changed, 341 insertions(+) create mode 100644 V3/Input/IInputManager.cs create mode 100644 V3/Input/IKeyEvent.cs create mode 100644 V3/Input/IMouseEvent.cs create mode 100644 V3/Input/IMouseEventHandler.cs create mode 100644 V3/Input/Internal/InputManager.cs create mode 100644 V3/Input/Internal/KeyEvent.cs create mode 100644 V3/Input/Internal/MouseEvent.cs create mode 100644 V3/Input/MouseButton.cs (limited to 'V3/Input') diff --git a/V3/Input/IInputManager.cs b/V3/Input/IInputManager.cs new file mode 100644 index 0000000..b092ebb --- /dev/null +++ b/V3/Input/IInputManager.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; + +namespace V3.Input +{ + /// + /// Watches the state of the mouse and keyboard and creates events if a + /// change (key pressed or released) is detected. To use this class, call + /// Update in every update round. After the update, you may access the + /// generated events in KeyEvents and MouseEvents. The input manager only + /// watches the mouse buttons and keys listed in sWatchedKeys and + /// sWatchedButtons. + /// + public interface IInputManager + { + /// + /// The key events that were generated during the last update. Reset + /// in the next update. + /// + ICollection KeyEvents { get; } + + /// + /// The mouse events that were generated during the last update. Reset in + /// the next update. + /// + ICollection MouseEvents { get; } + + /// + /// Updates the keyboard and mouse status and generates the key and mouse + /// events in KeyEvents and MouseEvents if changes were detected. Should + /// be called once every update, before doing something else. + /// + void Update(); + } +} \ No newline at end of file diff --git a/V3/Input/IKeyEvent.cs b/V3/Input/IKeyEvent.cs new file mode 100644 index 0000000..42b99c6 --- /dev/null +++ b/V3/Input/IKeyEvent.cs @@ -0,0 +1,20 @@ +using Microsoft.Xna.Framework.Input; + +namespace V3.Input +{ + /// + /// An event that is triggered if a key is pressed or released on the + /// keyboard. + /// + public interface IKeyEvent + { + /// + /// The key that was pressed or released. + /// + Keys Key { get; } + /// + /// The type of the event (key pressed or released?). + /// + KeyState KeyState { get; } + } +} \ No newline at end of file diff --git a/V3/Input/IMouseEvent.cs b/V3/Input/IMouseEvent.cs new file mode 100644 index 0000000..37b221d --- /dev/null +++ b/V3/Input/IMouseEvent.cs @@ -0,0 +1,34 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace V3.Input +{ + /// + /// An event that is sent when a mouse button is pressed or released. + /// + public interface IMouseEvent + { + /// + /// The mouse button that was pressed or released. + /// + MouseButton MouseButton { get; } + /// + /// The state of the mouse button (pressed or released?). + /// + ButtonState ButtonState { get; } + /// + /// The position where the mouse button was pressed the last time. + /// + Point PositionPressed { get; } + /// + /// The position where the mouse button was released if this is a + /// release event, null otherwise. + /// + Point? PositionReleased { get; } + /// + /// True if PositionReleased is a valid on-screen position, otherwise + /// false. + /// + bool ReleasedOnScreen { get; } + } +} diff --git a/V3/Input/IMouseEventHandler.cs b/V3/Input/IMouseEventHandler.cs new file mode 100644 index 0000000..7c8701c --- /dev/null +++ b/V3/Input/IMouseEventHandler.cs @@ -0,0 +1,14 @@ +namespace V3.Input +{ + /// + /// Handles mouse events. + /// + public interface IMouseEventHandler + { + /// + /// Handle the given mouse event, if applicable. + /// + /// the mouse event to handle + void HandleMouseEvent(IMouseEvent mouseEvent); + } +} diff --git a/V3/Input/Internal/InputManager.cs b/V3/Input/Internal/InputManager.cs new file mode 100644 index 0000000..8e6ce2e --- /dev/null +++ b/V3/Input/Internal/InputManager.cs @@ -0,0 +1,141 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using Ninject; + +namespace V3.Input.Internal +{ + /// + /// Watches the state of the mouse and keyboard and creates events if a + /// change (key pressed or released) is detected. To use this class, call + /// Update in every update round. After the update, you may access the + /// generated events in KeyEvents and MouseEvents. The input manager only + /// watches the mouse buttons and keys listed in sWatchedKeys and + /// sWatchedButtons. + /// + // ReSharper disable once ClassNeverInstantiated.Global + internal sealed class InputManager : IInputManager, IInitializable + { + /// + /// The key events that were generated during the last update. Reset + /// in the next update. + /// + public ICollection KeyEvents { get; } = new HashSet(); + /// + /// The mouse events that were generated during the last update. Reset in + /// the next update. + /// + public ICollection MouseEvents { get; } = new HashSet(); + + private static readonly ICollection sWatchedKeys = new List { Keys.Enter, Keys.Escape, Keys.E, Keys.L, Keys.Q, Keys.S, Keys.F1, Keys.F2 , Keys.F3, Keys.F4, Keys.F5, Keys.F6, Keys.F7, Keys.F8 }; + + private static readonly ICollection sWatchedButtons = new List { MouseButton.Left, MouseButton.Right, MouseButton.Middle }; + + private readonly GraphicsDeviceManager mGraphicsDeviceManager; + + private readonly IDictionary mKeyStates = new Dictionary(); + + private readonly IDictionary mButtonStates = new Dictionary(); + + private readonly IDictionary mButtonPositions = new Dictionary(); + + /// + /// Creates a new input manager. + /// + public InputManager(GraphicsDeviceManager graphicsDeviceManager) + { + mGraphicsDeviceManager = graphicsDeviceManager; + } + + public void Initialize() + { + foreach (var key in sWatchedKeys) + mKeyStates.Add(key, KeyState.Up); + foreach (var button in sWatchedButtons) + { + mButtonStates.Add(button, ButtonState.Released); + mButtonPositions.Add(button, null); + } + } + + /// + /// Updates the keyboard and mouse status and generates the key and mouse + /// events in KeyEvents and MouseEvents if changes were detected. Should + /// be called once every update, before doing something else. + /// + public void Update() + { + UpdateKeyboard(); + UpdateMouse(); + } + + private void UpdateKeyboard() + { + KeyEvents.Clear(); + + var state = Keyboard.GetState(); + foreach (var key in sWatchedKeys) + { + var newState = state[key]; + if (newState != mKeyStates[key]) + { + mKeyStates[key] = newState; + KeyEvents.Add(new KeyEvent(key, newState)); + } + } + } + + private void UpdateMouse() + { + MouseEvents.Clear(); + + var state = Mouse.GetState(); + foreach (var button in sWatchedButtons) + { + var newState = GetButtonState(state, button); + if (newState != mButtonStates[button]) + { + var position = new Point(state.X, state.Y); + var positionPressed = position; + Point? positionReleased = null; + if (newState == ButtonState.Released) + { + if (mButtonPositions[button].HasValue) + positionPressed = mButtonPositions[button].Value; + positionReleased = position; + } + + mButtonStates[button] = newState; + mButtonPositions[button] = position; + + var releasedOnScreen = false; + if (positionReleased.HasValue) + releasedOnScreen = IsPointOnScreen(positionReleased.Value); + + MouseEvents.Add(new MouseEvent(button, newState, positionPressed, positionReleased, releasedOnScreen)); + } + } + } + + private bool IsPointOnScreen(Point point) + { + var viewport = mGraphicsDeviceManager.GraphicsDevice.Viewport; + return point.X >= 0 && point.X <= viewport.Width && point.Y >= 0 && point.Y <= viewport.Height; + } + + private static ButtonState GetButtonState(MouseState state, MouseButton button) + { + switch (button) + { + case MouseButton.Left: + return state.LeftButton; + case MouseButton.Right: + return state.RightButton; + case MouseButton.Middle: + return state.MiddleButton; + default: + return state.LeftButton; + } + } + } +} diff --git a/V3/Input/Internal/KeyEvent.cs b/V3/Input/Internal/KeyEvent.cs new file mode 100644 index 0000000..b4a450e --- /dev/null +++ b/V3/Input/Internal/KeyEvent.cs @@ -0,0 +1,32 @@ +using Microsoft.Xna.Framework.Input; + +namespace V3.Input.Internal +{ + /// + /// Default implementation of an event that is triggered if a key is + /// pressed or released on the keyboard. + /// + internal sealed class KeyEvent : IKeyEvent + { + /// + /// The key that was pressed or released. + /// + public Keys Key { get; } + /// + /// The type of the event (key pressed or released?). + /// + public KeyState KeyState { get; } + + /// + /// Creates a new key event with the given data. + /// + /// the key that was pressed or released + /// the type of the event (presesd or + /// released?) + public KeyEvent(Keys key, KeyState keyState) + { + Key = key; + KeyState = keyState; + } + } +} diff --git a/V3/Input/Internal/MouseEvent.cs b/V3/Input/Internal/MouseEvent.cs new file mode 100644 index 0000000..f8024aa --- /dev/null +++ b/V3/Input/Internal/MouseEvent.cs @@ -0,0 +1,57 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace V3.Input.Internal +{ + /// + /// Default implementation of an event that is sent when a mouse button is + /// pressed or released. + /// + internal sealed class MouseEvent : IMouseEvent + { + /// + /// The mouse button that was pressed or released. + /// + public MouseButton MouseButton { get; } + /// + /// The state of the mouse button (pressed or released?). + /// + public ButtonState ButtonState { get; } + /// + /// The position where the mouse button was pressed the last time. + /// + public Point PositionPressed { get; } + /// + /// The position where the mouse button was released if this is a + /// release event, null otherwise. + /// + public Point? PositionReleased { get; } + /// + /// True if PositionReleased is a valid on-screen position, otherwise + /// false. + /// + public bool ReleasedOnScreen { get; } + + /// + /// Creates a new mouse event with the given data. + /// + /// the mouse button that was pressed or + /// released + /// the type of the event (pressed or + /// released?) + /// the position of the last press of + /// the button + /// the position of the release of the + /// button if this is a release event, or null otherwise + /// true if positionReleased is a valid + /// on-screen position. + public MouseEvent(MouseButton mouseButton, ButtonState buttonState, Point positionPressed, Point? positionReleased, bool releasedOnScreen) + { + MouseButton = mouseButton; + ButtonState = buttonState; + PositionPressed = positionPressed; + PositionReleased = positionReleased; + ReleasedOnScreen = releasedOnScreen; + } + } +} diff --git a/V3/Input/MouseButton.cs b/V3/Input/MouseButton.cs new file mode 100644 index 0000000..616872b --- /dev/null +++ b/V3/Input/MouseButton.cs @@ -0,0 +1,9 @@ +namespace V3.Input +{ + public enum MouseButton + { + Left, + Right, + Middle + } +} -- cgit v1.2.1