Files
RobustToolbox/Robust.Client/Graphics/Clyde/Clyde.Events.cs
Pieter-Jan Briers a4a7e754af GetKeyName improvements
Rewrote most of the related code, moved code out of windowing API backends.
SDL2 backend now handles key map change events correctly.
2023-02-06 23:11:53 +01:00

185 lines
6.3 KiB
C#

// Makes switching easier.
#if EXCEPTION_TOLERANCE
#define EXCEPTION_TOLERANCE_LOCAL
using System;
using Robust.Shared.Log;
#endif
using System.Collections.Generic;
using OpenToolkit.Graphics.OpenGL4;
using Robust.Client.Input;
using Robust.Shared.Maths;
namespace Robust.Client.Graphics.Clyde
{
internal sealed partial class Clyde
{
// To avoid re-entrancy bollocks we need ANOTHER queue here to actually dispatch our raw input events.
// Yes, on top of the two queues inside the GLFW impl.
// Because the GLFW-impl queue has to get flushed to avoid deadlocks on window creation
// which is ALSO where key events get raised from in a re-entrant fashion. Yay.
private readonly Queue<DEventBase> _eventDispatchQueue = new();
private void DispatchEvents()
{
while (_eventDispatchQueue.TryDequeue(out var ev))
{
#if EXCEPTION_TOLERANCE_LOCAL
try
#endif
{
DispatchSingleEvent(ev);
}
#if EXCEPTION_TOLERANCE_LOCAL
catch (Exception e)
{
Logger.ErrorS("clyde.win", $"Error dispatching window event {ev.GetType().Name}:\n{e}");
}
#endif
}
}
private void DispatchSingleEvent(DEventBase ev)
{
switch (ev)
{
case DEventKeyDown(var args):
KeyDown?.Invoke(args);
break;
case DEventKeyUp(var args):
KeyUp?.Invoke(args);
break;
case DEventMouseMove(var args):
MouseMove?.Invoke(args);
break;
case DEventMouseEnterLeave(var args):
MouseEnterLeave?.Invoke(args);
break;
case DEventScroll(var args):
MouseWheel?.Invoke(args);
break;
case DEventText(var args):
TextEntered?.Invoke(args);
break;
case DEventTextEditing(var args):
TextEditing?.Invoke(args);
break;
case DEventWindowClosed(var reg, var args):
reg.RequestClosed?.Invoke(args);
CloseWindow?.Invoke(args);
if (reg.DisposeOnClose && !reg.IsMainWindow)
DoDestroyWindow(reg);
break;
case DEventWindowContentScaleChanged(var args):
OnWindowScaleChanged?.Invoke(args);
break;
case DEventWindowFocus(var args):
OnWindowFocused?.Invoke(args);
break;
case DEventWindowResized(var reg, var args):
reg.Resized?.Invoke(args);
OnWindowResized?.Invoke(args);
break;
case DEventInputModeChanged:
RaiseInputModeChanged();
break;
}
}
private void SendKeyUp(KeyEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventKeyUp(ev));
}
private void SendKeyDown(KeyEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventKeyDown(ev));
}
private void SendScroll(MouseWheelEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventScroll(ev));
}
private void SendCloseWindow(WindowReg windowReg, WindowRequestClosedEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventWindowClosed(windowReg, ev));
}
private void SendWindowResized(WindowReg reg, Vector2i oldSize)
{
var loaded = RtToLoaded(reg.RenderTarget);
loaded.Size = reg.FramebufferSize;
_glContext!.WindowResized(reg, oldSize);
var eventArgs = new WindowResizedEventArgs(
oldSize,
reg.FramebufferSize,
reg.Handle);
_eventDispatchQueue.Enqueue(new DEventWindowResized(reg, eventArgs));
}
private void SendWindowContentScaleChanged(WindowContentScaleEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventWindowContentScaleChanged(ev));
}
private void SendWindowFocus(WindowFocusedEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventWindowFocus(ev));
}
private void SendText(TextEnteredEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventText(ev));
}
private void SendTextEditing(TextEditingEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventTextEditing(ev));
}
private void SendMouseMove(MouseMoveEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventMouseMove(ev));
}
private void SendMouseEnterLeave(MouseEnterLeaveEventArgs ev)
{
_eventDispatchQueue.Enqueue(new DEventMouseEnterLeave(ev));
}
private void SendInputModeChanged()
{
_eventDispatchQueue.Enqueue(new DEventInputModeChanged());
}
// D stands for Dispatch
private abstract record DEventBase;
private sealed record DEventKeyUp(KeyEventArgs Args) : DEventBase;
private sealed record DEventKeyDown(KeyEventArgs Args) : DEventBase;
private sealed record DEventScroll(MouseWheelEventArgs Args) : DEventBase;
private sealed record DEventWindowClosed(WindowReg Reg, WindowRequestClosedEventArgs Args) : DEventBase;
private sealed record DEventWindowResized(WindowReg Reg, WindowResizedEventArgs Args) : DEventBase;
private sealed record DEventWindowContentScaleChanged(WindowContentScaleEventArgs Args) : DEventBase;
private sealed record DEventWindowFocus(WindowFocusedEventArgs Args) : DEventBase;
private sealed record DEventText(TextEnteredEventArgs Args) : DEventBase;
private sealed record DEventTextEditing(TextEditingEventArgs Args) : DEventBase;
private sealed record DEventMouseMove(MouseMoveEventArgs Args) : DEventBase;
private sealed record DEventMouseEnterLeave(MouseEnterLeaveEventArgs Args) : DEventBase;
private sealed record DEventInputModeChanged : DEventBase;
}
}