### Run Data Receiver Example Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md Execute the 'data' binary to start receiving data from SimConnect. ```bash cargo run --bin data ``` -------------------------------- ### Run Facilities Cache Example Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md Execute the 'facilities' binary to demonstrate receiving facilities data from the SimConnect cache. ```bash cargo run --bin facilities ``` -------------------------------- ### Clone the SimConnect SDK Repository Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md To get started, clone the repository and navigate into the project directory. ```bash git clone git@github.com:mihai-dinculescu/simconnect-sdk-rs.git cd simconnect-sdk-rs ``` -------------------------------- ### Receive Airplane Data with SimConnect Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/README.md This example demonstrates how to set up a SimConnect client, define a data structure for airplane information, and continuously receive and process data. It registers an object to receive periodic updates and stops after receiving a certain number of notifications. ```rust use simconnect_sdk::{Notification, SimConnect, SimConnectObject}; /// A data structure that will be used to receive data from SimConnect. /// See the documentation of `SimConnectObject` for more information on the arguments of the `simconnect` attribute. #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second")] #[allow(dead_code)] struct AirplaneData { #[simconnect(name = "TITLE")] title: String, #[simconnect(name = "CATEGORY")] category: String, #[simconnect(name = "PLANE LATITUDE", unit = "degrees")] lat: f64, #[simconnect(name = "PLANE LONGITUDE", unit = "degrees")] lon: f64, #[simconnect(name = "PLANE ALTITUDE", unit = "feet")] alt: f64, #[simconnect(name = "SIM ON GROUND")] sim_on_ground: bool, } fn main() -> Result<(), Box> { let client = SimConnect::new("Receiving data example"); match client { Ok(mut client) => { let mut notifications_received = 0; loop { let notification = client.get_next_dispatch()?; 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(airplane_data) = AirplaneData::try_from(&data) { println!("{airplane_data:?}"); 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:?}") } } Ok(()) } ``` -------------------------------- ### SimConnectError Enum and Usage Example Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Demonstrates the SimConnectError enum variants and provides a practical example of error handling within the main loop of a SimConnect client application. ```APIDOC ## `SimConnectError` — Error types All public methods return `Result<_, SimConnectError>`. The enum is `#[non_exhaustive]` and covers both SDK-level mistakes and raw simulator exceptions. | Variant | When | |---------|------| | `SimConnectError(i32)` | Underlying C API call returned failure | | `SimConnectException(u32)` | Simulator sent a `SIMCONNECT_RECV_EXCEPTION` packet | | `ObjectAlreadyRegistered(String)` | `register_object` called twice for the same type | | `ObjectNotRegistered(String)` | `unregister_object` or data definition not found | | `EventAlreadySubscribedTo(String)` | Duplicate system/client event subscription | | `EventNotSubscribedTo(String)` | Unsubscribe called for an unregistered event | | `ObjectMismatch { actual, expected }` | `try_transmute` type mismatch | | `UnimplementedNotification(i32)` | Simulator sent a message ID the SDK doesn't handle | | `UnexpectedError(String)` | Internal invariant violation | ```rust use simconnect_sdk::{SimConnect, SimConnectError, SimConnectObject, Notification}; #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second")] #[allow(dead_code)] struct Data { #[simconnect(name = "PLANE ALTITUDE", unit = "feet")] alt: f64, } fn main() { match SimConnect::new("error handling demo") { Err(SimConnectError::SimConnectError(code)) => { eprintln!("Simulator unavailable (code {code}). Is MSFS running?"); } Ok(mut client) => { loop { match client.get_next_dispatch() { Ok(Some(Notification::Open)) => { // Registering the same type twice will yield ObjectAlreadyRegistered client.register_object::().unwrap(); match client.register_object::() { Err(SimConnectError::ObjectAlreadyRegistered(name)) => { eprintln!("Already registered: {name}"); } _ => {} } } Err(SimConnectError::SimConnectException(code)) => { eprintln!("Simulator exception: {code}"); break; } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } } } ``` ``` -------------------------------- ### SimConnect::register_object / unregister_object Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Starts and stops data streaming for a SimConnect object. `register_object::()` assigns an auto-managed request ID, calls `T::register`, and begins the data stream. `unregister_object::()` calls `SimConnect_ClearDataDefinition` and releases the ID. Both are generic over any type implementing `SimConnectObjectExt`. ```APIDOC ## `SimConnect::register_object` / `unregister_object` — Start and stop data streaming `register_object::()` assigns an auto-managed request ID, calls `T::register` (generated by the macro), and starts the data stream. `unregister_object::()` calls `SimConnect_ClearDataDefinition` and releases the ID. Both are generic over any type implementing `SimConnectObjectExt`. ``` -------------------------------- ### Run Data Receiver with Tracing (Verbose) Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md Use the RUST_LOG=trace environment variable to enable verbose tracing for the 'data_with_tracing' binary. ```bash RUST_LOG=trace cargo run --bin data_with_tracing ``` -------------------------------- ### Subscribe to Client Events Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md Execute the 'subscribe_to_client_events' binary to demonstrate subscribing to client-specific events in SimConnect. ```bash cargo run --bin subscribe_to_client_events ``` -------------------------------- ### Run Data Receiver with Tracing (Less Verbose) Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md Use the RUST_LOG=debug environment variable to enable less verbose tracing for the 'data_with_tracing' binary. ```bash RUST_LOG=debug cargo run --bin data_with_tracing ``` -------------------------------- ### Subscribe to System Events Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md Execute the 'subscribe_to_system_events' binary to demonstrate subscribing to system-wide events in SimConnect. ```bash cargo run --bin subscribe_to_system_events ``` -------------------------------- ### Run Data Receiver with Multiple Objects Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md Execute the 'data_multiple_objects' binary to demonstrate receiving data using multiple SimConnect objects. ```bash cargo run --bin data_multiple_objects ``` -------------------------------- ### Open a connection to the simulator Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Creates a new SimConnect client and opens the connection. Returns an error if the simulator is not running or the connection fails. The connection is automatically closed when the SimConnect value is dropped. ```rust use simconnect_sdk::{Notification, SimConnect, SimConnectObject}; fn main() -> Result<(), Box> { match SimConnect::new("My App") { Ok(mut client) => { // use client let _ = client.get_next_dispatch()?; } Err(e) => eprintln!("Could not connect to simulator: {e:?}"), } Ok(()) } ``` -------------------------------- ### Handle SimConnect Errors and Exceptions Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Demonstrates how to handle various SimConnect errors, including simulator unavailability and specific exceptions. It shows how to register an object and catch the `ObjectAlreadyRegistered` error. ```rust use simconnect_sdk::{SimConnect, SimConnectError, SimConnectObject, Notification}; #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second")] #[allow(dead_code)] struct Data { #[simconnect(name = "PLANE ALTITUDE", unit = "feet")] alt: f64, } fn main() { match SimConnect::new("error handling demo") { Err(SimConnectError::SimConnectError(code)) => { eprintln!("Simulator unavailable (code {code}). Is MSFS running?"); } Ok(mut client) => { loop { match client.get_next_dispatch() { Ok(Some(Notification::Open)) => { // Registering the same type twice will yield ObjectAlreadyRegistered client.register_object::().unwrap(); match client.register_object::() { Err(SimConnectError::ObjectAlreadyRegistered(name)) => { eprintln!("Already registered: {name}"); } _ => {} } } Err(SimConnectError::SimConnectException(code)) => { eprintln!("Simulator exception: {code}"); break; } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } } } ``` -------------------------------- ### Add simconnect-sdk Dependency Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/README.md Add this to your Cargo.toml file to include the simconnect-sdk crate with the 'derive' feature. ```toml [dependencies] simconnect-sdk = { version = "0.2", features = ["derive"] } ``` -------------------------------- ### SimConnect::new Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Opens a connection to the simulator by creating a new SimConnect client and establishing the underlying SimConnect_Open connection. Returns an error if the simulator is not running or the connection fails. The connection is automatically closed when the SimConnect instance is dropped. ```APIDOC ## `SimConnect::new` — Open a connection to the simulator Creates a new `SimConnect` client and opens the underlying `SimConnect_Open` connection. Returns `Err(SimConnectError)` if the simulator is not running or the connection cannot be established. The connection is automatically closed when the `SimConnect` value is dropped. ```rust use simconnect_sdk::{Notification, SimConnect, SimConnectObject}; fn main() -> Result<(), Box> { match SimConnect::new("My App") { Ok(mut client) => { // use client let _ = client.get_next_dispatch()?; } Err(e) => eprintln!("Could not connect to simulator: {e:?}"), } Ok(()) } ``` ``` -------------------------------- ### Manual SimConnectObjectExt and TryFrom Implementation Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Implement SimConnectObjectExt and TryFrom<&Object> manually when derive macros are insufficient. This requires a #[repr(C, packed)] intermediate struct to safely read raw memory from SimConnect. Use this for custom data definitions and requests. ```rust use simconnect_sdk::{ fixed_c_str_to_string, Condition, DataType, Notification, Object, Period, SimConnect, SimConnectError, SimConnectObjectExt, }; #[derive(Debug, Clone)] pub struct AirplaneData { pub title: String, pub lat: f64, pub alt: f64, pub sim_on_ground: bool, } // Must be #[repr(C, packed)] — mirrors the raw bytes SimConnect sends #[repr(C, packed)] struct AirplaneDataCPacked { title: [i8; 256], lat: f64, alt: f64, sim_on_ground: bool, } impl SimConnectObjectExt for AirplaneData { fn register(client: &mut SimConnect, id: u32) -> Result<(), SimConnectError> { client.add_to_data_definition(id, "TITLE", "", DataType::String)?; client.add_to_data_definition(id, "PLANE LATITUDE", "degrees", DataType::Float64)?; client.add_to_data_definition(id, "PLANE ALTITUDE", "feet", DataType::Float64)?; client.add_to_data_definition(id, "SIM ON GROUND", "", DataType::Bool)?; client.request_data_on_sim_object(id, Period::Second, Condition::None, 0)?; Ok(()) } } impl TryFrom<&Object> for AirplaneData { type Error = SimConnectError; fn try_from(value: &Object) -> Result { let raw = value.try_transmute::()?; Ok(AirplaneData { title: fixed_c_str_to_string(&raw.title), lat: raw.lat, alt: raw.alt, sim_on_ground: raw.sim_on_ground, }) } } fn main() -> Result<(), Box> { let mut client = SimConnect::new("manual impl demo")?; let mut count = 0; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.register_object::()?; } Some(Notification::Object(data)) => { if let Ok(d) = AirplaneData::try_from(&data) { println!(ירת{d:?}); count += 1; if count >= 10 { client.unregister_object::()?; break; } } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } Ok(()) } ``` -------------------------------- ### Add Git Tag for Release Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/CONTRIBUTING.md Use this command to add an annotated Git tag for a new release version. ```bash git tag -a vX.X.X -m "vX.X.X" ``` -------------------------------- ### Subscribe to Facilities Updates (Waypoint, NDB, VOR) Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Use `subscribe_to_facilities` to receive initial cache data and subsequent updates for a `FacilityType`. Call `unsubscribe_to_facilities` when no longer needed. Only one subscription per `FacilityType` is allowed at a time. ```rust use simconnect_sdk::{FacilityType, Notification, SimConnect}; fn main() -> Result<(), Box> { let mut client = SimConnect::new("facilities-subscribe demo")?; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.subscribe_to_facilities(FacilityType::Waypoint)?; client.subscribe_to_facilities(FacilityType::NDB)?; client.subscribe_to_facilities(FacilityType::VOR)?; } Some(Notification::WaypointList(wps)) => { for wp in &wps { if wp.icao == "BRAIN" { // Waypoint { icao: "BRAIN", lat: 52.19, lon: 0.12, alt: 24.0, mag_var: -0.4 } println!("{wp:?}"); client.unsubscribe_to_facilities(FacilityType::Waypoint)?; } } } Some(Notification::NdbList(ndbs)) => { for ndb in &ndbs { if ndb.icao == "CAM" { println!("{ndb:?}"); client.unsubscribe_to_facilities(FacilityType::NDB)?; } } } Some(Notification::VorList(vors)) => { for vor in &vors { if vor.icao == "LON" { // VOR { icao: "LON", has_localizer: true, glide_slope_angle: Some(3.0), ... } println!("{vor:?}"); client.unsubscribe_to_facilities(FacilityType::VOR)?; } } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` -------------------------------- ### Push Git Tags for Release Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/CONTRIBUTING.md Push all local tags to the remote repository to include them in the release. ```bash git push --follow-tags ``` -------------------------------- ### Request Facilities List (Airport) Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Use `request_facilities_list` for a one-time query of the current facilities cache for a specific `FacilityType`. The simulator responds with a list and automatically cleans up the registration. ```rust use simconnect_sdk::{FacilityType, Notification, SimConnect}; fn main() -> Result<(), Box> { let mut client = SimConnect::new("facilities-list demo")?; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { // One-shot: returns current cache then auto-unregisters client.request_facilities_list(FacilityType::Airport)?; } Some(Notification::AirportList(airports)) => { for airport in &airports { if airport.icao == "EGLL" { // Output: Airport { icao: "EGLL", lat: 51.4775, lon: -0.4614, alt: 25.3 } println!("{airport:?}"); } } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` -------------------------------- ### Register Multiple Objects Simultaneously Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Shows how to register multiple distinct data objects (GpsData, AircraftIdentity, OnGround) concurrently. Each object receives its own auto-managed request ID. Incoming notifications are routed using sequential `try_from` calls. ```rust use simconnect_sdk::{Notification, SimConnect, SimConnectObject}; #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second")] #[allow(dead_code)] struct GpsData { #[simconnect(name = "PLANE LATITUDE", unit = "degrees")] lat: f64, #[simconnect(name = "PLANE LONGITUDE", unit = "degrees")] lon: f64, #[simconnect(name = "PLANE ALTITUDE", unit = "feet")] alt: f64, } #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second", condition = "changed")] #[allow(dead_code)] struct AircraftIdentity { #[simconnect(name = "TITLE")] title: String, #[simconnect(name = "CATEGORY")] category: String, } #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second", condition = "changed")] #[allow(dead_code)] struct OnGround { #[simconnect(name = "SIM ON GROUND")] sim_on_ground: bool, } fn main() -> Result<(), Box> { let mut client = SimConnect::new("multi-object demo")?; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.register_object::()?; client.register_object::()?; client.register_object::()?; } Some(Notification::Object(data)) => { if let Ok(gps) = GpsData::try_from(&data) { println!("GPS → {:?}", gps); continue; } if let Ok(id) = AircraftIdentity::try_from(&data) { println!("ID → {:?}", id); continue; } if let Ok(og) = OnGround::try_from(&data) { println!("OnGround → {:?}", og); } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` -------------------------------- ### SimConnect::subscribe_to_system_event / unsubscribe_from_system_event Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Allows subscribing to and unsubscribing from simulator lifecycle events such as timing pulses, state changes, and file-load notifications. ```APIDOC ## `SimConnect::subscribe_to_system_event` / `unsubscribe_from_system_event` — React to simulator lifecycle events Subscribe to any `SystemEventRequest` variant to receive the corresponding `SystemEvent` in the dispatch loop. Events include timing pulses (`OneSecond`, `FourSeconds`, `Frame`), state changes (`Pause`, `Sim`, `Sound`, `View`), and file-load notifications (`FlightLoaded`, `AircraftLoaded`, `FlightPlanActivated`). ### Method - `subscribe_to_system_event(event_request: SystemEventRequest)` - `unsubscribe_from_system_event(event_request: SystemEventRequest)` ### Parameters #### `subscribe_to_system_event` / `unsubscribe_from_system_event` - **event_request** (`SystemEventRequest`) - Required - The type of system event to subscribe to or unsubscribe from. ### Request Example (Subscription) ```rust client.subscribe_to_system_event(SystemEventRequest::FourSeconds)?; client.subscribe_to_system_event(SystemEventRequest::Pause)?; ``` ### Response - **Notification::SystemEvent(event)** - Received when a subscribed system event occurs. - `SystemEvent::FourSeconds` - `SystemEvent::Pause { state: bool }` - `SystemEvent::Sim { state: bool }` - `SystemEvent::AircraftLoaded { file_name: String }` - `SystemEvent::FlightLoaded { file_name: String }` - `SystemEvent::View { view: View }` ### Request Example (Unsubscription) ```rust client.unsubscribe_from_system_event(SystemEventRequest::FourSeconds)?; ``` ``` -------------------------------- ### SimConnect::subscribe_to_client_event / unsubscribe_from_client_event / unsubscribe_from_all_client_events Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Enables monitoring of cockpit input events, allowing subscriptions to specific client events like throttle changes or brake activation, and provides methods to unsubscribe individually or from all client events. ```APIDOC ## `SimConnect::subscribe_to_client_event` / `unsubscribe_from_client_event` / `unsubscribe_from_all_client_events` — Monitor cockpit input events Subscribe to `ClientEventRequest` variants to receive `ClientEvent` notifications whenever the user (or automation) triggers aircraft controls such as throttle changes, elevator input, or brake activation. Each event carries a typed `value: i32` where applicable. Available client events: `Throttle1Set`–`Throttle4Set`, `AxisElevatorSet`, `Brakes`, `BrakesLeft`, `BrakesRight`, `AxisLeftBrakeSet`, `AxisRightBrakeSet`, `ParkingBrakes`. ### Method - `subscribe_to_client_event(event_request: ClientEventRequest)` - `unsubscribe_from_client_event(event_request: ClientEventRequest)` - `unsubscribe_from_all_client_events()` ### Parameters #### `subscribe_to_client_event` / `unsubscribe_from_client_event` - **event_request** (`ClientEventRequest`) - Required - The type of client event to subscribe to or unsubscribe from. ### Request Example (Subscription) ```rust client.subscribe_to_client_event(ClientEventRequest::Throttle1Set)?; client.subscribe_to_client_event(ClientEventRequest::AxisElevatorSet)?; ``` ### Response - **Notification::ClientEvent(event)** - Received when a subscribed client event occurs. - `ClientEvent::Throttle1Set { value: i32 }` - `ClientEvent::AxisElevatorSet { value: i32 }` - `ClientEvent::ParkingBrakes` ### Request Example (Individual Unsubscription) ```rust client.unsubscribe_from_client_event(ClientEventRequest::Throttle1Set)?; ``` ### Request Example (Unsubscribe All) ```rust client.unsubscribe_from_all_client_events()?; ``` ``` -------------------------------- ### Run Data Receiver Without Derive Macro Source: https://github.com/mihai-dinculescu/simconnect-sdk-rs/blob/main/examples/README.md Execute the 'data_without_macro' binary to receive data without using the derive macro. ```bash cargo run --bin data_without_macro ``` -------------------------------- ### SimConnect::request_facilities_list Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Requests the full current facilities cache for a given FacilityType. The simulator responds with facility list messages, and the registration is automatically cleaned up. ```APIDOC ## `SimConnect::request_facilities_list` — One-shot facilities query Requests the full current facilities cache for a given `FacilityType` (`Airport`, `Waypoint`, `NDB`, or `VOR`). The simulator responds with one or more `Notification::AirportList` / `WaypointList` / `NdbList` / `VorList` messages, then the registration is automatically cleaned up (transient request). ```rust use simconnect_sdk::{FacilityType, Notification, SimConnect}; fn main() -> Result<(), Box> { let mut client = SimConnect::new("facilities-list demo")?; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { // One-shot: returns current cache then auto-unregisters client.request_facilities_list(FacilityType::Airport)?; } Some(Notification::AirportList(airports)) => { for airport in &airports { if airport.icao == "EGLL" { // Output: Airport { icao: "EGLL", lat: 51.4775, lon: -0.4614, alt: 25.3 } println!("{airport:?}"); } } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` ``` -------------------------------- ### Registering multiple objects simultaneously Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Multiple `SimConnectObject` types can be registered at the same time, each with its own auto-managed request ID. Incoming `Notification::Object` messages are dispatched via the type-name embedded in the object; use sequential `try_from` calls and `continue` to route cleanly. ```APIDOC ## Registering multiple objects simultaneously Multiple `SimConnectObject` types can be registered at the same time. Each gets its own auto-managed request ID. Incoming `Notification::Object` messages are dispatched via the type-name embedded in the object; use sequential `try_from` calls and `continue` to route cleanly. ``` -------------------------------- ### SimConnect::subscribe_to_facilities / SimConnect::unsubscribe_to_facilities Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Subscribes to streaming updates for facilities of a given type. Delivers the full current cache immediately and then continues sending additions. Call unsubscribe when done. Each FacilityType supports one active subscription at a time. ```APIDOC ## `SimConnect::subscribe_to_facilities` / `unsubscribe_to_facilities` — Streaming facilities updates Unlike `request_facilities_list`, `subscribe_to_facilities` delivers the full current cache immediately and then continues sending additions as new facilities enter the aircraft's reality bubble. Call `unsubscribe_to_facilities` when done. Each `FacilityType` supports one active subscription at a time. ```rust use simconnect_sdk::{FacilityType, Notification, SimConnect}; fn main() -> Result<(), Box> { let mut client = SimConnect::new("facilities-subscribe demo")?; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.subscribe_to_facilities(FacilityType::Waypoint)?; client.subscribe_to_facilities(FacilityType::NDB)?; client.subscribe_to_facilities(FacilityType::VOR)?; } Some(Notification::WaypointList(wps)) => { for wp in &wps { if wp.icao == "BRAIN" { // Waypoint { icao: "BRAIN", lat: 52.19, lon: 0.12, alt: 24.0, mag_var: -0.4 } println!("{wp:?}"); client.unsubscribe_to_facilities(FacilityType::Waypoint)?; } } } Some(Notification::NdbList(ndbs)) => { for ndb in &ndbs { if ndb.icao == "CAM" { println!("{ndb:?}"); client.unsubscribe_to_facilities(FacilityType::NDB)?; } } } Some(Notification::VorList(vors)) => { for vor in &vors { if vor.icao == "LON" { // VOR { icao: "LON", has_localizer: true, glide_slope_angle: Some(3.0), ... } println!("{vor:?}"); client.unsubscribe_to_facilities(FacilityType::VOR)?; } } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` ``` -------------------------------- ### Register and Unregister Single Object Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Demonstrates how to register a single data object (GpsData) for streaming and then unregister it after receiving a specified number of samples. Requires the `SimConnectObjectExt` trait. ```rust use simconnect_sdk::{Notification, SimConnect, SimConnectObject}; #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second")] #[allow(dead_code)] struct GpsData { #[simconnect(name = "PLANE LATITUDE", unit = "degrees")] lat: f64, #[simconnect(name = "PLANE LONGITUDE", unit = "degrees")] lon: f64, #[simconnect(name = "PLANE ALTITUDE", unit = "feet")] alt: f64, } fn main() -> Result<(), Box> { let mut client = SimConnect::new("register/unregister demo")?; let mut count = 0; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.register_object::()?; println!("GpsData registered"); } Some(Notification::Object(data)) => { if let Ok(gps) = GpsData::try_from(&data) { println!("lat={:.4} lon={:.4} alt={:.0}ft", gps.lat, gps.lon, gps.alt); count += 1; if count >= 5 { client.unregister_object::()?; println!("GpsData unregistered after 5 samples"); break; } } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } Ok(()) } ``` -------------------------------- ### Monitor Client Input Events in Rust Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Subscribe to client events triggered by aircraft controls. Unsubscribe from a specific event after a certain number of occurrences or unsubscribe from all client events at once. ```rust use simconnect_sdk::{ClientEvent, ClientEventRequest, Notification, SimConnect}; fn main() -> Result<(), Box> { let mut client = SimConnect::new("client-events demo")?; let mut throttle_count = 0; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.subscribe_to_client_event(ClientEventRequest::Throttle1Set)?; client.subscribe_to_client_event(ClientEventRequest::AxisElevatorSet)?; client.subscribe_to_client_event(ClientEventRequest::ParkingBrakes)?; } Some(Notification::ClientEvent(event)) => match event { ClientEvent::Throttle1Set { value } => { // value: -16383 (idle) .. +16383 (full throttle) println!("Throttle1 → {value}"); throttle_count += 1; if throttle_count >= 10 { client.unsubscribe_from_client_event(ClientEventRequest::Throttle1Set)?; } } ClientEvent::AxisElevatorSet { value } => { // value: -16383 (full down) .. +16383 (full up) println!("Elevator → {value}"); } ClientEvent::ParkingBrakes => { println!("Parking brake toggled"); // Stop listening to all client events at once client.unsubscribe_from_all_client_events()?; } _ => {} }, _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` -------------------------------- ### Subscribe to System Events in Rust Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Subscribe to various system events like timing pulses, state changes, and file load notifications. Unsubscribe from specific events after they are no longer needed. ```rust use simconnect_sdk::{Notification, SimConnect, SystemEvent, SystemEventRequest}; fn main() -> Result<(), Box> { let mut client = SimConnect::new("system-events demo")?; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.subscribe_to_system_event(SystemEventRequest::FourSeconds)?; client.subscribe_to_system_event(SystemEventRequest::Pause)?; client.subscribe_to_system_event(SystemEventRequest::Sim)?; client.subscribe_to_system_event(SystemEventRequest::AircraftLoaded)?; client.subscribe_to_system_event(SystemEventRequest::FlightLoaded)?; client.subscribe_to_system_event(SystemEventRequest::View)?; } Some(Notification::SystemEvent(event)) => match event { SystemEvent::FourSeconds => { println!("4-second heartbeat"); client.unsubscribe_from_system_event(SystemEventRequest::FourSeconds)?; println!("Unsubscribed from FourSeconds"); } SystemEvent::Pause { state } => println!("Paused: {state}"), SystemEvent::Sim { state } => println!("Sim running: {state}"), SystemEvent::AircraftLoaded { file_name } => { println!("Aircraft loaded: {file_name}") } SystemEvent::FlightLoaded { file_name } => println!("Flight loaded: {file_name}"), SystemEvent::View { view } => println!("View changed: {view:?}"), _ => {} }, _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` -------------------------------- ### Declare simulation-variable structs with SimConnectObject Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Annotate a Rust struct with `#[derive(SimConnectObject)]` and `#[simconnect(...)]` attributes to bind it to simulator variables. This macro generates code for data definition, request, and deserialization. Use `period`, `condition`, and `interval` for struct-level configuration, and `name` and `unit` for field-level configuration. ```rust use simconnect_sdk::{Notification, SimConnect, SimConnectObject}; #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second", condition = "changed")] #[allow(dead_code)] struct AirplaneData { #[simconnect(name = "TITLE")] title: String, #[simconnect(name = "CATEGORY")] category: String, #[simconnect(name = "PLANE LATITUDE", unit = "degrees")] lat: f64, #[simconnect(name = "PLANE LONGITUDE", unit = "degrees")] lon: f64, #[simconnect(name = "PLANE ALTITUDE", unit = "feet")] alt: f64, #[simconnect(name = "SIM ON GROUND")] sim_on_ground: bool, } fn main() -> Result<(), Box> { let mut client = SimConnect::new("AirplaneData demo")?; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.register_object::()?; } Some(Notification::Object(data)) => { if let Ok(d) = AirplaneData::try_from(&data) { println!("{d:?}"); // Output: AirplaneData { title: "Cessna 172", lat: 51.47, lon: -0.46, alt: 5200.0, sim_on_ground: false, ... } } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` -------------------------------- ### SimConnectObject derive macro Source: https://context7.com/mihai-dinculescu/simconnect-sdk-rs/llms.txt Annotates a Rust struct with `#[derive(SimConnectObject)]` and field-level `#[simconnect(...)]` attributes to bind it to simulation variables. This macro generates necessary implementations for data definition and deserialization. ```APIDOC ## `SimConnectObject` derive macro — Declare simulation-variable structs Annotate a plain Rust struct with `#[derive(SimConnectObject)]` and per-field `#[simconnect(...)]` attributes to bind it to one or more simulator variables. The macro generates the `SimConnectObjectExt` impl (which calls `add_to_data_definition` + `request_data_on_sim_object`) and a `TryFrom<&Object>` impl for deserialisation. **Struct-level attributes** | Attribute | Required | Values | Description | |-----------|----------|--------|-------------| | `period` | Yes | `once`, `visual-frame`, `sim-frame`, `second` | How often data is delivered | | `condition` | No (default `none`) | `none`, `changed` | Only send when values change | | `interval` | No (default `0`) | integer | Skip N periods between sends | **Field-level attributes** | Attribute | Required | Description | |-----------|----------|-------------| | `name` | Yes | SimVar name (e.g. `"PLANE ALTITUDE"`) | | `unit` | No | Unit string (e.g. `"feet"`); omit for `String`/`bool` | Supported field types: `f64`, `bool`, `String`. ```rust use simconnect_sdk::{Notification, SimConnect, SimConnectObject}; #[derive(Debug, Clone, SimConnectObject)] #[simconnect(period = "second", condition = "changed")] #[allow(dead_code)] struct AirplaneData { #[simconnect(name = "TITLE")] title: String, #[simconnect(name = "CATEGORY")] category: String, #[simconnect(name = "PLANE LATITUDE", unit = "degrees")] lat: f64, #[simconnect(name = "PLANE LONGITUDE", unit = "degrees")] lon: f64, #[simconnect(name = "PLANE ALTITUDE", unit = "feet")] alt: f64, #[simconnect(name = "SIM ON GROUND")] sim_on_ground: bool, } fn main() -> Result<(), Box> { let mut client = SimConnect::new("AirplaneData demo")?; loop { match client.get_next_dispatch()? { Some(Notification::Open) => { client.register_object::()?; } Some(Notification::Object(data)) => { if let Ok(d) = AirplaneData::try_from(&data) { println!("{d:?}"); // Output: AirplaneData { title: "Cessna 172", lat: 51.47, lon: -0.46, alt: 5200.0, sim_on_ground: false, ... } } } _ => {} } std::thread::sleep(std::time::Duration::from_millis(16)); } } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.