Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update input #48

Merged
merged 4 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Hypercube.Client/ClientConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
public static class ClientConstants
{
public static bool MultiThreadingWindow = false;

}
16 changes: 8 additions & 8 deletions Hypercube.Client/Graphics/Viewports/CameraManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,28 @@ public void UpdateInput(ICamera? camera, float delta)

var speed = 60f;

if (_inputHandler.IsKeyDown(Key.W))
if (_inputHandler.IsKeyHeld(Key.W))
position += Vector3.UnitY * speed * delta;

if (_inputHandler.IsKeyDown(Key.S))
if (_inputHandler.IsKeyHeld(Key.S))
position -= Vector3.UnitY * speed * delta;

if (_inputHandler.IsKeyDown(Key.A))
if (_inputHandler.IsKeyHeld(Key.A))
position -= Vector3.UnitX * speed * delta;

if (_inputHandler.IsKeyDown(Key.D))
if (_inputHandler.IsKeyHeld(Key.D))
position += Vector3.UnitX * speed * delta;

if (_inputHandler.IsKeyDown(Key.Q))
if (_inputHandler.IsKeyHeld(Key.Q))
rotation -= Vector3.UnitZ * delta;

if (_inputHandler.IsKeyDown(Key.E))
if (_inputHandler.IsKeyHeld(Key.E))
rotation += Vector3.UnitZ * delta;

if (_inputHandler.IsKeyDown(Key.T))
if (_inputHandler.IsKeyHeld(Key.T))
scale -= Vector3.One * delta;

if (_inputHandler.IsKeyDown(Key.Y))
if (_inputHandler.IsKeyHeld(Key.Y))
scale += Vector3.One * delta;

camera.SetPosition(position);
Expand Down
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 Expand Up @@ -126,8 +126,8 @@ private static KeyState Convert(InputAction action)
return action switch
{
InputAction.Release => KeyState.Release,
InputAction.Press => KeyState.Press,
InputAction.Repeat => KeyState.Repeat,
InputAction.Press => KeyState.Pressed,
InputAction.Repeat => KeyState.Held,
_ => throw new ArgumentOutOfRangeException()
};
}
Expand Down
11 changes: 11 additions & 0 deletions Hypercube.Client/Input/Events/KeyHandledEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Hypercube.Input;
using Hypercube.Shared.EventBus.Events;

namespace Hypercube.Client.Input.Events;

public sealed class KeyHandledEvent : KeyStateChangedArgs, IEventArgs
{
public KeyHandledEvent(Key key, KeyState state, KeyModifiers modifiers, int scanCode) : base(key, state, modifiers, scanCode)
{
}
}
11 changes: 11 additions & 0 deletions Hypercube.Client/Input/Events/MouseButtonHandledEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Hypercube.Input;
using Hypercube.Shared.EventBus.Events;

namespace Hypercube.Client.Input.Events;

public class MouseButtonHandledEvent : MouseButtonChangedArgs, IEventArgs
{
public MouseButtonHandledEvent(MouseButton button, KeyState state, KeyModifiers modifiers) : base(button, state, modifiers)
{
}
}
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)
{
}
}
12 changes: 11 additions & 1 deletion Hypercube.Client/Input/Handler/IInputHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,15 @@ namespace Hypercube.Client.Input.Handler;
/// </summary>
public interface IInputHandler : IEventSubscriber
{
bool IsKeyDown(Key key);
bool IsKeyState(Key key, KeyState state);
bool IsKeyHeld(Key key);
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();
}
162 changes: 147 additions & 15 deletions Hypercube.Client/Input/Handler/InputHandler.cs
Original file line number Diff line number Diff line change
@@ -1,65 +1,197 @@
using Hypercube.Client.Input.Events.Windowing;
using System.Collections.Frozen;
using Hypercube.Client.Input.Events;
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 HashSet<Key> _keysRelease = [];
private readonly HashSet<Key> _keysPressed = [];
private readonly HashSet<Key> _keysDown = [];

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();

foreach (var key in _keys[KeyState.Held])
{
// Held event don't support modifiers yet, also scanCode
_eventBus.Raise(new KeyHandledEvent(key, KeyState.Held, KeyModifiers.None, 0));
}

_mouseButtons[KeyState.Pressed].Clear();
_mouseButtons[KeyState.Release].Clear();

foreach (var mouseButton in _mouseButtons[KeyState.Held])
{
// Held event don't support modifiers yet
_eventBus.Raise(new MouseButtonHandledEvent(mouseButton, KeyState.Held, KeyModifiers.None));
}
}

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

if (args.State == KeyState.Press)
switch (args.State)
{
_keysDown.Add(args.State.Key);
return;
case KeyState.Held:
return;

// Legacy shit, maybe will eat many ram and cpu
// We made many shit because fucking Key rollover: https://en.wikipedia.org/wiki/Key_rollover
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;

default:
throw new ArgumentOutOfRangeException();
}
_keysDown.Remove(args.State.Key);

_eventBus.Raise(new KeyHandledEvent(args.Key, args.State, args.Modifiers, args.ScanCode));
}

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.Held:
return;

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;

default:
throw new ArgumentOutOfRangeException();
}

_eventBus.Raise(new MouseButtonHandledEvent(args.Button, args.State, args.Modifiers));
}

private void OnScrollHandled(ref WindowingScrollHandledEvent args)
{
}

public bool IsKeyDown(Key key)
public bool IsKeyState(Key key, KeyState state)
{
return _keysDown.Contains(key);
return _keys[state].Contains(key);
}

public bool IsKeyHeld(Key key)
{
return IsKeyState(key, KeyState.Held);
}

public bool IsKeyPressed(Key key)
{
return IsKeyState(key, KeyState.Pressed);
}

public bool IsKeyReleased(Key key)
{
return IsKeyState(key, KeyState.Pressed);
}

public void KeyClear()
{
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();
}
}
}
4 changes: 2 additions & 2 deletions Hypercube.Example.Client/Controls/ControlsSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public override void FrameUpdate(UpdateFrameEvent args)
{
base.FrameUpdate(args);

var inputX = (_inputHandler.IsKeyDown(Key.D) ? 1 : 0) - (_inputHandler.IsKeyDown(Key.A) ? 1 : 0);
var inputY = (_inputHandler.IsKeyDown(Key.W) ? 1 : 0) - (_inputHandler.IsKeyDown(Key.S) ? 1 : 0);
var inputX = (_inputHandler.IsKeyHeld(Key.D) ? 1 : 0) - (_inputHandler.IsKeyHeld(Key.A) ? 1 : 0);
var inputY = (_inputHandler.IsKeyHeld(Key.W) ? 1 : 0) - (_inputHandler.IsKeyHeld(Key.S) ? 1 : 0);

foreach (var entity in GetEntities<ControlsComponent>())
{
Expand Down
4 changes: 2 additions & 2 deletions Hypercube.Input/KeyState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public enum KeyState
{
Release,
Press,
Repeat
Pressed,
Held
}
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
Loading
Loading