Add suport for system events

This commit is contained in:
Mihai Dinculescu
2022-10-29 13:48:00 +01:00
parent ad52d7f050
commit 2809917a93
16 changed files with 554 additions and 116 deletions

View File

@@ -3,8 +3,9 @@ use std::{collections::HashMap, ffi::c_void};
use tracing::{error, span, trace, warn, Level};
use crate::{
as_c_string, bindings, helpers::fixed_c_str_to_string, ok_if_fail, success, Airport, Event,
Notification, Object, SimConnectError, Waypoint, NDB, VOR,
as_c_string, bindings, helpers::fixed_c_str_to_string, ok_if_fail, success, Airport,
ClientEvent, Notification, Object, SimConnectError, SystemEvent, Waypoint, CLIENT_EVENT_START,
NDB, VOR,
};
/// SimConnect SDK Client.
@@ -102,7 +103,7 @@ impl SimConnect {
std::ptr::null_mut(),
0,
)
});
})?;
Ok(Self {
handle: std::ptr::NonNull::new(handle).ok_or_else(|| {
@@ -158,10 +159,32 @@ impl SimConnect {
let event: &bindings::SIMCONNECT_RECV_EVENT =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_EVENT) };
let event = Event::try_from(event.uEventID)
.map_err(|_| SimConnectError::UnimplementedEventType(event.uEventID))?;
if event.uEventID >= CLIENT_EVENT_START {
let event = ClientEvent::try_from(event.uEventID)
.map_err(|_| SimConnectError::UnimplementedEventType(event.uEventID))?;
Ok(Some(Notification::Event(event)))
Ok(Some(Notification::ClientEvent(event)))
} else {
let event = SystemEvent::try_from(event)?;
Ok(Some(Notification::SystemEvent(event)))
}
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FILENAME => {
trace!("Received SIMCONNECT_RECV_EVENT_FILENAME");
let event: &bindings::SIMCONNECT_RECV_EVENT_FILENAME =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_EVENT_FILENAME) };
let event = SystemEvent::try_from(event)?;
Ok(Some(Notification::SystemEvent(event)))
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FRAME => {
trace!("Received SIMCONNECT_RECV_EVENT_FRAME");
let event: &bindings::SIMCONNECT_RECV_EVENT_FRAME =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_EVENT_FRAME) };
let event = SystemEvent::try_from(event)?;
Ok(Some(Notification::SystemEvent(event)))
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => {
trace!("Received SIMCONNECT_RECV_SIMOBJECT_DATA");

View File

@@ -1,4 +1,7 @@
use crate::{bindings, success, Event, NotificationGroup, SimConnect, SimConnectError};
use crate::{
bindings, success, ClientEvent, NotificationGroup, SimConnect, SimConnectError,
SystemEventRequest,
};
impl SimConnect {
/// Associates a client defined event with a Microsoft Flight Simulator event name.
@@ -7,7 +10,7 @@ impl SimConnect {
#[tracing::instrument(name = "SimConnect::register_event", level = "debug", skip(self))]
pub fn register_event(
&self,
event: Event,
event: ClientEvent,
notification_group: NotificationGroup,
) -> Result<(), SimConnectError> {
success!(unsafe {
@@ -16,7 +19,7 @@ impl SimConnect {
event as u32,
event.into_c_char(),
)
});
})?;
success!(unsafe {
bindings::SimConnect_AddClientEventToNotificationGroup(
@@ -25,7 +28,7 @@ impl SimConnect {
event as u32,
0,
)
});
})?;
success!(unsafe {
bindings::SimConnect_SetNotificationGroupPriority(
@@ -33,8 +36,40 @@ impl SimConnect {
notification_group as u32,
1,
)
});
})
}
Ok(())
/// Request that a specific system event is notified to the client.
#[tracing::instrument(
name = "SimConnect::subscribe_to_system_event",
level = "debug",
skip(self)
)]
pub fn subscribe_to_system_event(
&mut self,
event: SystemEventRequest,
) -> Result<(), SimConnectError> {
success!(unsafe {
bindings::SimConnect_SubscribeToSystemEvent(
self.handle.as_ptr(),
event as u32,
event.into_c_char(),
)
})
}
/// Request that notifications are no longer received for the specified system event.
#[tracing::instrument(
name = "SimConnect::unsubscribe_from_system_event",
level = "debug",
skip(self)
)]
pub fn unsubscribe_from_system_event(
&mut self,
event: SystemEventRequest,
) -> Result<(), SimConnectError> {
success!(unsafe {
bindings::SimConnect_UnsubscribeFromSystemEvent(self.handle.as_ptr(), event as u32)
})
}
}

View File

@@ -22,15 +22,13 @@ impl SimConnect {
let type_name = facility_type.to_type_name();
let request_id = self.new_request_id(type_name)?;
unsafe {
success!(bindings::SimConnect_RequestFacilitiesList(
success!(unsafe {
bindings::SimConnect_RequestFacilitiesList(
self.handle.as_ptr(),
facility_type.into(),
request_id,
));
}
Ok(())
)
})
}
/// Request notifications when a facility of a certain type is added to the facilities cache.
@@ -58,15 +56,13 @@ impl SimConnect {
let type_name = facility_type.to_type_name();
let request_id = self.new_request_id(type_name)?;
unsafe {
success!(bindings::SimConnect_SubscribeToFacilities(
success!(unsafe {
bindings::SimConnect_SubscribeToFacilities(
self.handle.as_ptr(),
facility_type.into(),
request_id,
));
}
Ok(())
)
})
}
/// Request that notifications of additions to the facilities cache are not longer sent.
@@ -84,12 +80,9 @@ impl SimConnect {
) -> Result<(), SimConnectError> {
let type_name = facility_type.to_type_name();
unsafe {
success!(bindings::SimConnect_UnsubscribeToFacilities(
self.handle.as_ptr(),
facility_type.into(),
));
}
success!(unsafe {
bindings::SimConnect_UnsubscribeToFacilities(self.handle.as_ptr(), facility_type.into())
})?;
self.unregister_request_id_by_type_name(&type_name);

View File

@@ -26,12 +26,9 @@ impl SimConnect {
.get(&type_name)
.ok_or_else(|| SimConnectError::ObjectNotRegistered(type_name.clone()))?;
unsafe {
success!(bindings::SimConnect_ClearDataDefinition(
self.handle.as_ptr(),
*request_id,
));
}
success!(unsafe {
bindings::SimConnect_ClearDataDefinition(self.handle.as_ptr(), *request_id)
})?;
self.unregister_request_id_by_type_name(&type_name)
.ok_or(SimConnectError::ObjectNotRegistered(type_name))
@@ -59,8 +56,8 @@ impl SimConnect {
DataType::String => bindings::SIMCONNECT_DATATYPE_SIMCONNECT_DATATYPE_STRING256,
};
unsafe {
success!(bindings::SimConnect_AddToDataDefinition(
success!(unsafe {
bindings::SimConnect_AddToDataDefinition(
self.handle.as_ptr(),
request_id,
as_c_string!(name),
@@ -68,10 +65,8 @@ impl SimConnect {
c_type,
0.0,
u32::MAX,
));
}
Ok(())
)
})
}
/// Request when the SimConnect client is to receive data values for a specific object.
@@ -100,8 +95,8 @@ impl SimConnect {
condition: Condition,
interval: u32,
) -> Result<(), SimConnectError> {
unsafe {
success!(bindings::SimConnect_RequestDataOnSimObject(
success!(unsafe {
bindings::SimConnect_RequestDataOnSimObject(
self.handle.as_ptr(),
request_id,
request_id,
@@ -111,9 +106,7 @@ impl SimConnect {
0,
interval,
0,
));
}
Ok(())
)
})
}
}