Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
MouseEventPoller.cs
1using System.Drawing;
3
5
12public sealed class MouseEventPoller : IDisposable
13{
19 public static MouseEventPoller? Instance { get; private set; }
20
36 public static void Initialize(IMouseAdapter adapter, MouseEventConfiguration? mouseEventConfiguration = null)
37 {
38 ArgumentNullException.ThrowIfNull(adapter);
39
40 if (mouseEventConfiguration == null)
41 {
42 mouseEventConfiguration = new MouseEventConfiguration(
43 trackMouseMovement: true,
44 secondsBetweenEvents: Engine.Instance.Configuration.TimeBetweenMouseEvents);
45 }
46
47 Instance?.Dispose();
48 Instance = new MouseEventPoller(adapter, mouseEventConfiguration);
49 }
50
52 public static void Reset()
53 {
54 Instance?.Dispose();
55 Instance = null;
56 }
57
65 public event Action<MouseEventArgs>? MouseEvent;
66
67 private readonly Dictionary<MouseButton, MouseButtonState> _buttonStates = new();
68 private Point _lastPosition = new(0, 0);
69 private int _lastScrollDelta;
70 private bool _isDisposed;
71
77 public IMouseAdapter? Adapter { get; private set; }
78
83 public MouseEventConfiguration? Configuration { get; private set; }
84
91 public Point CurrentPosition => Adapter?.CurrentPosition ?? default;
92
99
106 public IReadOnlyDictionary<MouseButton, MouseButtonState> ButtonStates => _buttonStates;
107
114 public int ScrollDelta => _lastScrollDelta;
115
116 private MouseEventPoller(IMouseAdapter adapter, MouseEventConfiguration? mouseEventConfiguration)
117 {
118 Adapter = adapter;
119 Configuration = mouseEventConfiguration;
120
121 foreach (MouseButton button in Enum.GetValues(typeof(MouseButton)))
122 {
123 if (button != MouseButton.None)
124 _buttonStates[button] = new MouseButtonState();
125 }
126 }
127
149 internal void PollForEvents(long tick)
150 {
151 if (Adapter is null) return;
152 if ((Configuration?.IsPaused ?? true) || !(Configuration?.ReadyForNextEvent(tick) ?? false)) return;
153
154 var currentPos = Adapter.CurrentPosition;
155 var pressed = Adapter.PressedButtons;
156 var scrollDelta = Adapter.ScrollDelta;
157
158 bool anyButtonChange = false;
159 bool isAnyButtonDown = false;
160
161 // update per-button state every cycle
162 foreach (var kvp in _buttonStates.ToList())
163 {
164 var button = kvp.Key;
165 var state = kvp.Value;
166
167 bool isCurrentlyDown = pressed.Contains(button);
168 bool justPressed = isCurrentlyDown && !state.IsDown;
169 bool justReleased = !isCurrentlyDown && state.IsDown;
170
171 state.JustPressed = justPressed;
172 state.JustReleased = justReleased;
173 state.IsDown = isCurrentlyDown;
174
175 anyButtonChange |= justPressed || justReleased;
176 _buttonStates[button] = state;
177
178 if (isCurrentlyDown)
179 isAnyButtonDown = true;
180 }
181
182 // now decide whether to emit an event
183 bool moved = (Configuration?.TrackMouseMovement ?? false) && _lastPosition != currentPos;
184 // Adapters supply accumulated movement since the last read. Equal deltas on
185 // consecutive polls are separate wheel inputs, not a held button state.
186 bool scrolled = scrollDelta != 0;
187 _lastScrollDelta = scrollDelta;
188
189 if (anyButtonChange || moved || scrolled || isAnyButtonDown)
190 {
191 MouseEvent?.Invoke(new MouseEventArgs(
195 _lastPosition,
196 currentPos,
197 scrollDelta,
198 tick));
199
200 _lastPosition = currentPos;
201 Configuration!._lastEventTick = tick;
202 }
203 }
204
226 public void StartMonitoringMouse(bool trackMouseMovement = true, double timeBetweenEvents = -1, bool isPaused = false)
227 {
228 if (timeBetweenEvents < 0)
229 timeBetweenEvents = Engine.Instance.Configuration.TimeBetweenMouseEvents;
230
231 Configuration = new MouseEventConfiguration(trackMouseMovement, timeBetweenEvents, isPaused);
232 }
233
240 public void StopMonitoringMouse() => Configuration = null;
241
243 public void Dispose()
244 {
245 if (_isDisposed) return;
246 _isDisposed = true;
247 (Adapter as IDisposable)?.Dispose();
248 Adapter = null;
249 Configuration = null;
250
251 if (ReferenceEquals(Instance, this))
252 Instance = null;
253 }
254}
Represents the core game engine singleton responsible for managing the main update loop,...
Definition Engine.cs:36
static Engine Instance
Gets the singleton instance of the Engine.
Definition Engine.cs:49
EngineConfiguration Configuration
Gets the current engine configuration settings.
Definition Engine.cs:928
Represents the configuration for mouse event monitoring, including movement tracking settings and tim...
static void Reset()
Disposes and clears the current singleton instance.
int ScrollDelta
Gets the most recent scroll wheel delta value captured during the last poll. Positive values indicate...
void StartMonitoringMouse(bool trackMouseMovement=true, double timeBetweenEvents=-1, bool isPaused=false)
Starts or reconfigures mouse input monitoring with the specified settings. This method creates a new ...
static void Initialize(IMouseAdapter adapter, MouseEventConfiguration? mouseEventConfiguration=null)
Initializes the singleton instance of the MouseEventPoller with the specified mouse adapter and optio...
KeyboardModifierState CurrentKeyboardModifiers
Gets the current state of keyboard modifier keys (Shift, Ctrl, Alt) at the time of the last poll....
MouseEventConfiguration? Configuration
Gets the current mouse event configuration, which controls movement tracking, throttling intervals,...
Action< MouseEventArgs >? MouseEvent
Occurs when mouse input is detected and the configuration allows the event to be raised based on thro...
IReadOnlyDictionary< MouseButton, MouseButtonState > ButtonStates
Gets a read-only dictionary containing the current state of all monitored mouse buttons,...
static ? MouseEventPoller Instance
Gets the singleton instance of the MouseEventPoller class. This instance is created through the Initi...
void Dispose()
Releases the current platform adapter when it supports disposal.
IMouseAdapter? Adapter
Gets the mouse adapter currently in use, which provides access to the underlying mouse hardware state...
Point CurrentPosition
Gets the current position of the mouse cursor in screen or client coordinates. If no adapter is confi...
void StopMonitoringMouse()
Stops monitoring mouse input by clearing the configuration. After calling this method,...
Defines an adapter interface for accessing mouse device state, including cursor position,...
int ScrollDelta
Gets the accumulated scroll wheel delta since the last poll, measured in implementation-defined units...
HashSet< MouseButton > PressedButtons
Gets the set of mouse buttons that are currently pressed. This collection includes identifiers for al...
Point CurrentPosition
Gets the current position of the mouse cursor in screen or client coordinates, depending on the imple...
KeyboardModifierState
Represents the state of keyboard modifier keys (Shift, Ctrl, Alt) that can be pressed simultaneously ...
MouseButton
Represents mouse button identifiers that can be used individually or combined to represent multiple s...
Represents the current and transitional state of a mouse button, tracking whether the button is curre...