Skip to content

Commit

Permalink
Another refactoring: make sure input events are processed even if a w…
Browse files Browse the repository at this point in the history
…idget was removed from the desktop
  • Loading branch information
rds1983 committed Nov 8, 2023
1 parent 18459a7 commit d2f9caf
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 190 deletions.
85 changes: 35 additions & 50 deletions src/Myra/Graphics2D/UI/Desktop.Input.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Myra.Utility;
using System;
using System.Collections.Generic;
using Myra.Events;

#if MONOGAME || FNA
Expand Down Expand Up @@ -31,7 +30,7 @@ public struct MouseInfo
public float Wheel;
}

partial class Desktop
partial class Desktop: IInputEventsProcessor
{
private MouseInfo _lastMouseInfo;
private DateTime? _lastKeyDown;
Expand All @@ -40,8 +39,6 @@ partial class Desktop
private Point _mousePosition;
private Point? _touchPosition;
private float _mouseWheelDelta;
private readonly List<InputEventType> _scheduledInputEvents = new List<InputEventType>();
private readonly List<InputEventType> _scheduledInputEventsCopy = new List<InputEventType>();

public Point PreviousMousePosition { get; private set; }
public Point? PreviousTouchPosition { get; private set; }
Expand All @@ -57,7 +54,7 @@ private set
}

_mousePosition = value;
_scheduledInputEvents.Add(InputEventType.MouseMoved);
InputEventsManager.QueueMouseMoved(this);
}
}

Expand All @@ -77,16 +74,16 @@ private set

if (value != null && oldValue == null)
{
_scheduledInputEvents.Add(InputEventType.TouchDown);
InputEventsManager.QueueTouchDown(this);
}
else if (value == null && oldValue != null)
{
_scheduledInputEvents.Add(InputEventType.TouchUp);
InputEventsManager.QueueTouchUp(this);
}
else if (value != null && oldValue != null &&
value.Value != oldValue.Value)
{
_scheduledInputEvents.Add(InputEventType.TouchMoved);
InputEventsManager.QueueTouchMoved(this);
}
}
}
Expand All @@ -103,7 +100,7 @@ public float MouseWheelDelta

if (!value.IsZero())
{
_scheduledInputEvents.Add(InputEventType.MouseWheel);
InputEventsManager.QueueMouseWheel(this);
}
}
}
Expand Down Expand Up @@ -283,49 +280,37 @@ public void UpdateInput()
}
}

public void ProcessInputEvents()
void IInputEventsProcessor.ProcessEvent(InputEventType eventType)
{
if (_scheduledInputEvents.Count == 0)
switch (eventType)
{
return;
}

_scheduledInputEventsCopy.Clear();
_scheduledInputEventsCopy.AddRange(_scheduledInputEvents);
_scheduledInputEvents.Clear();

foreach (var inputEventType in _scheduledInputEventsCopy)
{
switch (inputEventType)
{
case InputEventType.MouseLeft:
break;
case InputEventType.MouseEntered:
break;
case InputEventType.MouseMoved:
MouseMoved.Invoke(this);
break;
case InputEventType.MouseWheel:
MouseWheelChanged.Invoke(this, MouseWheelDelta);
break;
case InputEventType.TouchLeft:
break;
case InputEventType.TouchEntered:
break;
case InputEventType.TouchMoved:
TouchMoved.Invoke(this);
break;
case InputEventType.TouchDown:
InputOnTouchDown();
TouchDown.Invoke(this);
break;
case InputEventType.TouchUp:
TouchUp.Invoke(this);
break;
case InputEventType.TouchDoubleClick:
TouchDoubleClick.Invoke(this);
break;
}
case InputEventType.MouseLeft:
break;
case InputEventType.MouseEntered:
break;
case InputEventType.MouseMoved:
MouseMoved.Invoke(this);
break;
case InputEventType.MouseWheel:
MouseWheelChanged.Invoke(this, MouseWheelDelta);
break;
case InputEventType.TouchLeft:
break;
case InputEventType.TouchEntered:
break;
case InputEventType.TouchMoved:
TouchMoved.Invoke(this);
break;
case InputEventType.TouchDown:
InputOnTouchDown();
TouchDown.Invoke(this);
break;
case InputEventType.TouchUp:
TouchUp.Invoke(this);
break;
case InputEventType.TouchDoubleClick:
TouchDoubleClick.Invoke(this);
break;
}
}
}
Expand Down
11 changes: 2 additions & 9 deletions src/Myra/Graphics2D/UI/Desktop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -527,18 +527,11 @@ public void Render()
// So scheduling it here
if (_inputContext.MouseWheelWidget != null)
{
_inputContext.MouseWheelWidget.ScheduleInputEvent(InputEventType.MouseWheel);
InputEventsManager.QueueMouseWheel(_inputContext.MouseWheelWidget);
}

// Second input run: process input events
ProcessInputEvents();

childrenCopy = ChildrenCopy;
for (var i = childrenCopy.Count - 1; i >= 0; --i)
{
var widget = childrenCopy[i];
widget.ProcessInputEvents();
}
InputEventsManager.ProcessEvents();

// Do another layout run, since an input event could cause the layout change
UpdateLayout();
Expand Down
16 changes: 0 additions & 16 deletions src/Myra/Graphics2D/UI/InputEventType.cs

This file was deleted.

112 changes: 112 additions & 0 deletions src/Myra/Graphics2D/UI/InputEventsManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System.Collections.Generic;

#if MONOGAME || FNA
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
#elif STRIDE
using Stride.Core.Mathematics;
using Stride.Input;
#else
using System.Numerics;
using System.Drawing;
using Myra.Platform;
#endif

namespace Myra.Graphics2D.UI
{
internal enum InputEventType
{
MouseLeft,
MouseEntered,
MouseMoved,
MouseWheel,
TouchLeft,
TouchEntered,
TouchMoved,
TouchDown,
TouchUp,
TouchDoubleClick
}

internal interface IInputEventsProcessor
{
void ProcessEvent(InputEventType eventType);
}

internal static class InputEventsManager
{
private struct InputEvent
{
public IInputEventsProcessor Processor;
public InputEventType Type;

public InputEvent(IInputEventsProcessor processor, InputEventType type)
{
Processor = processor;
Type = type;
}
}

private static readonly Queue<InputEvent> _events = new Queue<InputEvent>();

public static void QueueMouseLeft(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.MouseLeft));
}

public static void QueueMouseEntered(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.MouseEntered));
}

public static void QueueMouseMoved(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.MouseMoved));
}

public static void QueueMouseWheel(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.MouseWheel));
}

public static void QueueTouchLeft(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.TouchLeft));
}

public static void QueueTouchEntered(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.TouchEntered));
}

public static void QueueTouchMoved(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.TouchMoved));
}

public static void QueueTouchDown(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.TouchDown));
}

public static void QueueTouchUp(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.TouchUp));
}

public static void QueueTouchDoubleClick(IInputEventsProcessor processor)
{
_events.Enqueue(new InputEvent(processor, InputEventType.TouchDoubleClick));
}

public static void ProcessEvents()
{
while(_events.Count > 0)
{
var ev = _events.Dequeue();

ev.Processor.ProcessEvent(ev.Type);
}
}
}
}
Loading

0 comments on commit d2f9caf

Please sign in to comment.