simconnect_sdk/domain/client_event.rs
1use std::os::raw::c_char;
2
3use crate::{bindings, SimConnectError};
4
5// System Events start from 0 so we have to stagger the values to avoid collisions.
6pub(crate) const CLIENT_EVENT_DISCRIMINANT_START: u32 = 1024;
7
8/// SimConnect Client Event Request.
9///
10/// Defined by <https://www.prepar3d.com/SDKv5/sdk/references/variables/event_ids.html>.
11/// Extended by <https://docs.flightsimulator.com/html/Programming_Tools/Event_IDs/Event_IDs.htm>.
12#[derive(Debug, Copy, Clone, PartialEq, Eq, num_enum::TryFromPrimitive)]
13#[repr(u32)]
14#[non_exhaustive]
15pub enum ClientEventRequest {
16 // ---------------
17 // Aircraft Engine
18 // ---------------
19 /// Set throttle 1 exactly (0 to 16383).
20 Throttle1Set = CLIENT_EVENT_DISCRIMINANT_START,
21 /// Set throttle 2 exactly (0 to 16383).
22 Throttle2Set,
23 /// Set throttle 3 exactly (0 to 16383).
24 Throttle3Set,
25 /// Set throttle 4 exactly (0 to 16383).
26 Throttle4Set,
27 // ---------------
28 // Aircraft Flight Controls
29 // ---------------
30 /// Sets elevator position (-16383 - +16383).
31 AxisElevatorSet,
32 // ---------------
33 // Aircraft Miscellaneous Systems
34 // ---------------
35 /// Increment brake pressure. Note: These are simulated spring-loaded toe brakes, which will bleed back to zero over time.
36 Brakes,
37 /// Increments left brake pressure. Note: This is a simulated spring-loaded toe brake, which will bleed back to zero over time.
38 BrakesLeft,
39 /// Increments right brake pressure. Note: This is a simulated spring-loaded toe brake, which will bleed back to zero over time.
40 BrakesRight,
41 /// Sets left brake position from axis controller (e.g. joystick). -16383 (0 brakes) to +16383 (max brakes).
42 AxisLeftBrakeSet,
43 /// Sets right brake position from axis controller (e.g. joystick). -16383 (0 brakes) to +16383 (max brakes).
44 AxisRightBrakeSet,
45 /// Toggles parking brake on/off.
46 ParkingBrakes,
47}
48
49impl ClientEventRequest {
50 pub(crate) fn into_c_char(self) -> *const c_char {
51 match self {
52 // Aircraft Engine
53 Self::Throttle1Set => c"THROTTLE1_SET".as_ptr() as *const c_char,
54 Self::Throttle2Set => c"THROTTLE2_SET".as_ptr() as *const c_char,
55 Self::Throttle3Set => c"THROTTLE3_SET".as_ptr() as *const c_char,
56 Self::Throttle4Set => c"THROTTLE4_SET".as_ptr() as *const c_char,
57 // Aircraft Flight Controls
58 Self::AxisElevatorSet => c"AXIS_ELEVATOR_SET".as_ptr() as *const c_char,
59 // Aircraft Miscellaneous Systems
60 Self::Brakes => c"BRAKES".as_ptr() as *const c_char,
61 Self::BrakesLeft => c"BRAKES_LEFT".as_ptr() as *const c_char,
62 Self::BrakesRight => c"BRAKES_RIGHT".as_ptr() as *const c_char,
63 Self::AxisLeftBrakeSet => c"AXIS_LEFT_BRAKE_SET".as_ptr() as *const c_char,
64 Self::AxisRightBrakeSet => c"AXIS_RIGHT_BRAKE_SET".as_ptr() as *const c_char,
65 Self::ParkingBrakes => c"PARKING_BRAKES".as_ptr() as *const c_char,
66 }
67 }
68}
69
70/// SimConnect Client Event.
71///
72/// Defined by <https://www.prepar3d.com/SDKv5/sdk/references/variables/event_ids.html>.
73/// Extended by <https://docs.flightsimulator.com/html/Programming_Tools/Event_IDs/Event_IDs.htm>.
74#[derive(Debug, Copy, Clone, PartialEq, Eq)]
75#[non_exhaustive]
76pub enum ClientEvent {
77 // ---------------
78 // Aircraft Engine
79 // ---------------
80 /// Set throttle 1 exactly (0 to 16383).
81 Throttle1Set {
82 /// -16383 (0 throttle) to +16383 (max throttle).
83 value: i32,
84 },
85 /// Set throttle 2 exactly (0 to 16383).
86 Throttle2Set {
87 /// -16383 (0 throttle) to +16383 (max throttle).
88 value: i32,
89 },
90 /// Set throttle 3 exactly (0 to 16383).
91 Throttle3Set {
92 /// -16383 (0 throttle) to +16383 (max throttle).
93 value: i32,
94 },
95 /// Set throttle 4 exactly (0 to 16383).
96 Throttle4Set {
97 /// -16383 (0 throttle) to +16383 (max throttle).
98 value: i32,
99 },
100 // ---------------
101 // Aircraft Flight Controls
102 // ---------------
103 /// Sets elevator position (-16383 - +16383).
104 AxisElevatorSet {
105 /// -16383 (full down) to +16383 (full up).
106 value: i32,
107 },
108 // ---------------
109 // Aircraft Miscellaneous Systems
110 // ---------------
111 /// Increment brake pressure. Note: These are simulated spring-loaded toe brakes, which will bleed back to zero over time.
112 Brakes,
113 /// Increments left brake pressure. Note: This is a simulated spring-loaded toe brake, which will bleed back to zero over time.
114 BrakesLeft,
115 /// Increments right brake pressure. Note: This is a simulated spring-loaded toe brake, which will bleed back to zero over time.
116 BrakesRight,
117 /// Sets left brake position from axis controller (e.g. joystick). -16383 (0 brakes) to +16383 (max brakes).
118 AxisLeftBrakeSet {
119 /// -16383 (0 brakes) to +16383 (max brakes).
120 value: i32,
121 },
122 /// Sets right brake position from axis controller (e.g. joystick). -16383 (0 brakes) to +16383 (max brakes).
123 AxisRightBrakeSet {
124 /// -16383 (0 brakes) to +16383 (max brakes).
125 value: i32,
126 },
127 /// Toggles parking brake on/off.
128 ParkingBrakes,
129}
130
131impl TryFrom<&bindings::SIMCONNECT_RECV_EVENT> for ClientEvent {
132 type Error = SimConnectError;
133
134 fn try_from(event: &bindings::SIMCONNECT_RECV_EVENT) -> Result<Self, Self::Error> {
135 let request = ClientEventRequest::try_from(event.uEventID)
136 .map_err(|_| SimConnectError::UnimplementedEventType(event.uEventID))?;
137
138 match request {
139 // Aircraft Engine
140 ClientEventRequest::Throttle1Set => Ok(Self::Throttle1Set {
141 value: event.dwData as i32,
142 }),
143 ClientEventRequest::Throttle2Set => Ok(Self::Throttle2Set {
144 value: event.dwData as i32,
145 }),
146 ClientEventRequest::Throttle3Set => Ok(Self::Throttle3Set {
147 value: event.dwData as i32,
148 }),
149 ClientEventRequest::Throttle4Set => Ok(Self::Throttle4Set {
150 value: event.dwData as i32,
151 }),
152 // Aircraft Flight Controls
153 ClientEventRequest::AxisElevatorSet => Ok(Self::AxisElevatorSet {
154 value: event.dwData as i32,
155 }),
156 // Aircraft Miscellaneous Systems
157 ClientEventRequest::Brakes => Ok(Self::Brakes),
158 ClientEventRequest::BrakesLeft => Ok(Self::BrakesLeft),
159 ClientEventRequest::BrakesRight => Ok(Self::BrakesRight),
160 ClientEventRequest::AxisLeftBrakeSet => Ok(Self::AxisLeftBrakeSet {
161 value: event.dwData as i32,
162 }),
163 ClientEventRequest::AxisRightBrakeSet => Ok(Self::AxisRightBrakeSet {
164 value: event.dwData as i32,
165 }),
166 ClientEventRequest::ParkingBrakes => Ok(Self::ParkingBrakes),
167 }
168 }
169}
170
171impl From<ClientEvent> for (ClientEventRequest, i32) {
172 fn from(event: ClientEvent) -> Self {
173 match event {
174 // Aircraft Engine
175 ClientEvent::Throttle1Set { value } => (ClientEventRequest::Throttle1Set, value),
176 ClientEvent::Throttle2Set { value } => (ClientEventRequest::Throttle2Set, value),
177 ClientEvent::Throttle3Set { value } => (ClientEventRequest::Throttle3Set, value),
178 ClientEvent::Throttle4Set { value } => (ClientEventRequest::Throttle4Set, value),
179 // Aircraft Flight Controls
180 ClientEvent::AxisElevatorSet { value } => (ClientEventRequest::AxisElevatorSet, value),
181 // Aircraft Miscellaneous Systems
182 ClientEvent::Brakes => (ClientEventRequest::Brakes, 0),
183 ClientEvent::BrakesLeft => (ClientEventRequest::BrakesLeft, 0),
184 ClientEvent::BrakesRight => (ClientEventRequest::BrakesRight, 0),
185 ClientEvent::AxisLeftBrakeSet { value } => {
186 (ClientEventRequest::AxisLeftBrakeSet, value)
187 }
188 ClientEvent::AxisRightBrakeSet { value } => {
189 (ClientEventRequest::AxisRightBrakeSet, value)
190 }
191 ClientEvent::ParkingBrakes => (ClientEventRequest::ParkingBrakes, 0),
192 }
193 }
194}