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
TouchEventPoller.cs
2
4
23public sealed class TouchEventPoller : ITouchInput, IDisposable
24{
30 public static TouchEventPoller? Instance { get; private set; }
31
47 public static void Initialize(ITouchAdapter adapter, TouchEventConfiguration? config = null)
48 {
49 ArgumentNullException.ThrowIfNull(adapter);
50
51 config ??= new TouchEventConfiguration(
52 secondsBetweenEvents: Engine.Instance.Configuration.TimeBetweenTouchEvents);
53
54 Instance?.Dispose();
55 Instance = new TouchEventPoller(adapter, config);
56 }
57
61 public static void Reset()
62 {
63 Instance?.Dispose();
64 Instance = null;
65 }
66
67 private readonly Dictionary<int, TouchPoint> _activeTouches = new();
68 private TouchPoint[] _activeTouchesSnapshot = Array.Empty<TouchPoint>();
69
71 public IReadOnlyList<TouchPoint> ActiveTouches => _activeTouchesSnapshot;
72
78 public ITouchAdapter? Adapter { get; private set; }
79
84 public TouchEventConfiguration? Configuration { get; private set; }
85
87 public event EventHandler<TouchEventArgs>? TouchBegan;
88
90 public event EventHandler<TouchEventArgs>? TouchMoved;
91
93 public event EventHandler<TouchEventArgs>? TouchEnded;
94
109 public event Action<GestureEventArgs>? TouchEvent;
110
117
124
129 private bool _isDisposed;
130
132 {
133 Adapter = adapter;
134 Configuration = config;
135
139 TapRecognizer.CompetingSwipeRecognizer = SwipeRecognizer;
140
141 TapRecognizer.Tapped += (_, e) => TouchEvent?.Invoke(new GestureEventArgs(e));
142 SwipeRecognizer.Swiped += (_, e) => TouchEvent?.Invoke(new GestureEventArgs(e));
143 PinchRecognizer.PinchStarted += OnPinch;
144 PinchRecognizer.PinchUpdated += OnPinch;
145 PinchRecognizer.PinchEnded += OnPinch;
146 }
147
148 private void OnPinch(object? sender, PinchedEventArgs e)
149 => TouchEvent?.Invoke(new GestureEventArgs(e));
150
178 internal void PollForEvents(long tick)
179 {
180 if (_isDisposed || Adapter is null) return;
181
182 var began = Adapter.ConsumeBeganTouches();
183 var ended = Adapter.ConsumeEndedTouches();
184
185 // A paused/stopped poller deliberately establishes a new logical contact boundary.
186 // Drain transient queues, forget prior contacts, and begin fresh on resume.
187 if (Configuration is null || Configuration.IsPaused)
188 {
189 ClearContactState();
190 return;
191 }
192
193 // Lifecycle transitions are lossless and are never throttled.
194 foreach (var beganPoint in began)
195 {
196 if (_activeTouches.ContainsKey(beganPoint.Id))
197 continue;
198
199 var normalized = new TouchPoint(
200 beganPoint.Id,
201 beganPoint.Position,
202 TouchPhase.Began);
203
204 _activeTouches[normalized.Id] = normalized;
205 TouchBegan?.Invoke(this, new TouchEventArgs(normalized, tick));
206 }
207
208 foreach (var endedPoint in ended)
209 {
210 // A beginning and ending may both have occurred between engine polls. The queued
211 // beginning above ensures consumers still receive a complete lifecycle.
212 if (_activeTouches.Remove(endedPoint.Id))
213 TouchEnded?.Invoke(this, new TouchEventArgs(endedPoint, tick));
214 }
215
216 var currentActive = Adapter.ActiveTouches;
217
218 // Discover active contacts for adapters that use the default empty beginning queue.
219 foreach (var point in currentActive)
220 {
221 if (!_activeTouches.ContainsKey(point.Id))
222 {
223 var normalized = new TouchPoint(point.Id, point.Position, TouchPhase.Began);
224 _activeTouches[normalized.Id] = normalized;
225 TouchBegan?.Invoke(this, new TouchEventArgs(normalized, tick));
226 }
227 }
228
229 bool movementEmitted = false;
230 if (Configuration.ReadyForNextEvent(tick))
231 {
232 foreach (var point in currentActive)
233 {
234 if (!_activeTouches.TryGetValue(point.Id, out var known) ||
235 known.Position == point.Position)
236 continue;
237
238 var movedPoint = new TouchPoint(point.Id, point.Position, TouchPhase.Moved);
239 _activeTouches[point.Id] = movedPoint;
240 TouchMoved?.Invoke(this, new TouchEventArgs(movedPoint, tick));
241 movementEmitted = true;
242 }
243 }
244
245 _activeTouchesSnapshot = _activeTouches.Values.ToArray();
246
247 if (movementEmitted)
248 Configuration._lastEventTick = tick;
249 }
250
267 public void StartMonitoringTouch(double timeBetweenEvents = -1, bool isPaused = false)
268 {
269 if (timeBetweenEvents < 0)
270 timeBetweenEvents = Engine.Instance.Configuration.TimeBetweenTouchEvents;
271
272 Configuration = new TouchEventConfiguration(timeBetweenEvents, isPaused);
273 }
274
280 {
281 Configuration = null;
282 ClearContactState();
283 }
284
285 private void ClearContactState()
286 {
287 _activeTouches.Clear();
288 _activeTouchesSnapshot = Array.Empty<TouchPoint>();
289 TapRecognizer.Reset();
290 SwipeRecognizer.Reset();
291 PinchRecognizer.Reset();
292 }
293
297 public void Dispose()
298 {
299 if (_isDisposed)
300 return;
301
302 _isDisposed = true;
303
304 TapRecognizer.Dispose();
305 SwipeRecognizer.Dispose();
306 PinchRecognizer.PinchStarted -= OnPinch;
307 PinchRecognizer.PinchUpdated -= OnPinch;
308 PinchRecognizer.PinchEnded -= OnPinch;
309 PinchRecognizer.Dispose();
310
311 (Adapter as IDisposable)?.Dispose();
312 Adapter = null;
313 Configuration = null;
314 _activeTouches.Clear();
315 _activeTouchesSnapshot = Array.Empty<TouchPoint>();
316
317 if (ReferenceEquals(Instance, this))
318 Instance = null;
319 }
320}
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
Provides data for the TouchEventPoller.TouchEvent, carrying the details of a recognized gesture....
Recognizes two-finger pinch and spread gestures by listening to touch events from an ITouchInput sour...
Provides data for the PinchGestureRecognizer.PinchUpdated event, describing the change in scale produ...
Recognizes swipe gestures by listening to touch events from an ITouchInput source....
Recognizes single-finger tap gestures by listening to touch events from an ITouchInput source....
Provides data for touch contact events raised by ITouchInput, including the touch point and engine ti...
Represents the configuration for touch event monitoring, including timing controls for movement-event...
Provides centralized polling and event management for touch input. This singleton class monitors touc...
EventHandler< TouchEventArgs >? TouchBegan
static void Reset()
Disposes and clears the current singleton instance, including its adapter.
TouchEventConfiguration? Configuration
Gets the current touch event configuration, which controls movement-event throttling and pause state....
Action< GestureEventArgs >? TouchEvent
Occurs when any recognized gesture — tap, swipe, or pinch — is detected. Inspect GestureEventArgs....
EventHandler< TouchEventArgs >? TouchMoved
void Dispose()
Releases recognizers and the current platform adapter.
EventHandler< TouchEventArgs >? TouchEnded
PinchGestureRecognizer PinchRecognizer
Gets the pinch gesture recognizer used by this poller.
void StartMonitoringTouch(double timeBetweenEvents=-1, bool isPaused=false)
Starts or reconfigures touch input monitoring with the specified settings. This method creates a new ...
static ? TouchEventPoller Instance
Gets the singleton instance of the TouchEventPoller class. This instance is created through the Initi...
ITouchAdapter? Adapter
Gets the touch adapter currently in use, which provides access to the underlying touch state includin...
TapGestureRecognizer TapRecognizer
Gets the tap gesture recognizer used by this poller. Adjust TapGestureRecognizer.MaxTapDurationSecond...
static void Initialize(ITouchAdapter adapter, TouchEventConfiguration? config=null)
Initializes the singleton instance of the TouchEventPoller with the specified touch adapter and optio...
void StopMonitoringTouch()
Stops monitoring touch input by clearing the configuration. After calling this method,...
IReadOnlyList< TouchPoint > ActiveTouches
Gets the list of touch contact points that are currently active (in contact with the surface)....
SwipeGestureRecognizer SwipeRecognizer
Gets the swipe gesture recognizer used by this poller. Adjust SwipeGestureRecognizer....
Defines a passive adapter interface for accessing touch device state. Implementations update their in...
IReadOnlyList< TouchPoint > ConsumeEndedTouches()
Drains and returns all touch contacts that ended (lifted or cancelled) since the last call....
IReadOnlyList< TouchPoint > ConsumeBeganTouches()
Drains and returns all touch contacts that began since the last call. Keeping beginnings in a queue p...
Represents a touch input source that tracks active contact points and raises lifecycle events when fi...
readonly record struct TouchPoint(int Id, Point Position, TouchPhase Phase)
Represents a single touch contact point, capturing its unique identifier, screen position,...
TouchPhase
Describes the current phase of a single touch contact point in its lifecycle.
Definition TouchPhase.cs:7