|
2 | 2 | // Copyright (c) BARS. All rights reserved. |
3 | 3 | // </copyright> |
4 | 4 |
|
5 | | -using System; |
6 | 5 | using System.Runtime.InteropServices; |
7 | 6 | using System.Threading; |
8 | 7 | using System.Threading.Tasks; |
@@ -70,6 +69,11 @@ public SimConnectClient(string applicationName = "SimConnect.NET Client") |
70 | 69 | /// </summary> |
71 | 70 | public event EventHandler<RawSimConnectMessageEventArgs>? RawMessageReceived; |
72 | 71 |
|
| 72 | + /// <summary> |
| 73 | + /// Occurs when a subscribed event is fired. |
| 74 | + /// </summary> |
| 75 | + public event EventHandler<SimSystemEventReceivedEventArgs>? SystemEventReceived; |
| 76 | + |
73 | 77 | /// <summary> |
74 | 78 | /// Gets a value indicating whether the client is connected to SimConnect. |
75 | 79 | /// </summary> |
@@ -345,6 +349,40 @@ public async Task DisconnectAsync() |
345 | 349 | } |
346 | 350 | } |
347 | 351 |
|
| 352 | + /// <summary> |
| 353 | + /// Subscribes to a specific simulator system event. |
| 354 | + /// </summary> |
| 355 | + /// <param name="systemEventName">The name of the system event (e.g., "SimStart", "4Sec", "Crashed").</param> |
| 356 | + /// <param name="systemEventId">A user-defined ID to identify this subscription.</param> |
| 357 | + /// <param name="cancellationToken">Cancellation token for the operation.</param> |
| 358 | + /// <returns>A task representing the event.</returns> |
| 359 | + /// <exception cref="InvalidOperationException">Thrown when a sim connection wasn't found.</exception> |
| 360 | + /// <exception cref="SimConnectException">Thrown when the event wasn't subscribed.</exception> |
| 361 | + public async Task SubscribeToEventAsync(string systemEventName, uint systemEventId, CancellationToken cancellationToken = default) |
| 362 | + { |
| 363 | + ObjectDisposedException.ThrowIf(this.disposed, nameof(SimConnectClient)); |
| 364 | + |
| 365 | + if (!this.isConnected) |
| 366 | + { |
| 367 | + throw new InvalidOperationException("Not connected to SimConnect."); |
| 368 | + } |
| 369 | + |
| 370 | + await Task.Run( |
| 371 | + () => |
| 372 | + { |
| 373 | + var result = SimConnectNative.SimConnect_SubscribeToSystemEvent( |
| 374 | + this.simConnectHandle, |
| 375 | + systemEventId, |
| 376 | + systemEventName); |
| 377 | + |
| 378 | + if (result != (int)SimConnectError.None) |
| 379 | + { |
| 380 | + throw new SimConnectException($"Failed to subscribe to event {systemEventName}: {(SimConnectError)result}", (SimConnectError)result); |
| 381 | + } |
| 382 | + }, |
| 383 | + cancellationToken).ConfigureAwait(false); |
| 384 | + } |
| 385 | + |
348 | 386 | /// <summary> |
349 | 387 | /// Processes the next SimConnect message. |
350 | 388 | /// </summary> |
@@ -419,6 +457,9 @@ public async Task<bool> ProcessNextMessageAsync(CancellationToken cancellationTo |
419 | 457 | case SimConnectRecvId.VorList: |
420 | 458 | case SimConnectRecvId.NdbList: |
421 | 459 | break; |
| 460 | + case SimConnectRecvId.Event: |
| 461 | + this.ProcessSystemEvent(ppData); |
| 462 | + break; |
422 | 463 | default: |
423 | 464 | this.simVarManager?.ProcessReceivedData(ppData, pcbData); |
424 | 465 | break; |
@@ -543,6 +584,29 @@ private void ProcessOpen(IntPtr ppData) |
543 | 584 | } |
544 | 585 | } |
545 | 586 |
|
| 587 | + /// <summary> |
| 588 | + /// Processes a system event message from SimConnect. |
| 589 | + /// </summary> |
| 590 | + /// <param name="ppData">Pointer to the received Event data.</param> |
| 591 | + private void ProcessSystemEvent(IntPtr ppData) |
| 592 | + { |
| 593 | + try |
| 594 | + { |
| 595 | + var recvEvent = Marshal.PtrToStructure<SimConnectRecvEvent>(ppData); |
| 596 | + |
| 597 | + this.SystemEventReceived?.Invoke(this, new SimSystemEventReceivedEventArgs(recvEvent.EventId, recvEvent.Data)); |
| 598 | + |
| 599 | + if (SimConnectLogger.IsLevelEnabled(SimConnectLogger.LogLevel.Debug)) |
| 600 | + { |
| 601 | + SimConnectLogger.Debug($"System Event Received: ID={recvEvent.EventId} Data={recvEvent.Data}"); |
| 602 | + } |
| 603 | + } |
| 604 | + catch (Exception ex) when (!ExceptionHelper.IsCritical(ex)) |
| 605 | + { |
| 606 | + SimConnectLogger.Error("Error processing system event", ex); |
| 607 | + } |
| 608 | + } |
| 609 | + |
546 | 610 | /// <summary> |
547 | 611 | /// Starts the background message processing loop. |
548 | 612 | /// </summary> |
|
0 commit comments