1use std::os::raw::c_char;
2
3use crate::{bindings, fixed_c_str_to_string, SimConnectError};
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq, num_enum::TryFromPrimitive)]
7#[repr(u32)]
8#[non_exhaustive]
9pub enum SystemEventRequest {
10 OneSecond = 0,
12 FourSeconds,
14 SixTimesPerSecond,
16 AircraftLoaded,
18 Crashed,
20 CrashReset,
22 FlightLoaded,
24 FlightSaved,
26 FlightPlanActivated,
28 FlightPlanDeactivated,
30 Frame,
32 Pause,
34 Paused,
36 PauseFrame,
38 PositionChanged,
40 Sim,
42 SimStart,
44 SimStop,
46 Sound,
48 Unpaused,
50 View,
52}
53
54impl SystemEventRequest {
55 pub(crate) fn into_c_char(self) -> *const c_char {
56 match self {
57 SystemEventRequest::OneSecond => c"1sec".as_ptr() as *const c_char,
58 SystemEventRequest::FourSeconds => c"4sec".as_ptr() as *const c_char,
59 SystemEventRequest::SixTimesPerSecond => c"6Hz".as_ptr() as *const c_char,
60 SystemEventRequest::AircraftLoaded => c"AircraftLoaded".as_ptr() as *const c_char,
61 SystemEventRequest::Crashed => c"Crashed".as_ptr() as *const c_char,
62 SystemEventRequest::CrashReset => c"CrashReset".as_ptr() as *const c_char,
63 SystemEventRequest::FlightLoaded => c"FlightLoaded".as_ptr() as *const c_char,
64 SystemEventRequest::FlightSaved => c"FlightSaved".as_ptr() as *const c_char,
65 SystemEventRequest::FlightPlanActivated => {
66 c"FlightPlanActivated".as_ptr() as *const c_char
67 }
68 SystemEventRequest::FlightPlanDeactivated => {
69 c"FlightPlanDeactivated".as_ptr() as *const c_char
70 }
71 SystemEventRequest::Frame => c"Frame".as_ptr() as *const c_char,
72 SystemEventRequest::Pause => c"Pause".as_ptr() as *const c_char,
73 SystemEventRequest::Paused => c"Paused".as_ptr() as *const c_char,
74 SystemEventRequest::PauseFrame => c"PauseFrame".as_ptr() as *const c_char,
75 SystemEventRequest::PositionChanged => c"PositionChanged".as_ptr() as *const c_char,
76 SystemEventRequest::Sim => c"Sim".as_ptr() as *const c_char,
77 SystemEventRequest::SimStart => c"SimStart".as_ptr() as *const c_char,
78 SystemEventRequest::SimStop => c"SimStop".as_ptr() as *const c_char,
79 SystemEventRequest::Sound => c"Sound".as_ptr() as *const c_char,
80 SystemEventRequest::Unpaused => c"Unpaused".as_ptr() as *const c_char,
81 SystemEventRequest::View => c"View".as_ptr() as *const c_char,
82 }
83 }
84}
85
86#[derive(Debug, Copy, Clone, PartialEq, Eq, num_enum::TryFromPrimitive)]
88#[repr(u32)]
89pub enum ViewType {
90 None = 0,
92 Cockpit2D = bindings::SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_2D,
94 CockpitVirtual = bindings::SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_VIRTUAL,
96 Orthogonal = bindings::SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_ORTHOGONAL,
98}
99
100#[derive(Debug, Clone, PartialEq)]
102#[non_exhaustive]
103pub enum SystemEvent {
104 OneSecond,
106 FourSeconds,
108 SixTimesPerSecond,
110 AircraftLoaded {
112 file_name: String,
114 },
115 Crashed,
117 CrashReset,
119 FlightLoaded {
121 file_name: String,
123 },
124 FlightSaved {
126 file_name: String,
128 },
129 FlightPlanActivated {
131 file_name: String,
133 },
134 FlightPlanDeactivated,
136 Frame {
138 frame_rate: f32,
140 sim_speed: f32,
142 },
143 Pause {
145 state: bool,
147 },
148 Paused,
150 PauseFrame {
152 frame_rate: f32,
154 sim_speed: f32,
156 },
157 PositionChanged,
159 Sim {
161 state: bool,
163 },
164 SimStart,
166 SimStop,
168 Sound {
170 state: bool,
172 },
173 Unpaused,
175 View {
177 view: ViewType,
179 },
180}
181
182impl TryFrom<&bindings::SIMCONNECT_RECV_EVENT> for SystemEvent {
183 type Error = SimConnectError;
184
185 fn try_from(event: &bindings::SIMCONNECT_RECV_EVENT) -> Result<Self, Self::Error> {
186 let request = SystemEventRequest::try_from(event.uEventID)
187 .map_err(|_| SimConnectError::UnimplementedEventType(event.uEventID))?;
188
189 match request {
190 SystemEventRequest::OneSecond => Ok(SystemEvent::OneSecond),
191 SystemEventRequest::FourSeconds => Ok(SystemEvent::FourSeconds),
192 SystemEventRequest::SixTimesPerSecond => Ok(SystemEvent::SixTimesPerSecond),
193 SystemEventRequest::Crashed => Ok(SystemEvent::Crashed),
194 SystemEventRequest::CrashReset => Ok(SystemEvent::CrashReset),
195 SystemEventRequest::FlightPlanDeactivated => Ok(SystemEvent::FlightPlanDeactivated),
196 SystemEventRequest::Pause => Ok(SystemEvent::Pause {
197 state: event.dwData == 1,
198 }),
199 SystemEventRequest::Paused => Ok(SystemEvent::Paused),
200 SystemEventRequest::PositionChanged => Ok(SystemEvent::PositionChanged),
201 SystemEventRequest::Sim => Ok(SystemEvent::Sim {
202 state: event.dwData == 1,
203 }),
204 SystemEventRequest::SimStart => Ok(SystemEvent::SimStart),
205 SystemEventRequest::SimStop => Ok(SystemEvent::SimStop),
206 SystemEventRequest::Sound => Ok(SystemEvent::Sound {
207 state: event.dwData == bindings::SIMCONNECT_SOUND_SYSTEM_EVENT_DATA_MASTER,
208 }),
209 SystemEventRequest::Unpaused => Ok(SystemEvent::Unpaused),
210 SystemEventRequest::View => Ok(SystemEvent::View {
211 view: ViewType::try_from(event.dwData).unwrap_or(ViewType::None),
212 }),
213 _ => Err(SimConnectError::UnimplementedEventType(event.uEventID)),
214 }
215 }
216}
217
218impl TryFrom<&bindings::SIMCONNECT_RECV_EVENT_FILENAME> for SystemEvent {
219 type Error = SimConnectError;
220
221 fn try_from(event: &bindings::SIMCONNECT_RECV_EVENT_FILENAME) -> Result<Self, Self::Error> {
222 let request = SystemEventRequest::try_from(event._base.uEventID)
223 .map_err(|_| SimConnectError::UnimplementedEventType(event._base.uEventID))?;
224
225 match request {
226 SystemEventRequest::AircraftLoaded => {
227 let file_name = fixed_c_str_to_string(&event.szFileName);
228 Ok(SystemEvent::AircraftLoaded { file_name })
229 }
230 SystemEventRequest::FlightLoaded => {
231 let file_name = fixed_c_str_to_string(&event.szFileName);
232 Ok(SystemEvent::FlightLoaded { file_name })
233 }
234 SystemEventRequest::FlightSaved => {
235 let file_name = fixed_c_str_to_string(&event.szFileName);
236 Ok(SystemEvent::FlightSaved { file_name })
237 }
238 SystemEventRequest::FlightPlanActivated => {
239 let file_name = fixed_c_str_to_string(&event.szFileName);
240 Ok(SystemEvent::FlightPlanActivated { file_name })
241 }
242 _ => Err(SimConnectError::UnimplementedEventType(
243 event._base.uEventID,
244 )),
245 }
246 }
247}
248
249impl TryFrom<&bindings::SIMCONNECT_RECV_EVENT_FRAME> for SystemEvent {
250 type Error = SimConnectError;
251
252 fn try_from(event: &bindings::SIMCONNECT_RECV_EVENT_FRAME) -> Result<Self, Self::Error> {
253 let request = SystemEventRequest::try_from(event._base.uEventID)
254 .map_err(|_| SimConnectError::UnimplementedEventType(event._base.uEventID))?;
255
256 match request {
257 SystemEventRequest::Frame => Ok(SystemEvent::Frame {
258 frame_rate: event.fFrameRate,
259 sim_speed: event.fSimSpeed,
260 }),
261 SystemEventRequest::PauseFrame => Ok(SystemEvent::PauseFrame {
262 frame_rate: event.fFrameRate,
263 sim_speed: event.fSimSpeed,
264 }),
265 _ => Err(SimConnectError::UnimplementedEventType(
266 event._base.uEventID,
267 )),
268 }
269 }
270}