Skip to content

Commit

Permalink
Fixed input
Browse files Browse the repository at this point in the history
  • Loading branch information
Tornado-Technology committed Aug 14, 2024
1 parent 885a901 commit 79b476f
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ private void OnErrorHandled(ErrorCode error, string description)

private void OnWindowKeyHandled(Window* window, Keys glfwKey, int scanCode, InputAction action, GlfwKeyModifiers mods)
{
RaiseInput(new WindowingKeyHandledEvent(new KeyStateChangedArgs(
RaiseInput(new WindowingKeyHandledEvent(
(Key)glfwKey,
Convert(action),
(KeyModifiers)mods,
scanCode
)));
));
}

private void OnWindowCharHandled(Window* window, uint codepoint)
Expand All @@ -75,11 +75,11 @@ private void OnWindowScrollHandled(Window* window, double offsetX, double offset

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

private void RaiseInput<T>(T args) where T : IEventArgs
Expand Down
6 changes: 6 additions & 0 deletions Hypercube.Client/Input/Events/KeyHandledEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Hypercube.Client.Input.Events;

public class KeyHandledEvent
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@

namespace Hypercube.Client.Input.Events.Windowing;

public readonly record struct WindowingKeyHandledEvent(KeyStateChangedArgs State) : IEventArgs;
public sealed class WindowingKeyHandledEvent : KeyStateChangedArgs, IEventArgs
{
public WindowingKeyHandledEvent(Key key, KeyState state, KeyModifiers modifiers, int scanCode) : base(key, state, modifiers, scanCode)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@

namespace Hypercube.Client.Input.Events.Windowing;

public readonly record struct WindowingMouseButtonHandledEvent(MouseButtonChangedArgs State) : IEventArgs;
public class WindowingMouseButtonHandledEvent : MouseButtonChangedArgs, IEventArgs
{
public WindowingMouseButtonHandledEvent(MouseButton button, KeyState state, KeyModifiers modifiers) : base(button, state, modifiers)
{
}
}
6 changes: 6 additions & 0 deletions Hypercube.Client/Input/Handler/IInputHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ public interface IInputHandler : IEventSubscriber
bool IsKeyPressed(Key key);
bool IsKeyReleased(Key key);
void KeyClear();

bool IsMouseButtonState(MouseButton button, KeyState state);
bool IsMouseButtonHeld(MouseButton button);
bool IsMouseButtonPressed(MouseButton button);
bool IsMouseButtonReleased(MouseButton button);
void MouseButtonClear();
}
127 changes: 111 additions & 16 deletions Hypercube.Client/Input/Handler/InputHandler.cs
Original file line number Diff line number Diff line change
@@ -1,56 +1,120 @@
using Hypercube.Client.Input.Events.Windowing;
using System.Collections.Frozen;
using Hypercube.Client.Input.Events.Windowing;
using Hypercube.Input;
using Hypercube.Shared.Dependency;
using Hypercube.Shared.EventBus;
using Hypercube.Shared.Logging;
using Hypercube.Shared.Runtimes.Loop.Event;

namespace Hypercube.Client.Input.Handler;

public sealed class InputHandler : IInputHandler, IPostInject
{
[Dependency] private readonly IEventBus _eventBus = default!;

private readonly Dictionary<Key, KeyState> _keys = [];

private readonly FrozenDictionary<KeyState, HashSet<Key>> _keys = new Dictionary<KeyState, HashSet<Key>>
{
{ KeyState.Held, [] },
{ KeyState.Release, [] },
{ KeyState.Pressed, [] },
}.ToFrozenDictionary();

private readonly FrozenDictionary<KeyState, HashSet<MouseButton>> _mouseButtons = new Dictionary<KeyState, HashSet<MouseButton>>
{
{ KeyState.Held, [] },
{ KeyState.Release, [] },
{ KeyState.Pressed, [] },
}.ToFrozenDictionary();


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

public void PostInject()
{
_eventBus.Subscribe<InputFrameEvent>(this, OnInputFrameUpdate);

_eventBus.Subscribe<WindowingCharHandledEvent>(this, OnCharHandled);
_eventBus.Subscribe<WindowingKeyHandledEvent>(this, OnKeyHandled);
_eventBus.Subscribe<WindowingMouseButtonHandledEvent>(this, OnMouseButtonHandled);
_eventBus.Subscribe<WindowingScrollHandledEvent>(this, OnScrollHandled);
}

private void OnInputFrameUpdate(ref InputFrameEvent args)
{
_keys[KeyState.Pressed].Clear();
_keys[KeyState.Release].Clear();
_mouseButtons[KeyState.Pressed].Clear();
_mouseButtons[KeyState.Release].Clear();
}

private void OnCharHandled(ref WindowingCharHandledEvent args)
{
throw new NotImplementedException();
}

private void OnKeyHandled(ref WindowingKeyHandledEvent args)
{
var state = args.State.State;
var key = args.State.Key;

#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), key))
if (!Enum.IsDefined(typeof(Key), args.Key))
{
_logger.Warning($"Unknown key {key} handled");
_logger.Warning($"Unknown {args.Key} handled");
return;
}
#endif

// Legacy shit, maybe will eat many ram and cpu
// We made many shit because fucking Key rollover: https://en.wikipedia.org/wiki/Key_rollover


_logger.Warning($"{key} {state}");
switch (args.State)
{
case KeyState.Pressed:
_keys[KeyState.Held].Add(args.Key);
_keys[KeyState.Pressed].Add(args.Key);
break;

case KeyState.Release:
_keys[KeyState.Held].Remove(args.Key);
_keys[KeyState.Pressed].Add(args.Key);
break;

case KeyState.Held:
break;

default:
throw new ArgumentOutOfRangeException();
}
}

private void OnMouseButtonHandled(ref WindowingMouseButtonHandledEvent 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(MouseButton), args.Button))
{
_logger.Warning($"Unknown {args.Button} handled");
return;
}
#endif

switch (args.State)
{
case KeyState.Pressed:
_mouseButtons[KeyState.Held].Add(args.Button);
_mouseButtons[KeyState.Pressed].Add(args.Button);
break;

case KeyState.Release:
_mouseButtons[KeyState.Held].Remove(args.Button);
_mouseButtons[KeyState.Pressed].Add(args.Button);
break;

case KeyState.Held:
break;

default:
throw new ArgumentOutOfRangeException();
}
}

private void OnScrollHandled(ref WindowingScrollHandledEvent args)
Expand All @@ -59,12 +123,12 @@ private void OnScrollHandled(ref WindowingScrollHandledEvent args)

public bool IsKeyState(Key key, KeyState state)
{
return _keys.TryGetValue(key, out var keyState) && keyState == state;
return _keys[state].Contains(key);
}

public bool IsKeyHeld(Key key)
{
return _keys.TryGetValue(key, out var keyState) && keyState is KeyState.Held or KeyState.Pressed;
return IsKeyState(key, KeyState.Held);
}

public bool IsKeyPressed(Key key)
Expand All @@ -76,9 +140,40 @@ public bool IsKeyReleased(Key key)
{
return IsKeyState(key, KeyState.Pressed);
}

public void KeyClear()
{
_keys.Clear();
foreach (var (_, key) in _keys)
{
key.Clear();
}
}

public bool IsMouseButtonState(MouseButton button, KeyState state)
{
return _mouseButtons[state].Contains(button);
}

public bool IsMouseButtonHeld(MouseButton button)
{
return IsMouseButtonState(button, KeyState.Held);
}

public bool IsMouseButtonPressed(MouseButton button)
{
return IsMouseButtonState(button, KeyState.Pressed);
}

public bool IsMouseButtonReleased(MouseButton button)
{
return IsMouseButtonState(button, KeyState.Release);
}

public void MouseButtonClear()
{
foreach (var (_, mouseButtons) in _mouseButtons)
{
mouseButtons.Clear();
}
}
}
2 changes: 1 addition & 1 deletion Hypercube.Input/KeyStateChangedArgs.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Hypercube.Input;

public readonly struct KeyStateChangedArgs
public class KeyStateChangedArgs
{
public bool Shift => Modifiers.HasFlag(KeyModifiers.Shift);
public bool Control => Modifiers.HasFlag(KeyModifiers.Control);
Expand Down
2 changes: 1 addition & 1 deletion Hypercube.Input/MouseButtonChangedArgs.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Hypercube.Input;

public readonly struct MouseButtonChangedArgs
public class MouseButtonChangedArgs
{
public bool Shift => Modifiers.HasFlag(KeyModifiers.Shift);
public bool Control => Modifiers.HasFlag(KeyModifiers.Control);
Expand Down

0 comments on commit 79b476f

Please sign in to comment.