Add unsubscribe to objects

This commit is contained in:
Mihai Dinculescu
2022-10-18 21:46:01 +01:00
parent a2002e02cd
commit 0db9847030
11 changed files with 211 additions and 109 deletions

View File

@@ -26,27 +26,40 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = SimConnect::new("Simple Program"); let client = SimConnect::new("Simple Program");
match client { match client {
Ok(mut client) => loop { Ok(mut client) => {
let notification = client.get_next_dispatch()?; let mut notifications_received = 0;
match notification { loop {
Some(Notification::Open) => { let notification = client.get_next_dispatch()?;
println!("Open");
// After the connection is successfully open, we register the struct match notification {
client.register_object::<GpsData>()?; Some(Notification::Open) => {
} println!("Connection opened.");
Some(Notification::Object(data)) => {
if let Ok(gps_data) = GpsData::try_from(&data) { // After the connection is successfully open, we register the struct
println!("{gps_data:?}"); client.register_object::<GpsData>()?;
} }
} 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 notifications_received += 1;
std::thread::sleep(std::time::Duration::from_millis(16));
}, // After we have received 10 notifications, we unregister the struct
if notifications_received > 10 {
client.unregister_object::<GpsData>()?;
println!("Subscription stopped.");
break;
}
}
}
_ => (),
}
// sleep for about a frame to reduce CPU usage
std::thread::sleep(std::time::Duration::from_millis(16));
}
}
Err(e) => { Err(e) => {
println!("Error: {e:?}") println!("Error: {e:?}")
} }
@@ -56,4 +69,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
``` ```
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

View File

@@ -18,27 +18,40 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = SimConnect::new("Simple Program"); let client = SimConnect::new("Simple Program");
match client { match client {
Ok(mut client) => loop { Ok(mut client) => {
let notification = client.get_next_dispatch()?; let mut notifications_received = 0;
match notification { loop {
Some(Notification::Open) => { let notification = client.get_next_dispatch()?;
println!("Open");
// After the connection is successfully open, we register the struct match notification {
client.register_object::<GpsData>()?; Some(Notification::Open) => {
} println!("Connection opened.");
Some(Notification::Object(data)) => {
if let Ok(gps_data) = GpsData::try_from(&data) { // After the connection is successfully open, we register the struct
println!("{gps_data:?}"); client.register_object::<GpsData>()?;
} }
} 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 notifications_received += 1;
std::thread::sleep(std::time::Duration::from_millis(16));
}, // After we have received 10 notifications, we unregister the struct
if notifications_received > 10 {
client.unregister_object::<GpsData>()?;
println!("Subscription stopped.");
break;
}
}
}
_ => (),
}
// sleep for about a frame to reduce CPU usage
std::thread::sleep(std::time::Duration::from_millis(16));
}
}
Err(e) => { Err(e) => {
println!("Error: {e:?}") println!("Error: {e:?}")
} }

View File

@@ -31,7 +31,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
match notification { match notification {
Some(Notification::Open) => { Some(Notification::Open) => {
println!("Open"); println!("Connection opened.");
// After the connection is successfully open, we register the structs // After the connection is successfully open, we register the structs
client.register_object::<GpsData>()?; client.register_object::<GpsData>()?;

View File

@@ -22,27 +22,40 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = SimConnect::new("Simple Program"); let client = SimConnect::new("Simple Program");
match client { match client {
Ok(mut client) => loop { Ok(mut client) => {
let notification = client.get_next_dispatch()?; let mut notifications_received = 0;
match notification { loop {
Some(Notification::Open) => { let notification = client.get_next_dispatch()?;
info!("Open");
// After the connection is successfully open, we register the struct match notification {
client.register_object::<GpsData>()?; Some(Notification::Open) => {
} info!("Open");
Some(Notification::Object(data)) => {
if let Ok(gps_data) = GpsData::try_from(&data) { // After the connection is successfully open, we register the struct
info!("{gps_data:?}"); client.register_object::<GpsData>()?;
} }
} 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 notifications_received += 1;
std::thread::sleep(std::time::Duration::from_millis(16));
}, // After we have received 10 notifications, we unregister the struct
if notifications_received > 10 {
client.unregister_object::<GpsData>()?;
println!("Subscription stopped.");
break;
}
}
}
_ => (),
}
// sleep for about a frame to reduce CPU usage
std::thread::sleep(std::time::Duration::from_millis(16));
}
}
Err(e) => { Err(e) => {
error!("{e:?}") error!("{e:?}")
} }

View File

@@ -37,27 +37,40 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = SimConnect::new("Simple Program"); let client = SimConnect::new("Simple Program");
match client { match client {
Ok(mut client) => loop { Ok(mut client) => {
let notification = client.get_next_dispatch()?; let mut notifications_received = 0;
match notification { loop {
Some(Notification::Open) => { let notification = client.get_next_dispatch()?;
println!("Open");
// After the connection is successfully open, we register the struct match notification {
client.register_object::<GpsData>()?; Some(Notification::Open) => {
} println!("Connection opened.");
Some(Notification::Object(data)) => {
if let Ok(gps_data) = GpsData::try_from(&data) { // After the connection is successfully open, we register the struct
println!("{gps_data:?}"); client.register_object::<GpsData>()?;
} }
} 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 notifications_received += 1;
std::thread::sleep(std::time::Duration::from_millis(16));
}, // After we have received 10 notifications, we unregister the struct
if notifications_received > 10 {
client.unregister_object::<GpsData>()?;
println!("Subscription stopped.");
break;
}
}
}
_ => (),
}
// sleep for about a frame to reduce CPU usage
std::thread::sleep(std::time::Duration::from_millis(16));
}
}
Err(e) => { Err(e) => {
println!("Error: {e:?}") println!("Error: {e:?}")
} }

View File

@@ -9,7 +9,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
match notification { match notification {
Some(Notification::Open) => { Some(Notification::Open) => {
println!("Open"); println!("Connection opened.");
// After the connection is successfully open // After the connection is successfully open

View File

@@ -23,6 +23,7 @@ fn main() {
.allowlist_function("SimConnect_GetNextDispatch") .allowlist_function("SimConnect_GetNextDispatch")
.allowlist_function("SimConnect_AddToDataDefinition") .allowlist_function("SimConnect_AddToDataDefinition")
.allowlist_function("SimConnect_RequestDataOnSimObject") .allowlist_function("SimConnect_RequestDataOnSimObject")
.allowlist_function("SimConnect_ClearDataDefinition")
.allowlist_function("SimConnect_SubscribeToFacilities") .allowlist_function("SimConnect_SubscribeToFacilities")
.allowlist_function("SimConnect_UnsubscribeToFacilities") .allowlist_function("SimConnect_UnsubscribeToFacilities")
.allowlist_function("SimConnect_RequestFacilitiesList") .allowlist_function("SimConnect_RequestFacilitiesList")

View File

@@ -27,27 +27,40 @@
//! let client = SimConnect::new("Simple Program"); //! let client = SimConnect::new("Simple Program");
//! //!
//! match client { //! match client {
//! Ok(mut client) => loop { //! Ok(mut client) => {
//! let notification = client.get_next_dispatch()?; //! let mut notifications_received = 0;
//! //!
//! match notification { //! loop {
//! Some(Notification::Open) => { //! let notification = client.get_next_dispatch()?;
//! println!("Open");
//! //!
//! // After the connection is successfully open, we register the struct //! match notification {
//! client.register_object::<GpsData>()?; //! Some(Notification::Open) => {
//! } //! println!("Connection opened.");
//! Some(Notification::Object(data)) => { //!
//! if let Ok(gps_data) = GpsData::try_from(&data) { //! // After the connection is successfully open, we register the struct
//! println!("{gps_data:?}"); //! client.register_object::<GpsData>()?;
//! } //! }
//! } //! 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 //! notifications_received += 1;
//! std::thread::sleep(std::time::Duration::from_millis(16)); //!
//! }, //! // After we have received 10 notifications, we unregister the struct
//! if notifications_received > 10 {
//! client.unregister_object::<GpsData>()?;
//! println!("Subscription stopped.");
//! break;
//! }
//! }
//! }
//! _ => (),
//! }
//!
//! // sleep for about a frame to reduce CPU usage
//! std::thread::sleep(std::time::Duration::from_millis(16));
//! }
//! }
//! Err(e) => { //! Err(e) => {
//! println!("Error: {e:?}") //! println!("Error: {e:?}")
//! } //! }

View File

@@ -28,27 +28,40 @@ use crate::{
/// let client = SimConnect::new("Simple Program"); /// let client = SimConnect::new("Simple Program");
/// ///
/// match client { /// match client {
/// Ok(mut client) => loop { /// Ok(mut client) => {
/// let notification = client.get_next_dispatch()?; /// let mut notifications_received = 0;
/// ///
/// match notification { /// loop {
/// Some(Notification::Open) => { /// let notification = client.get_next_dispatch()?;
/// println!("Open");
/// ///
/// // After the connection is successfully open, we register the struct /// match notification {
/// client.register_object::<GpsData>()?; /// Some(Notification::Open) => {
/// } /// println!("Connection opened.");
/// Some(Notification::Object(data)) => { ///
/// if let Ok(gps_data) = GpsData::try_from(&data) { /// // After the connection is successfully open, we register the struct
/// println!("{gps_data:?}"); /// client.register_object::<GpsData>()?;
/// } /// }
/// } /// 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 /// notifications_received += 1;
/// std::thread::sleep(std::time::Duration::from_millis(16)); ///
/// }, /// // After we have received 10 notifications, we unregister the struct
/// if notifications_received > 10 {
/// client.unregister_object::<GpsData>()?;
/// println!("Subscription stopped.");
/// break;
/// }
/// }
/// }
/// _ => (),
/// }
///
/// // sleep for about a frame to reduce CPU usage
/// std::thread::sleep(std::time::Duration::from_millis(16));
/// }
/// }
/// Err(e) => { /// Err(e) => {
/// println!("Error: {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. /// 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")] #[tracing::instrument(name = "SimConnect::unregister_request_id_by_type_name")]
pub(super) fn unregister_request_id_by_type_name(&mut self, type_name: String) { pub(super) fn unregister_request_id_by_type_name(&mut self, type_name: &str) -> Option<u32> {
self.registered_objects.remove(&type_name); self.registered_objects.remove(type_name)
} }
/// Get the Type Name of a Request ID. /// 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<String> { pub(super) fn get_type_name_by_request_id(&self, request_id: u32) -> Option<String> {
self.registered_objects self.registered_objects
.iter() .iter()

View File

@@ -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(()) Ok(())
} }

View File

@@ -16,6 +16,27 @@ impl SimConnect {
Ok(id) Ok(id)
} }
// Unregister an object with SimConnect.
#[tracing::instrument(name = "SimConnect::register_object")]
pub fn unregister_object<T: SimConnectObjectExt>(&mut self) -> Result<u32, SimConnectError> {
let type_name: String = std::any::type_name::<T>().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. /// Add a Microsoft Flight Simulator simulation variable name to a client defined object definition.
/// ///
/// # Remarks /// # Remarks