Skip to content

Commit

Permalink
Updated input handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Tornado-Technology committed Aug 12, 2024
1 parent 7aeb1fa commit a7a1413
Show file tree
Hide file tree
Showing 22 changed files with 236 additions and 96 deletions.
1 change: 1 addition & 0 deletions Hypercube.Client/Graphics/Viewports/CameraManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Hypercube.Client.Input;
using Hypercube.Client.Input.Handler;
using Hypercube.Input;
using Hypercube.Math.Matrices;
using Hypercube.Math.Vectors;
using Hypercube.Shared.Dependency;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
using Hypercube.Client.Input;
using Hypercube.Client.Utilities.Helpers;
using Hypercube.Client.Input.Events.Windowing;
using Hypercube.Input;
using Hypercube.OpenGL.Utilities.Helpers;
using Hypercube.Shared.EventBus.Events;
using OpenTK.Windowing.GraphicsLibraryFramework;

using GlfwKeyModifiers = OpenTK.Windowing.GraphicsLibraryFramework.KeyModifiers;
using KeyModifiers = Hypercube.Client.Input.KeyModifiers;
using GlfwMouseButton = OpenTK.Windowing.GraphicsLibraryFramework.MouseButton;

using KeyModifiers = Hypercube.Input.KeyModifiers;
using MouseButton = Hypercube.Input.MouseButton;

using static OpenTK.Windowing.GraphicsLibraryFramework.GLFWCallbacks;

namespace Hypercube.Client.Graphics.Windows.Realisation.Glfw;

public sealed unsafe partial class GlfwWindowManager
{
private ErrorCallback? _errorCallback;


private CharCallback? _charCallback;
private ScrollCallback? _scrollCallback;
private KeyCallback? _keyCallback;

private MouseButtonCallback? _mouseButtonCallback;

private WindowCloseCallback? _windowCloseCallback;
private WindowSizeCallback? _windowSizeCallback;
private WindowFocusCallback? _windowFocusCallback;
Expand All @@ -26,52 +35,60 @@ public sealed unsafe partial class GlfwWindowManager
private void HandleCallbacks()
{
_errorCallback = OnErrorHandled;


_charCallback = OnWindowCharHandled;
_scrollCallback = OnWindowScrollHandled;
_keyCallback = OnWindowKeyHandled;
_mouseButtonCallback = OnMouseButtonHandled;

_windowCloseCallback = OnWindowClosed;
_windowSizeCallback = OnWindowResized;
_windowFocusCallback = OnWindowFocusChanged;
}

private void OnErrorHandled(ErrorCode error, string description)
{
_logger.Error(GLFWHelper.FormatError(error, description));
}

#region Input handler

private void OnWindowKeyHandled(Window* window, Keys glfwKey, int scanCode, InputAction action, GlfwKeyModifiers mods)
{
var key = (Key)glfwKey;
var pressed = false;
var repeat = false;

switch (action)
{
case InputAction.Release:
pressed = false;
break;

case InputAction.Press:
pressed = true;
break;

case InputAction.Repeat:
pressed = true;
repeat = true;
break;

default:
throw new ArgumentOutOfRangeException(nameof(action), action, null);
}

_inputHandler.SendKeyState(new KeyStateChangedArgs(
key,
pressed,
repeat,
RaiseInput(new WindowingKeyHandledEvent(new KeyStateChangedArgs(
(Key)glfwKey,
Convert(action),
(KeyModifiers)mods,
scanCode));
scanCode
)));
}

private void OnWindowCharHandled(Window* window, uint codepoint)
{
RaiseInput(new WindowingCharHandledEvent());
}

private void OnWindowScrollHandled(Window* window, double offsetX, double offsetY)
{
RaiseInput(new WindowingScrollHandledEvent());
}

private void OnMouseButtonHandled(Window* window, GlfwMouseButton button, InputAction action, GlfwKeyModifiers mods)
{
RaiseInput(new WindowingMouseButtonHandledEvent(new MouseButtonChangedArgs(
(MouseButton)button,
Convert(action),
(KeyModifiers)mods
)));
}

private void RaiseInput<T>(T args) where T : IEventArgs
{
_eventBus.Raise(_inputHandler, ref args);
}

#endregion

private void OnWindowClosed(Window* window)
{
if (!TryGetWindow(window, out var registration))
Expand All @@ -95,12 +112,23 @@ private void OnWindowFocusChanged(Window* window, bool focused)

_renderer.OnFocusChanged(registration, focused);
}

private void OnWindowFocused(Window* window, bool focused)
{
if (!TryGetWindow(window, out var registration))
return;

_renderer.OnFocusChanged(registration, focused);
}


private static KeyState Convert(InputAction action)
{
return action switch
{
InputAction.Release => KeyState.Release,
InputAction.Press => KeyState.Press,
InputAction.Repeat => KeyState.Repeat,
_ => throw new ArgumentOutOfRangeException()
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
using Hypercube.Graphics.Windowing;
using Hypercube.Math.Vectors;
using Hypercube.Shared.Dependency;
using Hypercube.Shared.EventBus;
using Hypercube.Shared.Logging;
using OpenTK.Windowing.GraphicsLibraryFramework;

namespace Hypercube.Client.Graphics.Windows.Realisation.Glfw;

public sealed unsafe partial class GlfwWindowManager : IWindowManager
{
[Dependency] private readonly IRenderer _renderer = default!;
[Dependency] private readonly IEventBus _eventBus = default!;
[Dependency] private readonly IInputHandler _inputHandler = default!;

private readonly ILogger _logger = LoggingManager.GetLogger("glfw");
[Dependency] private readonly IRenderer _renderer = default!;

private readonly Logger _logger = LoggingManager.GetLogger("glfw");

private bool _initialized;
private bool _running;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Hypercube.Shared.EventBus.Events;

namespace Hypercube.Client.Input.Events.Windowing;

public readonly record struct WindowingCharHandledEvent : IEventArgs;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Hypercube.Input;
using Hypercube.Shared.EventBus.Events;

namespace Hypercube.Client.Input.Events.Windowing;

public readonly record struct WindowingKeyHandledEvent(KeyStateChangedArgs State) : IEventArgs;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Hypercube.Input;
using Hypercube.Shared.EventBus.Events;

namespace Hypercube.Client.Input.Events.Windowing;

public readonly record struct WindowingMouseButtonHandledEvent(MouseButtonChangedArgs State) : IEventArgs;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Hypercube.Shared.EventBus.Events;

namespace Hypercube.Client.Input.Events.Windowing;

public readonly record struct WindowingScrollHandledEvent : IEventArgs;
9 changes: 3 additions & 6 deletions Hypercube.Client/Input/Handler/IInputHandler.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
using Hypercube.Client.Graphics.Windows;
using Hypercube.Input;
using Hypercube.Shared.EventBus;

namespace Hypercube.Client.Input.Handler;

/// <summary>
/// Receives requests from user input, via <see cref="IWindowManager"/>,
/// and submits them for further work via events.
/// </summary>
public interface IInputHandler
public interface IInputHandler : IEventSubscriber
{
event Action<KeyStateChangedArgs>? KeyUp;
event Action<KeyStateChangedArgs>? KeyDown;

// TODO: Create Analyzer to allow access only for IWindowManager implementation
void SendKeyState(KeyStateChangedArgs changedArgs);
bool IsKeyDown(Key key);
}
53 changes: 39 additions & 14 deletions Hypercube.Client/Input/Handler/InputHandler.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,61 @@
using Hypercube.Shared.Logging;
using Hypercube.Client.Input.Events.Windowing;
using Hypercube.Input;
using Hypercube.Shared.Dependency;
using Hypercube.Shared.EventBus;
using Hypercube.Shared.Logging;

namespace Hypercube.Client.Input.Handler;

public sealed class InputHandler : IInputHandler
public sealed class InputHandler : IInputHandler, IPostInject
{
public event Action<KeyStateChangedArgs>? KeyUp;
public event Action<KeyStateChangedArgs>? KeyDown;
[Dependency] private readonly IEventBus _eventBus = default!;

private readonly HashSet<Key> _keysRelease = [];
private readonly HashSet<Key> _keysPressed = [];
private readonly HashSet<Key> _keysDown = [];

private readonly Logger _logger = LoggingManager.GetLogger("input_handler");

private readonly HashSet<Key> _keysDown = new();
private readonly ILogger _logger = LoggingManager.GetLogger("input_handler");
public void PostInject()
{
_eventBus.Subscribe<WindowingCharHandledEvent>(this, OnCharHandled);
_eventBus.Subscribe<WindowingKeyHandledEvent>(this, OnKeyHandled);
_eventBus.Subscribe<WindowingMouseButtonHandledEvent>(this, OnMouseButtonHandled);
_eventBus.Subscribe<WindowingScrollHandledEvent>(this, OnScrollHandled);
}

public void SendKeyState(KeyStateChangedArgs changedArgs)
private void OnCharHandled(ref WindowingCharHandledEvent args)
{
throw new NotImplementedException();
}

private void OnKeyHandled(ref WindowingKeyHandledEvent args)
{
#if DEBUG
// Use only in Debug build,
// as this check can take quite a lot of performance during input processing
if (!Enum.IsDefined(typeof(Key), changedArgs.Key))
if (!Enum.IsDefined(typeof(Key), args.State.Key))
{
_logger.Warning($"Unknown key {changedArgs.Key} handled");
_logger.Warning($"Unknown key {args.State.Key} handled");
return;
}
#endif

if (changedArgs.Pressed)
if (args.State == KeyState.Press)
{
KeyDown?.Invoke(changedArgs);
_keysDown.Add(changedArgs.Key);
_keysDown.Add(args.State.Key);
return;
}

_keysDown.Remove(changedArgs.Key);
KeyUp?.Invoke(changedArgs);
_keysDown.Remove(args.State.Key);
}

private void OnMouseButtonHandled(ref WindowingMouseButtonHandledEvent args)
{
}

private void OnScrollHandled(ref WindowingScrollHandledEvent args)
{
}

public bool IsKeyDown(Key key)
Expand Down
20 changes: 1 addition & 19 deletions Hypercube.Client/Input/Manager/InputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,7 @@

namespace Hypercube.Client.Input.Manager;

public sealed class InputManager : IInputManager, IPostInject
public sealed class InputManager : IInputManager
{
[Dependency] private readonly IInputHandler _inputHandler = default!;

private Dictionary<Key, KeyState> _keyStates = new();

public void PostInject()
{
_inputHandler.KeyUp += OnKeyUp;
_inputHandler.KeyDown += OnKeyDown;
}

private void OnKeyUp(KeyStateChangedArgs changedArgs)
{

}

private void OnKeyDown(KeyStateChangedArgs changedArgs)
{

}
}
1 change: 1 addition & 0 deletions Hypercube.Example.Client/Controls/ControlsSystem.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Hypercube.Client.Input;
using Hypercube.Client.Input.Handler;
using Hypercube.Input;
using Hypercube.Math.Vectors;
using Hypercube.Shared.Dependency;
using Hypercube.Shared.Entities.Realisation.Systems;
Expand Down
22 changes: 18 additions & 4 deletions Hypercube.ImGui/Implementations/GlfwImGuiController.Input.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
namespace Hypercube.ImGui.Implementations;
using Hypercube.Math.Vectors;
using OpenTK.Platform;

namespace Hypercube.ImGui.Implementations;

public partial class GlfwImGuiController
{
private void UpdateMousePosition()
private void UpdateMousePosition(Vector2Int position)
{

_io.MousePos = position;
}

private void UpdateMouseButtons()
private void UpdateMouseButtons(bool[] state)
{
_io.MouseDown[0] = state[0]; // Left
_io.MouseDown[1] = state[1]; // Right
_io.MouseDown[2] = state[2]; // Middle

_io.MouseDown[3] = state[3];
_io.MouseDown[4] = state[4];
}

private void UpdateMouseScroll(Vector2 offset)
{
_io.MouseWheelH = offset.X;
_io.MouseWheel = offset.Y;
}

private void UpdateMouseCursor()
Expand Down
4 changes: 0 additions & 4 deletions Hypercube.ImGui/Implementations/GlfwImGuiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,6 @@ public void Update(float deltaTime)
_io.DisplayFramebufferScale = framebufferSize / size;

_io.DeltaTime = deltaTime;

UpdateMousePosition();
UpdateMouseButtons();
UpdateMouseCursor();

ImGuiNET.ImGui.NewFrame();
}
Expand Down
9 changes: 9 additions & 0 deletions Hypercube.Input/Hypercube.Input.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Loading

0 comments on commit a7a1413

Please sign in to comment.