diff --git a/README.md b/README.md index 1abc8af..600507e 100644 --- a/README.md +++ b/README.md @@ -26,27 +26,40 @@ fn main() -> Result<(), Box> { let client = SimConnect::new("Simple Program"); match client { - Ok(mut client) => loop { - let notification = client.get_next_dispatch()?; + Ok(mut client) => { + let mut notifications_received = 0; - match notification { - Some(Notification::Open) => { - println!("Open"); + loop { + let notification = client.get_next_dispatch()?; - // After the connection is successfully open, we register the struct - client.register_object::()?; - } - Some(Notification::Object(data)) => { - if let Ok(gps_data) = GpsData::try_from(&data) { - println!("{gps_data:?}"); + match notification { + Some(Notification::Open) => { + println!("Connection opened."); + + // After the connection is successfully open, we register the struct + client.register_object::()?; } - } - _ => (), - } + Some(Notification::Object(data)) => { + if let Ok(gps_data) = GpsData::try_from(&data) { + println!("{gps_data:?}"); - // sleep for about a frame to reduce CPU usage - std::thread::sleep(std::time::Duration::from_millis(16)); - }, + notifications_received += 1; + + // After we have received 10 notifications, we unregister the struct + if notifications_received > 10 { + client.unregister_object::()?; + println!("Subscription stopped."); + break; + } + } + } + _ => (), + } + + // sleep for about a frame to reduce CPU usage + std::thread::sleep(std::time::Duration::from_millis(16)); + } + } Err(e) => { println!("Error: {e:?}") } @@ -56,4 +69,6 @@ fn main() -> Result<(), Box> { } ``` -See [more examples](https://github.com/mihai-dinculescu/simconnect-sdk/tree/main/examples). +See [more examples][examples]. + +[examples]: https://github.com/mihai-dinculescu/simconnect-sdk/tree/main/examples diff --git a/examples/src/data.rs b/examples/src/data.rs index f509c67..0536a79 100644 --- a/examples/src/data.rs +++ b/examples/src/data.rs @@ -18,27 +18,40 @@ fn main() -> Result<(), Box> { let client = SimConnect::new("Simple Program"); match client { - Ok(mut client) => loop { - let notification = client.get_next_dispatch()?; + Ok(mut client) => { + let mut notifications_received = 0; - match notification { - Some(Notification::Open) => { - println!("Open"); + loop { + let notification = client.get_next_dispatch()?; - // After the connection is successfully open, we register the struct - client.register_object::()?; - } - Some(Notification::Object(data)) => { - if let Ok(gps_data) = GpsData::try_from(&data) { - println!("{gps_data:?}"); + match notification { + Some(Notification::Open) => { + println!("Connection opened."); + + // After the connection is successfully open, we register the struct + client.register_object::()?; } - } - _ => (), - } + Some(Notification::Object(data)) => { + if let Ok(gps_data) = GpsData::try_from(&data) { + println!("{gps_data:?}"); - // sleep for about a frame to reduce CPU usage - std::thread::sleep(std::time::Duration::from_millis(16)); - }, + notifications_received += 1; + + // After we have received 10 notifications, we unregister the struct + if notifications_received > 10 { + client.unregister_object::()?; + println!("Subscription stopped."); + break; + } + } + } + _ => (), + } + + // sleep for about a frame to reduce CPU usage + std::thread::sleep(std::time::Duration::from_millis(16)); + } + } Err(e) => { println!("Error: {e:?}") } diff --git a/examples/src/data_multiple_objects.rs b/examples/src/data_multiple_objects.rs index 85f9814..9d4c326 100644 --- a/examples/src/data_multiple_objects.rs +++ b/examples/src/data_multiple_objects.rs @@ -31,7 +31,7 @@ fn main() -> Result<(), Box> { match notification { Some(Notification::Open) => { - println!("Open"); + println!("Connection opened."); // After the connection is successfully open, we register the structs client.register_object::()?; diff --git a/examples/src/data_with_tracing.rs b/examples/src/data_with_tracing.rs index 0e0042e..c9f8396 100644 --- a/examples/src/data_with_tracing.rs +++ b/examples/src/data_with_tracing.rs @@ -22,27 +22,40 @@ fn main() -> Result<(), Box> { let client = SimConnect::new("Simple Program"); match client { - Ok(mut client) => loop { - let notification = client.get_next_dispatch()?; + Ok(mut client) => { + let mut notifications_received = 0; - match notification { - Some(Notification::Open) => { - info!("Open"); + loop { + let notification = client.get_next_dispatch()?; - // After the connection is successfully open, we register the struct - client.register_object::()?; - } - Some(Notification::Object(data)) => { - if let Ok(gps_data) = GpsData::try_from(&data) { - info!("{gps_data:?}"); + match notification { + Some(Notification::Open) => { + info!("Open"); + + // After the connection is successfully open, we register the struct + client.register_object::()?; } - } - _ => (), - } + Some(Notification::Object(data)) => { + if let Ok(gps_data) = GpsData::try_from(&data) { + info!("{gps_data:?}"); - // sleep for about a frame to reduce CPU usage - std::thread::sleep(std::time::Duration::from_millis(16)); - }, + notifications_received += 1; + + // After we have received 10 notifications, we unregister the struct + if notifications_received > 10 { + client.unregister_object::()?; + println!("Subscription stopped."); + break; + } + } + } + _ => (), + } + + // sleep for about a frame to reduce CPU usage + std::thread::sleep(std::time::Duration::from_millis(16)); + } + } Err(e) => { error!("{e:?}") } diff --git a/examples/src/data_without_macro.rs b/examples/src/data_without_macro.rs index 74b326d..487bf08 100644 --- a/examples/src/data_without_macro.rs +++ b/examples/src/data_without_macro.rs @@ -37,27 +37,40 @@ fn main() -> Result<(), Box> { let client = SimConnect::new("Simple Program"); match client { - Ok(mut client) => loop { - let notification = client.get_next_dispatch()?; + Ok(mut client) => { + let mut notifications_received = 0; - match notification { - Some(Notification::Open) => { - println!("Open"); + loop { + let notification = client.get_next_dispatch()?; - // After the connection is successfully open, we register the struct - client.register_object::()?; - } - Some(Notification::Object(data)) => { - if let Ok(gps_data) = GpsData::try_from(&data) { - println!("{gps_data:?}"); + match notification { + Some(Notification::Open) => { + println!("Connection opened."); + + // After the connection is successfully open, we register the struct + client.register_object::()?; } - } - _ => (), - } + Some(Notification::Object(data)) => { + if let Ok(gps_data) = GpsData::try_from(&data) { + println!("{gps_data:?}"); - // sleep for about a frame to reduce CPU usage - std::thread::sleep(std::time::Duration::from_millis(16)); - }, + notifications_received += 1; + + // After we have received 10 notifications, we unregister the struct + if notifications_received > 10 { + client.unregister_object::()?; + println!("Subscription stopped."); + break; + } + } + } + _ => (), + } + + // sleep for about a frame to reduce CPU usage + std::thread::sleep(std::time::Duration::from_millis(16)); + } + } Err(e) => { println!("Error: {e:?}") } diff --git a/examples/src/facilities.rs b/examples/src/facilities.rs index 084de8c..5a782bc 100644 --- a/examples/src/facilities.rs +++ b/examples/src/facilities.rs @@ -9,7 +9,7 @@ fn main() -> Result<(), Box> { match notification { Some(Notification::Open) => { - println!("Open"); + println!("Connection opened."); // After the connection is successfully open diff --git a/simconnect-sdk/build.rs b/simconnect-sdk/build.rs index 5d05ee4..a904328 100644 --- a/simconnect-sdk/build.rs +++ b/simconnect-sdk/build.rs @@ -23,6 +23,7 @@ fn main() { .allowlist_function("SimConnect_GetNextDispatch") .allowlist_function("SimConnect_AddToDataDefinition") .allowlist_function("SimConnect_RequestDataOnSimObject") + .allowlist_function("SimConnect_ClearDataDefinition") .allowlist_function("SimConnect_SubscribeToFacilities") .allowlist_function("SimConnect_UnsubscribeToFacilities") .allowlist_function("SimConnect_RequestFacilitiesList") diff --git a/simconnect-sdk/src/lib.rs b/simconnect-sdk/src/lib.rs index 80e16cb..69d81ee 100644 --- a/simconnect-sdk/src/lib.rs +++ b/simconnect-sdk/src/lib.rs @@ -27,27 +27,40 @@ //! let client = SimConnect::new("Simple Program"); //! //! match client { -//! Ok(mut client) => loop { -//! let notification = client.get_next_dispatch()?; +//! Ok(mut client) => { +//! let mut notifications_received = 0; //! -//! match notification { -//! Some(Notification::Open) => { -//! println!("Open"); +//! loop { +//! let notification = client.get_next_dispatch()?; //! -//! // After the connection is successfully open, we register the struct -//! client.register_object::()?; -//! } -//! Some(Notification::Object(data)) => { -//! if let Ok(gps_data) = GpsData::try_from(&data) { -//! println!("{gps_data:?}"); +//! match notification { +//! Some(Notification::Open) => { +//! println!("Connection opened."); +//! +//! // After the connection is successfully open, we register the struct +//! client.register_object::()?; //! } -//! } -//! _ => (), -//! } +//! Some(Notification::Object(data)) => { +//! if let Ok(gps_data) = GpsData::try_from(&data) { +//! println!("{gps_data:?}"); //! -//! // sleep for about a frame to reduce CPU usage -//! std::thread::sleep(std::time::Duration::from_millis(16)); -//! }, +//! notifications_received += 1; +//! +//! // After we have received 10 notifications, we unregister the struct +//! if notifications_received > 10 { +//! client.unregister_object::()?; +//! println!("Subscription stopped."); +//! break; +//! } +//! } +//! } +//! _ => (), +//! } +//! +//! // sleep for about a frame to reduce CPU usage +//! std::thread::sleep(std::time::Duration::from_millis(16)); +//! } +//! } //! Err(e) => { //! println!("Error: {e:?}") //! } diff --git a/simconnect-sdk/src/simconnect/base.rs b/simconnect-sdk/src/simconnect/base.rs index 4f5be7a..4092f19 100644 --- a/simconnect-sdk/src/simconnect/base.rs +++ b/simconnect-sdk/src/simconnect/base.rs @@ -28,27 +28,40 @@ use crate::{ /// let client = SimConnect::new("Simple Program"); /// /// match client { -/// Ok(mut client) => loop { -/// let notification = client.get_next_dispatch()?; +/// Ok(mut client) => { +/// let mut notifications_received = 0; /// -/// match notification { -/// Some(Notification::Open) => { -/// println!("Open"); +/// loop { +/// let notification = client.get_next_dispatch()?; /// -/// // After the connection is successfully open, we register the struct -/// client.register_object::()?; -/// } -/// Some(Notification::Object(data)) => { -/// if let Ok(gps_data) = GpsData::try_from(&data) { -/// println!("{gps_data:?}"); +/// match notification { +/// Some(Notification::Open) => { +/// println!("Connection opened."); +/// +/// // After the connection is successfully open, we register the struct +/// client.register_object::()?; /// } -/// } -/// _ => (), -/// } +/// Some(Notification::Object(data)) => { +/// if let Ok(gps_data) = GpsData::try_from(&data) { +/// println!("{gps_data:?}"); /// -/// // sleep for about a frame to reduce CPU usage -/// std::thread::sleep(std::time::Duration::from_millis(16)); -/// }, +/// notifications_received += 1; +/// +/// // After we have received 10 notifications, we unregister the struct +/// if notifications_received > 10 { +/// client.unregister_object::()?; +/// println!("Subscription stopped."); +/// break; +/// } +/// } +/// } +/// _ => (), +/// } +/// +/// // sleep for about a frame to reduce CPU usage +/// std::thread::sleep(std::time::Duration::from_millis(16)); +/// } +/// } /// Err(e) => { /// println!("Error: {e:?}") /// } @@ -322,12 +335,12 @@ impl SimConnect { /// Unregister a Request ID in the internal state so that the user doesn't have to manually manage Request IDs. #[tracing::instrument(name = "SimConnect::unregister_request_id_by_type_name")] - pub(super) fn unregister_request_id_by_type_name(&mut self, type_name: String) { - self.registered_objects.remove(&type_name); + pub(super) fn unregister_request_id_by_type_name(&mut self, type_name: &str) -> Option { + self.registered_objects.remove(type_name) } /// Get the Type Name of a Request ID. - #[tracing::instrument(name = "SimConnect::get_request_id_by_type_name")] + #[tracing::instrument(name = "SimConnect::get_type_name_by_request_id")] pub(super) fn get_type_name_by_request_id(&self, request_id: u32) -> Option { self.registered_objects .iter() diff --git a/simconnect-sdk/src/simconnect/facilities.rs b/simconnect-sdk/src/simconnect/facilities.rs index b177c04..9de8dbe 100644 --- a/simconnect-sdk/src/simconnect/facilities.rs +++ b/simconnect-sdk/src/simconnect/facilities.rs @@ -79,7 +79,7 @@ impl SimConnect { )); } - self.unregister_request_id_by_type_name(type_name); + self.unregister_request_id_by_type_name(&type_name); Ok(()) } diff --git a/simconnect-sdk/src/simconnect/objects.rs b/simconnect-sdk/src/simconnect/objects.rs index 0b2de3d..8468598 100644 --- a/simconnect-sdk/src/simconnect/objects.rs +++ b/simconnect-sdk/src/simconnect/objects.rs @@ -16,6 +16,27 @@ impl SimConnect { Ok(id) } + // Unregister an object with SimConnect. + #[tracing::instrument(name = "SimConnect::register_object")] + pub fn unregister_object(&mut self) -> Result { + let type_name: String = std::any::type_name::().into(); + + let request_id = self + .registered_objects + .get(&type_name) + .ok_or_else(|| SimConnectError::ObjectNotRegistered(type_name.clone()))?; + + unsafe { + success!(bindings::SimConnect_ClearDataDefinition( + self.handle.as_ptr(), + *request_id, + )); + } + + self.unregister_request_id_by_type_name(&type_name) + .ok_or(SimConnectError::ObjectNotRegistered(type_name)) + } + /// Add a Microsoft Flight Simulator simulation variable name to a client defined object definition. /// /// # Remarks