Add support for String

This commit is contained in:
Mihai Dinculescu
2022-10-20 15:42:51 +01:00
parent 60b73c1557
commit 4ac94cdb96
21 changed files with 574 additions and 404 deletions

View File

@@ -44,6 +44,7 @@ fn main() {
.allowlist_var("SIMCONNECT_RECV_ID_VOR_LIST_HAS_LOCALIZER")
.allowlist_var("SIMCONNECT_RECV_ID_VOR_LIST_HAS_GLIDE_SLOPE")
.allowlist_var("SIMCONNECT_RECV_ID_VOR_LIST_HAS_DME")
.allowlist_var("SIMCONNECT_OBJECT_ID_USER")
.generate()
.expect("Unable to generate bindings");

View File

@@ -3,4 +3,5 @@
pub enum DataType {
Float64,
Bool,
String,
}

View File

@@ -35,12 +35,12 @@ impl Object {
///
/// # Errors
/// - [`crate::SimConnectError::ObjectMismatch`] -- The type of this SimConnect object is different from `T`.
pub fn try_transmute<T: SimConnectObjectExt>(&self) -> Result<T, SimConnectError> {
pub fn try_transmute<T: SimConnectObjectExt, I>(&self) -> Result<I, SimConnectError> {
let type_name: String = std::any::type_name::<T>().into();
if self.type_name == type_name {
let data: &T = unsafe { std::mem::transmute_copy(&self.data_addr) };
Ok(data.clone())
let data: I = unsafe { std::ptr::read_unaligned(self.data_addr as *const I) };
Ok(data)
} else {
Err(SimConnectError::ObjectMismatch {
actual: self.type_name.clone(),

View File

@@ -26,6 +26,7 @@ pub(crate) use macros::{as_c_string, ok_if_fail, success};
pub use domain::*;
pub use errors::SimConnectError;
pub use helpers::fixed_c_str_to_string;
pub use simconnect::SimConnect;
pub use simconnect_object_ext::SimConnectObjectExt;

View File

@@ -68,21 +68,23 @@ impl SimConnect {
);
};
let result = match unsafe { (*data_buf).dwID as i32 } {
let recv_id = unsafe { (*data_buf).dwID as i32 };
let result = match recv_id {
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_OPEN => Some(Notification::Open),
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_QUIT => Some(Notification::Quit),
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT => {
let event = unsafe { *(data_buf as *const bindings::SIMCONNECT_RECV_EVENT) };
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::SimConnectUnrecognizedEvent(event.uEventID))?;
Some(Notification::Event(event))
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => {
let event: &bindings::SIMCONNECT_RECV_SIMOBJECT_DATA = unsafe {
std::mem::transmute_copy(
&(data_buf as *const bindings::SIMCONNECT_RECV_SIMOBJECT_DATA),
)
};
let event: &bindings::SIMCONNECT_RECV_SIMOBJECT_DATA =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_SIMOBJECT_DATA) };
let type_name = self.get_type_name_by_request_id(event.dwDefineID);
@@ -99,11 +101,8 @@ impl SimConnect {
}
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_AIRPORT_LIST => {
let event: &bindings::SIMCONNECT_RECV_AIRPORT_LIST = unsafe {
std::mem::transmute_copy(
&(data_buf as *const bindings::SIMCONNECT_RECV_AIRPORT_LIST),
)
};
let event: &bindings::SIMCONNECT_RECV_AIRPORT_LIST =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_AIRPORT_LIST) };
let data = (0..event._base.dwArraySize as usize)
.map(|i| {
@@ -122,11 +121,8 @@ impl SimConnect {
Some(Notification::AirportList(data))
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WAYPOINT_LIST => {
let event: &bindings::SIMCONNECT_RECV_WAYPOINT_LIST = unsafe {
std::mem::transmute_copy(
&(data_buf as *const bindings::SIMCONNECT_RECV_WAYPOINT_LIST),
)
};
let event: &bindings::SIMCONNECT_RECV_WAYPOINT_LIST =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_WAYPOINT_LIST) };
let data = (0..event._base.dwArraySize as usize)
.map(|i| {
@@ -146,11 +142,8 @@ impl SimConnect {
Some(Notification::WaypointList(data))
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NDB_LIST => {
let event: &bindings::SIMCONNECT_RECV_NDB_LIST = unsafe {
std::mem::transmute_copy(
&(data_buf as *const bindings::SIMCONNECT_RECV_NDB_LIST),
)
};
let event: &bindings::SIMCONNECT_RECV_NDB_LIST =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_NDB_LIST) };
let data = (0..event._base.dwArraySize as usize)
.map(|i| {
@@ -171,11 +164,8 @@ impl SimConnect {
Some(Notification::NdbList(data))
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_VOR_LIST => {
let event: &bindings::SIMCONNECT_RECV_VOR_LIST = unsafe {
std::mem::transmute_copy(
&(data_buf as *const bindings::SIMCONNECT_RECV_VOR_LIST),
)
};
let event: &bindings::SIMCONNECT_RECV_VOR_LIST =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_VOR_LIST) };
let data = (0..event._base.dwArraySize as usize)
.map(|i| {
@@ -241,13 +231,12 @@ impl SimConnect {
Some(Notification::VorList(data))
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EXCEPTION => {
let event = unsafe { *(data_buf as *const bindings::SIMCONNECT_RECV_EXCEPTION) };
let event: &bindings::SIMCONNECT_RECV_EXCEPTION =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_EXCEPTION) };
Some(Notification::Exception(event.dwException))
}
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NULL => None,
_ => panic!("Got unrecognized notification: {}", unsafe {
(*data_buf).dwID as i32
}),
id => panic!("Got unrecognized notification: {id}"),
};
Ok(result)

View File

@@ -45,21 +45,22 @@ impl SimConnect {
pub fn add_to_data_definition(
&self,
request_id: u32,
datum_name: &str,
units_name: &str,
name: &str,
unit: &str,
data_type: DataType,
) -> Result<(), SimConnectError> {
let c_type = match data_type {
DataType::Float64 => bindings::SIMCONNECT_DATATYPE_SIMCONNECT_DATATYPE_FLOAT64,
DataType::Bool => bindings::SIMCONNECT_DATATYPE_SIMCONNECT_DATATYPE_INT32,
DataType::String => bindings::SIMCONNECT_DATATYPE_SIMCONNECT_DATATYPE_STRING256,
};
unsafe {
success!(bindings::SimConnect_AddToDataDefinition(
self.handle.as_ptr(),
request_id,
as_c_string!(datum_name),
as_c_string!(units_name),
as_c_string!(name),
as_c_string!(unit),
c_type,
0.0,
u32::MAX,
@@ -71,7 +72,12 @@ impl SimConnect {
/// Request when the SimConnect client is to receive data values for a specific object.
///
/// # Current limitation
/// All objects are requested from the local user's aircraft POV.
/// This comes with the side-effect that currently there is no way to request data for other aircraft in multiplayer.
///
/// # Arguments
/// * `request_id` - The request ID of the object.
/// * `period` - [`crate::Period`]
/// * `condition` - [`crate::Condition`]
/// * `interval` - The number of period events that should elapse between transmissions of the data. `0` means the data is transmitted every Period, `1` means that the data is transmitted every other Period, etc.
@@ -91,7 +97,7 @@ impl SimConnect {
self.handle.as_ptr(),
request_id,
request_id,
request_id,
bindings::SIMCONNECT_OBJECT_ID_USER,
period.into(),
condition.into(),
0,