From f950111be1e3171bf591e8e4f018518cd8530caf Mon Sep 17 00:00:00 2001 From: Randy T <47700786+rthom91@users.noreply.github.com> Date: Thu, 7 May 2026 21:49:11 -0400 Subject: [PATCH 1/6] 0.24.5 DLL --- SimConnect.dll | Bin 67072 -> 67072 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/SimConnect.dll b/SimConnect.dll index 2aa284c02b3a18123fd0ae619d1bcd35334b254d..8f0fe287bf12976fd86e0b41ec827fb98367c862 100644 GIT binary patch delta 6981 zcmeI0Yj{-ExyRp`Ok#k*nLq#`K|&2T36w%aE`kZ+l4!6)62yY`WXKF8$4N3y28aku zu$05GfYA*W6)-&o%0aY|aI*(BRFI1x18U28sxneak(&{*MGJC%Yu1`H&6o4_d}yBM z&+ot9^{&0wW$!&}QM%-e=eG zk@kdW{^+(z%o*mjQ$u&{Lvn)ZL zIedSam10}iuJ(dR_P>ZUSufarW&5--$DTgQHmGsdm_N+5-PSnn^?PnhJlIntZ{^q~ zYtf#p#Funob>ka*CdY?d-|1V7H!LxX-FU6T7PX5F%M1$)M;h)hOfb9wPOZ7}3{r-68Ti3R?T#zo+kB6Ae!m8I&iY%gp!LL}`gxy^i

=Y#P3>5RhAlZnP4N1~Gnv1eKN zAKaH*KtMe?;qQrjg9@w{K1j6{SUW#BK6t`8Q@2Z`?{40kXgNXT8am6%7EF?Gtj>D< z!za65QyI~T=^%aPi{v1&az5&E|LuR)*HV#bC{}LCiq<=#3oFHmQa_J;@}gJdB7ZM8 zZuqF1-PZ8)AJ}YNtn@>U_F>+t>nQ!gvwgZ*u0sy1`S%O$Wf!bf2fK~Z6c`MZv>knfzC<0q;5|e$(K7T3I)W~vcwX^- zXgXSmUP8OjDfBsVe#u&(0`xd~7HvgGPy~I8oL5B#UX_sKVM@`HXdP-o=aBO&k^U$L z%|tb5IogEwp-+)qqa$cC@}Zxh*U)?D3)Jyzk-_Kz9ScQsza{uE!J1Zy@7ioqPwY^u*ePPoD%R@vHG|*AX4UCdu?fU#iPf}si zdFAXX*<=m6bWiW8_CoKRTwhhS_W|z{vP6}B==WAqm{^k|tE?rL`uyvwc2`w(aEiCO z+C9gc!Z-YO0|AN?$^#@<1)d;&(&VX*T~9^6Fq7 zSyJD4@oHC_<%~<;el5`+N{sMjPZpVqJnVr>;0Gv!cmxjb!sZm84R<4z)3PVVx85(S zee}KEL_Q?0I0>D{D^5n&@h!^sphIHMa z33l$I4=d^Lx9kFiU17_P5U+NIi5cYJ6+59IUNHqN#izs7eGwbidiXI?TkQx;3-!|l z7ktY2I{1b0PWH9Yz3o}eQU^Qj72U@$HF(9*=o&s7-b88yaxY)5v3g`JCluo9N zAX<)BT#7d06`w(S@J;a8cm_a+!sA11U2}OVnZ^j5Iziv81l}-SCW;iI{WNHOXlZ?* zQ3suMsDvEFCKSXg9z;v=VK{j*gW_H;=ttW^5p9-G*nzKuzc9W5?lV3NV@FFxM?M!M zU$G}Ti&yM}uHhB?o4Dd&6CVl#NZm`FkV4TT5V3d^m}p zVbxI=>|CLrv-A+=0#Y|?hNt)yRXzeo`1NSAVaLaH+zET|%e;=+N{0ihwI2%ao~uWh z4Li-#v*m96L6KqUXr@=0wWqTc1PKd2}VpB(AsyW#bk93%T%$4X6aK z7)CXC#Va*>s+(cl0yFJ!#gn?Dbx-pCCoR$iCmg?6dly{I(nKE?xV%=6z79URM31Zl zI)1_#gPCx`PmucRMc`LU_08m`9MG5PX&(xw{k!%huyDEZT)YG`_&;>xq41{h@-#=( zpP5d;u`9LDhTB*1YsM&>;O1xaMH}GOXLU{kJZ{k$Iv0k2T&+9gUnBC|^Lkn9;isXW z^S-L}hVQK9bvjQ2xc&v*p?X;HqV|3`_9gAJVaIjaJK^#5+(1n`d~t)Gt$JATvS|w+ zsyCyD)xXdk3e{pZ{3j0{jqBltU+ScKcxt2e5qM~mzGxV}xY^tQF8`HT8n|GK&aZ`2 zx9V5A1YUZDZv->Z4BNk|XUGY!zsmZnr(IqX$^SL$NRkWYHy95`ysmvVoUvUuE`fQC z`o=EUd53wO;2Gna;hQ`4=$qi-UHVOF`Hvay)ps}R|K4ss1QZlMLVmpBB~*)7{F{m2 zfFt+l*C`Kr(T)h;2>1@lWcecSJ2Vn6Z}8bh>h;Tnub_L0Z-Y0`ju4HN>HObxf{GNl z7S-Vu5AWr3j6Vw7y{SJenXmwDqir!vA}r6HAr=IExhx$Q6G{F z%wCj5?-V1tBFc8}=mu$U&VEKkP8r;Y)Sf^wV!Yy#cllu$&XfwR$aydSPb t6L{vr@bba?n1;`orbFy>k@AWK#w(T>ulPJl;zEkAq2k^AZ`*Ol{{np8qt^fc delta 6920 zcmeI0Yj{-ExyRqh%|Ihf2nr#oBpL*&SgNRqpa}_(Nbn3vM9M`oFk3P*WYWn10mK;; zZLG0|?nKcd#vVYt(MV9}Q&6m+6cHxe%5&tD0aHZ`G@#|s7V-SntTi#^OTYF*^E`ik z|Ml*7UH9y@*Cte-5UNjT2>Es#`FrWot&NVD>ULb_c!Ki&olWwyD3?o9lntWe&&nf| zn+`QeJzToA$?+#RcIR?=EXqa+MLEZz`AoE2>X}tZANH~B87a=OBJRhNWPiKIvimq5 z>d|~sB=7qo5&JpE%Z`h!`El8|ISN{5-u}rv$AH#5-n{j)y%COGRYdFR5fZ?@-t9wcN*49G#-?b zCb7`auP?|uW+1x^4;i)_er+h<>Y-*C4mT_@bQ=Z?>kXfeGAOdv1lAjFH#}^3+EC2E zQVa(h78*`AjIG>xQ$BP_{O#`LAlc($Gch%PeM$L7hhD-_hT{zHGaPKV+Hk$$2ZptV zv4Q=fTiL$wZf-`h>F_e05y~>@=SSz;V&<_KGNLrB*Uu> z+fCjs!&ePg8Q!INwQM$lScg}ca*APXtK+>#<0q;ILZ!r^5bART?ZWUEyOx6QgBrQk zc*(WPiLa*eI}Rji_WtX$_++Bv(^XH;`#L{D0%b-MyC#`lHDd1~l#Zmp^v+Xrs2bWY@NBI=pC z!K2E#H>#ZWzw7y%*i9;S-d?^tJudm8y>|D-p{waAhhQj6)j$U!n%ips)CoxVE zhxe3i=^}ej*lzncJ?F5gp(4joto&V8;vPG#KBC)oUM2D-s<&U+b8FfG6Ah0Sxvog$ zfPH39y5oSIxOc$7>|?q{>LihANSC=k!;_>dW*6_hrdK_g$GI@L3A4#ww0CA&Y#PI^ z6B&3M{ zju!Et)%Hu_^sausi|z{BywG&~{6&jc^9L!U)eXH*9oGJFvY=VFcx%3!)?E?e{b6K&&;*AMFwsXnQkvRkm;Ci zKX+hpamweh34c#=7Kr4dezBOlN3?tov0*Ak`|5i4a#tOD#=*Y5qpgwEJfCbbQ$BBf z{NR;wj-Ai`*x^XGvv(%+IPnE5aFVImKRujohyS?D5sJFz4-*o*;>(96=X}c_P08fb zdaIv?SK3MC;T`nRy5_LY5wy7cBzgnwLw`kSf8hs=?naBzTJ#Y*i7xMC5zsia0Ifv7 zLx<3L)Z+}3MJ33KmZLY(E_4#fS&{x|7%Dz1L8-(%ihhN*pa@F(iUc$sxzJ*?0wXUPF7(m+1R{6&Z>qqB-a>vtUtkf; z-$?Z`+9y)mEjF20sEx&BbBp~os=TmBUAMdq#2U!!_m5Z>>%+@9o4m?ydAo>Jljqd2 zU^KhG!y!`$uIQHd8L?(!C%VPX6YEs5Z@%lKkT+hZ8g#dqn^=h0if*xG#F~j!c8jfz zx8FI@|3AmH{~Xi)y^m?-|N5AA$uX`-?k&qNwPwwiiOQ8(Rc=`$v#o&3?e=@B9`Nyw z{a(kd1E$55TC)qhz8Y(SwNRc^rT?n7swj-D&6gFnt0U+B^>I#LO<ristJts`+a_q z8Yys9&9c13K9L9QV;z}}5%xD7eKWSlmsqa(Rsqd;X1Tm&)~tZXSH;F?4?Wd)!n;!7 zw_E{h?0l;#z&J8gs|EA?eu{-2KgmA-LgF8oJT;Jfxi+!P3Ph`jJe^qPwXAB%v7bJ5 zMe)O`{zRX9p4Zajq;Bxim|6x_pG>FUH!GjjV;y)`BzbEB{#l$-^JSxb>Qttq#qM!B zv$!+yUY93uw`;EDc6zGSYCR}pJXP*upE}ZdEj6D4m)ASfHH*EzG-1*_%fHZR`5*B4 z=c*+s@Xf0VSbiz9=bj$on9%y{>9qJO4knZayalf6z&t+*T(1qt5qs;Ij4M7>S0;P> zfq5?PJyi?nNMxJ+<(bUHpqjSbaVBF(cDH3xb5P@7l~`{1=X$DG%~*(2{RVc+ zF0W+0-Nm%|Rh%6<+s`r3e(r2$UtfH26*tJ`^(?Z=N<1}zBC_PM){o9!;n?tXa$GPw z!uFgdG6_Az3AO_6N27>G;7#egknwqN6H+-{Ct7^>)2=%8j=EB$gSg^2B-B+Lk5chY zxD`d)xssRoslL3hxzGvwWbmS*ayGnx+{C3n?@r{!x4;Eiyg%^W59aEC{uO$ix{5hJ zV37D>@aC)ZWV#OA)Kv%X)dM)lM1tBJrLd6;5!jNgD{OOdWVS;1>{!3iHRz5)Kl_^uOcyFR%d z9>ft0ulOx0!pmThF-R?G1TNt0o_w4Yf`3HOIE-Xq)7)@9=M8+zQ?ZWe`{2AnrRvmQhzRfSU1&%g`3Q;?pRM-v&P( z!vttQJSNDAu7HCE%NT)^3Uy}{@PhF&mWLl5p+eV(2fq79iTYSsiE4=}ZbS8W#ShU+ zd>D=&&j&AkIbk*09*k(Sl)`R&1ANK&7Wkg=VHo`|Bu6o!n3EM=u|K+iSIj{vEU)4q z6IUE+;=`aHslL>APcZu7!-y2yC$MyQ#iSCR2z)AZOk$+U!`K(7;_K*oI#b+)^6-l9 zASZqsTvJNhf95w;CSu>iEyg!P@4ZnUlxj@iCsh875y7KVby5VrF-_m^7Pw@(_96Jz z44tzLuDy@h&}a)xs^BB=a|Q}~yL3DoemPU;cfxo#?+Ef!VY!?8ukLFFg~u&MM&$-r z`v9vzQV3Sg*1j4}snos#7J0OH!VwQ@p9dd7qgdVsIAe~#?T5je=jmDI!Cv$AYNf)7NNqSy z*of4GW1oq^=y&6S@4h~}e`Tt#&8JWytD@M1rr;G{L6vyL7F3H@45J3T;^|tw)SWPX zky&4_OJCnya={&BNeHgswXWCc5(mLg7yaF@y30-*@{Kk0sIbW7fnnA$PPidbAH~fN5 zPw)$eYoFGQw!l}H>zo$2*JfvAaAEjqqaILolgKZh(YLi3{weq@&nrn0`2GqWCmIdI z7oO7tYKC*4*S;E#{+0H5@bZ<~r^3B2(1BWZ`1~rpTFr3oi>5A|+-znKYhKa=3WhMN ze$9`M%FS@qf9s@XczCt;5x8@WZZr&^Uu!ymbuXJ+0~f8+`5`#zRsBd;z>e40KbT}E z?D>XXp;UPO4er1Cwaa==X}{r(M3NI0w-^s^c~kp5ICX=rTmg$(b;nNFd!u=r;Bn(S z;nuhG?6<)`yse*xJ z_SmX7mg`{&+D_eaScg;xic{aAqc8Z6CipQLjt|3!-sN`S6<1g;dUEnUWG_K0@D=a@)QqoIF*KduTo|7E@J_bF jW1Pcwa?(Z0E0!3qSYf>4Gbopa6xSo~CjNJAZ^Hira1yx; From a3c97a616b6950bc61ae0fbda76f727a8bf6b7b9 Mon Sep 17 00:00:00 2001 From: Randy T <47700786+rthom91@users.noreply.github.com> Date: Fri, 8 May 2026 00:28:12 -0400 Subject: [PATCH 2/6] Readme corrections --- Readme.md | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/Readme.md b/Readme.md index c960e92..90da561 100644 --- a/Readme.md +++ b/Readme.md @@ -2,12 +2,18 @@ # SimConnect Bindings for Rust -## Requirements +This crate provides Rust bindings to receive and send information through SimConnect, for Microsoft Flight Simulator (2020). -- [CLang](https://clang.llvm.org/get_started.html) (See the [Rust Bindgen Documentation](https://rust-lang.github.io/rust-bindgen/requirements.html)) -- MSVC x64 Rust build (`x86_64-pc-windows-msvc`, see [The rustup book](https://rust-lang.github.io/rustup/installation/windows.html)) +Documentation can be found at: [MSFS 2020 SDK](https://docs.flightsimulator.com/html/Programming_Tools/SimConnect/SimConnect_SDK.htm) -## Using +### Requirements + +- [Rust](https://rust-lang.org/learn/get-started) +- [LLVM/Clang](https://clang.llvm.org/get_started.html) + +See the [Rust Bindgen Documentation](https://rust-lang.github.io/rust-bindgen/introduction.html) + +### Using Add this to your `Cargo.toml` @@ -16,14 +22,16 @@ Add this to your `Cargo.toml` simconnect = "0.4" ``` -## Building +_You must have SimConnect.dll in the same directory as your executable._ + +### Building _The SimConnect binaries are included within this repository, but they may not be up-to-date._ -1. run `cargo build` -2. Add `use simconnect` at the top of your file +1. Run `cargo build` +2. Add import `use simconnect` at the top of your file -## Example +### Examples Read float position data @@ -31,14 +39,12 @@ Read float position data cargo run --example aircraft_updates ``` -Requests tagged data with thresholds from SimConnect and reads floats/strings +Requests tagged data with thresholds from SimConnect, and reads floats/strings ``` cargo run --example aircraft_updates_on_change ``` -_You must have SimConnect.dll in the same directory as the compiled exe for it to run (e.g. in )_ - ### Remarks -I have not tested every single function from the api. If you find an error, feel free to make an issue or a pull request. +I have not tested every function of the API. If you find an error, feel free to make an issue or pull request. From 2b510fcafb32768c731fa190ff3eac9e33e235fe Mon Sep 17 00:00:00 2001 From: Randy T <47700786+rthom91@users.noreply.github.com> Date: Fri, 8 May 2026 00:49:17 -0400 Subject: [PATCH 3/6] Fix example typos --- examples/aircraft_updates/main.rs | 8 ++++---- examples/aircraft_updates_on_change/main.rs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/aircraft_updates/main.rs b/examples/aircraft_updates/main.rs index 5e6eedf..44ae0ce 100644 --- a/examples/aircraft_updates/main.rs +++ b/examples/aircraft_updates/main.rs @@ -1,6 +1,5 @@ use std::thread::sleep; use std::time::Duration; - use simconnect::DispatchResult; struct DataStruct { @@ -8,9 +7,10 @@ struct DataStruct { lon: f64, alt: f64, } + fn main() { let mut conn = simconnect::SimConnector::new(); - conn.connect("Simple Program"); // Intialize connection with SimConnect + conn.connect("Simple Program"); // Initialize connection with SimConnect conn.add_data_definition( 0, "PLANE LATITUDE", @@ -34,7 +34,7 @@ fn main() { simconnect::SIMCONNECT_DATATYPE_SIMCONNECT_DATATYPE_FLOAT64, u32::MAX, 1.0, - ); //define_id, units, data_type, datum_id, epsilon (update threshold) + ); // define_id, units, data_type, datum_id, epsilon (update threshold) conn.request_data_on_sim_object( 0, 0, @@ -44,7 +44,7 @@ fn main() { 0, 0, 0, - ); //request_id, define_id, object_id (user), period, falgs, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft + ); // request_id, define_id, object_id (user), period, flags, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft loop { match conn.get_next_message() { diff --git a/examples/aircraft_updates_on_change/main.rs b/examples/aircraft_updates_on_change/main.rs index f4211a0..4e51592 100644 --- a/examples/aircraft_updates_on_change/main.rs +++ b/examples/aircraft_updates_on_change/main.rs @@ -1,9 +1,9 @@ -use simconnect::{DispatchResult, DWORD}; use std::ptr::read_unaligned; use std::thread::sleep; use std::time::Duration; +use simconnect::{DispatchResult, DWORD}; -// To allign the memory we have to set a fixed max size to the returned variables from the game +// To align the memory we have to set a fixed max size to the returned variables from the game const MAX_RETURNED_ITEMS: usize = 255; // Rust will add padding to the inner parts of a struct if it isn't marked as packed @@ -54,7 +54,7 @@ fn main() { simconnect::SIMCONNECT_DATATYPE_SIMCONNECT_DATATYPE_FLOAT64, 3, 100.0, - ); //define_id, units, data_type, datum_id, epsilon (update threshold) + ); // define_id, units, data_type, datum_id, epsilon (update threshold) // Here we define all our variabes that get returned as Strings // Notice how the define_id differs from the float values @@ -82,7 +82,7 @@ fn main() { 0, 0, 0, - ); //request_id, define_id, object_id (user), period, falgs, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft + ); // request_id, define_id, object_id (user), period, flags, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft // Request the data from our define_id 1 (strings) // The request_id has to differ from the float request. Or else it will overwrite the previous request conn.request_data_on_sim_object( @@ -95,7 +95,7 @@ fn main() { 0, 0, 0, - ); //request_id, define_id, object_id (user), period, falgs, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft + ); // request_id, define_id, object_id (user), period, flags, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft loop { match conn.get_next_message() { From 93c4cd5d02cf042164ec2cb937930bb1d8a5df0a Mon Sep 17 00:00:00 2001 From: Randy T <47700786+rthom91@users.noreply.github.com> Date: Fri, 8 May 2026 00:55:50 -0400 Subject: [PATCH 4/6] tweaks --- Readme.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index 90da561..24ee76b 100644 --- a/Readme.md +++ b/Readme.md @@ -2,18 +2,20 @@ # SimConnect Bindings for Rust -This crate provides Rust bindings to receive and send information through SimConnect, for Microsoft Flight Simulator (2020). +This crate provides Rust bindings to send/receive information through SimConnect, for Microsoft Flight Simulator (2020). Documentation can be found at: [MSFS 2020 SDK](https://docs.flightsimulator.com/html/Programming_Tools/SimConnect/SimConnect_SDK.htm) -### Requirements + +## Requirements - [Rust](https://rust-lang.org/learn/get-started) - [LLVM/Clang](https://clang.llvm.org/get_started.html) See the [Rust Bindgen Documentation](https://rust-lang.github.io/rust-bindgen/introduction.html) -### Using + +## Using Add this to your `Cargo.toml` @@ -24,14 +26,16 @@ simconnect = "0.4" _You must have SimConnect.dll in the same directory as your executable._ -### Building + +## Building _The SimConnect binaries are included within this repository, but they may not be up-to-date._ 1. Run `cargo build` 2. Add import `use simconnect` at the top of your file -### Examples + +## Examples Read float position data @@ -45,6 +49,7 @@ Requests tagged data with thresholds from SimConnect, and reads floats/strings cargo run --example aircraft_updates_on_change ``` -### Remarks + +## Remarks I have not tested every function of the API. If you find an error, feel free to make an issue or pull request. From cc1e481138b86936372f5f007b56018fb0aedbe7 Mon Sep 17 00:00:00 2001 From: Randy T <47700786+rthom91@users.noreply.github.com> Date: Fri, 8 May 2026 01:00:54 -0400 Subject: [PATCH 5/6] Shorten about --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 24ee76b..70d97c7 100644 --- a/Readme.md +++ b/Readme.md @@ -2,7 +2,7 @@ # SimConnect Bindings for Rust -This crate provides Rust bindings to send/receive information through SimConnect, for Microsoft Flight Simulator (2020). +Send and receive information through SimConnect, for Microsoft Flight Simulator (2020). Documentation can be found at: [MSFS 2020 SDK](https://docs.flightsimulator.com/html/Programming_Tools/SimConnect/SimConnect_SDK.htm) From b5874b70b600c28f0917b96d7473e9b69a360e01 Mon Sep 17 00:00:00 2001 From: Randy T <47700786+rthom91@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:39:15 -0400 Subject: [PATCH 6/6] Refactor and update for SU16 --- Cargo.lock | 34 +- Cargo.toml | 4 +- build.rs | 548 +++++++++++---------- src/lib.rs | 1361 ++++++++++++++++++++++++++-------------------------- 4 files changed, 983 insertions(+), 964 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ee65d1..d662df3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "cexpr" @@ -65,9 +65,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "glob" @@ -102,15 +102,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "minimal-lexical" @@ -149,18 +149,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -181,9 +181,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rustc-hash" @@ -199,16 +199,16 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "simconnect" -version = "0.4.0" +version = "0.5.0" dependencies = [ "bindgen", ] [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a0b921b..8d08e3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,9 +2,9 @@ name = "simconnect" license = "MIT" description = "Rust bindings for SimConnect" -version = "0.4.0" +version = "0.5.0" authors = ["Connor T"] -edition = "2018" +edition = "2021" [[example]] name = "aircraft_updates_on_change" diff --git a/build.rs b/build.rs index 5973c70..f65b5f4 100644 --- a/build.rs +++ b/build.rs @@ -4,267 +4,299 @@ fn main() { println!("cargo:rustc-link-search=libsrc/lib"); println!("cargo:rustc-link-lib=static=SimConnect"); - let bindings = bindgen::Builder::default() - .header("libsrc/include/SimConnect.hpp") - .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + let handle = std::thread::Builder::new() + .stack_size(128 * 1024 * 1024) + .spawn(|| { + let mut builder = bindgen::Builder::default() + .header("libsrc/include/SimConnect.hpp") + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .impl_debug(true); - // ==================== CONSTANTS ==================== - .allowlist_var("SIMCONNECT_UNUSED") - .allowlist_var("SIMCONNECT_OBJECT_ID_USER") - .allowlist_var("SIMCONNECT_CAMERA_IGNORE_FIELD") - .allowlist_var("SIMCONNECT_CLIENTDATA_MAX_SIZE") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_HIGHEST") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_STANDARD") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_DEFAULT") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_LOWEST") - .allowlist_var("MAX_METAR_LENGTH") - .allowlist_var("MAX_THERMAL_SIZE") - .allowlist_var("MAX_THERMAL_RATE") - .allowlist_var("INITPOSITION_AIRSPEED_CRUISE") - .allowlist_var("INITPOSITION_AIRSPEED_KEEP") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_INT8") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_INT16") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_INT32") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_INT64") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_FLOAT32") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_FLOAT64") - .allowlist_var("SIMCONNECT_CLIENTDATAOFFSET_AUTO") - .allowlist_var("SIMCONNECT_OPEN_CONFIGINDEX_LOCAL") - .allowlist_var("SIMCONNECT_RECV_ID_VOR_LIST_HAS_NAV_SIGNAL") - .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_WAYPOINT_NONE") - .allowlist_var("SIMCONNECT_WAYPOINT_SPEED_REQUESTED") - .allowlist_var("SIMCONNECT_WAYPOINT_THROTTLE_REQUESTED") - .allowlist_var("SIMCONNECT_WAYPOINT_COMPUTE_VERTICAL_SPEED") - .allowlist_var("SIMCONNECT_WAYPOINT_ALTITUDE_IS_AGL") - .allowlist_var("SIMCONNECT_WAYPOINT_ON_GROUND") - .allowlist_var("SIMCONNECT_WAYPOINT_REVERSE") - .allowlist_var("SIMCONNECT_WAYPOINT_WRAP_TO_FIRST") - .allowlist_var("SIMCONNECT_WAYPOINT_ALWAYS_BACKUP") - .allowlist_var("SIMCONNECT_WAYPOINT_KEEP_LAST_HEADING") - .allowlist_var("SIMCONNECT_WAYPOINT_YIELD_TO_USER") - .allowlist_var("SIMCONNECT_WAYPOINT_CAN_REVERSE") - .allowlist_var("SIMCONNECT_EVENT_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_EVENT_FLAG_FAST_REPEAT_TIMER") - .allowlist_var("SIMCONNECT_EVENT_FLAG_SLOW_REPEAT_TIMER") - .allowlist_var("SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY") - .allowlist_var("SIMCONNECT_DATA_REQUEST_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_DATA_REQUEST_FLAG_CHANGED") - .allowlist_var("SIMCONNECT_DATA_REQUEST_FLAG_TAGGED") - .allowlist_var("SIMCONNECT_DATA_SET_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_DATA_SET_FLAG_TAGGED") - .allowlist_var("SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_CREATE_CLIENT_DATA_FLAG_READ_ONLY") - .allowlist_var("SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED") - .allowlist_var("SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_TAGGED") - .allowlist_var("SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_CLIENT_DATA_SET_FLAG_TAGGED") - .allowlist_var("SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_2D") - .allowlist_var("SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_VIRTUAL") - .allowlist_var("SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_ORTHOGONAL") - .allowlist_var("SIMCONNECT_SOUND_SYSTEM_EVENT_DATA_MASTER") - .allowlist_var("UNKNOWN_SENDID") - .allowlist_var("UNKNOWN_INDEX") - .allowlist_var("UNKNOWN_GROUP") - .allowlist_var("SIMCONNECT_CLOUD_STATE_ARRAY_WIDTH") - .allowlist_var("SIMCONNECT_CLOUD_STATE_ARRAY_SIZE") - .allowlist_var("SIMCONNECT_PICK_GROUND") - .allowlist_var("SIMCONNECT_PICK_AI") - .allowlist_var("SIMCONNECT_PICK_SCENERY") - .allowlist_var("SIMCONNECT_PICK_ALL") - .allowlist_var("SIMCONNECT_PICK_COORDSASPIXELS") + // ==================== CONSTANTS / VARS ==================== + let vars = [ + "SIMCONNECT_UNUSED", + "SIMCONNECT_OBJECT_ID_USER", + "SIMCONNECT_CAMERA_IGNORE_FIELD", + "SIMCONNECT_CLIENTDATA_MAX_SIZE", + "SIMCONNECT_GROUP_PRIORITY_HIGHEST", + "SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE", + "SIMCONNECT_GROUP_PRIORITY_STANDARD", + "SIMCONNECT_GROUP_PRIORITY_DEFAULT", + "SIMCONNECT_GROUP_PRIORITY_LOWEST", + "MAX_METAR_LENGTH", + "MAX_THERMAL_SIZE", + "MAX_THERMAL_RATE", + "INITPOSITION_AIRSPEED_CRUISE", + "INITPOSITION_AIRSPEED_KEEP", + "SIMCONNECT_CLIENTDATATYPE_INT8", + "SIMCONNECT_CLIENTDATATYPE_INT16", + "SIMCONNECT_CLIENTDATATYPE_INT32", + "SIMCONNECT_CLIENTDATATYPE_INT64", + "SIMCONNECT_CLIENTDATATYPE_FLOAT32", + "SIMCONNECT_CLIENTDATATYPE_FLOAT64", + "SIMCONNECT_CLIENTDATAOFFSET_AUTO", + "SIMCONNECT_OPEN_CONFIGINDEX_LOCAL", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_NAV_SIGNAL", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_LOCALIZER", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_GLIDE_SLOPE", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_DME", + "SIMCONNECT_WAYPOINT_NONE", + "SIMCONNECT_WAYPOINT_SPEED_REQUESTED", + "SIMCONNECT_WAYPOINT_THROTTLE_REQUESTED", + "SIMCONNECT_WAYPOINT_COMPUTE_VERTICAL_SPEED", + "SIMCONNECT_WAYPOINT_ALTITUDE_IS_AGL", + "SIMCONNECT_WAYPOINT_ON_GROUND", + "SIMCONNECT_WAYPOINT_REVERSE", + "SIMCONNECT_WAYPOINT_WRAP_TO_FIRST", + "SIMCONNECT_WAYPOINT_ALWAYS_BACKUP", + "SIMCONNECT_WAYPOINT_KEEP_LAST_HEADING", + "SIMCONNECT_WAYPOINT_YIELD_TO_USER", + "SIMCONNECT_WAYPOINT_CAN_REVERSE", + "SIMCONNECT_EVENT_FLAG_DEFAULT", + "SIMCONNECT_EVENT_FLAG_FAST_REPEAT_TIMER", + "SIMCONNECT_EVENT_FLAG_SLOW_REPEAT_TIMER", + "SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY", + "SIMCONNECT_DATA_REQUEST_FLAG_DEFAULT", + "SIMCONNECT_DATA_REQUEST_FLAG_CHANGED", + "SIMCONNECT_DATA_REQUEST_FLAG_TAGGED", + "SIMCONNECT_DATA_SET_FLAG_DEFAULT", + "SIMCONNECT_DATA_SET_FLAG_TAGGED", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG_READ_ONLY", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_DEFAULT", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_TAGGED", + "SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT", + "SIMCONNECT_CLIENT_DATA_SET_FLAG_TAGGED", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_2D", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_VIRTUAL", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_ORTHOGONAL", + "SIMCONNECT_SOUND_SYSTEM_EVENT_DATA_MASTER", + "UNKNOWN_SENDID", + "UNKNOWN_INDEX", + "UNKNOWN_GROUP", + "SIMCONNECT_CLOUD_STATE_ARRAY_WIDTH", + "SIMCONNECT_CLOUD_STATE_ARRAY_SIZE", + "SIMCONNECT_PICK_GROUND", + "SIMCONNECT_PICK_AI", + "SIMCONNECT_PICK_SCENERY", + "SIMCONNECT_PICK_ALL", + "SIMCONNECT_PICK_COORDSASPIXELS", + ]; - // ==================== TYPES / ENUMS ==================== - .allowlist_type("HANDLE") - .allowlist_type("SIMCONNECT_RECV_ID") - .allowlist_type("SIMCONNECT_DATATYPE") - .allowlist_type("SIMCONNECT_EXCEPTION") - .allowlist_type("SIMCONNECT_SIMOBJECT_TYPE") - .allowlist_type("SIMCONNECT_STATE") - .allowlist_type("SIMCONNECT_PERIOD") - .allowlist_type("SIMCONNECT_MISSION_END") - .allowlist_type("SIMCONNECT_CLIENT_DATA_PERIOD") - .allowlist_type("SIMCONNECT_TEXT_TYPE") - .allowlist_type("SIMCONNECT_TEXT_RESULT") - .allowlist_type("SIMCONNECT_WEATHER_MODE") - .allowlist_type("SIMCONNECT_FACILITY_LIST_TYPE") - .allowlist_type("SIMCONNECT_FACILITY_DATA_TYPE") - .allowlist_type("SIMCONNECT_INPUT_EVENT_TYPE") - .allowlist_type("SIMCONNECT_VOR_FLAGS") - .allowlist_type("SIMCONNECT_WAYPOINT_FLAGS") - .allowlist_type("SIMCONNECT_EVENT_FLAG") - .allowlist_type("SIMCONNECT_DATA_REQUEST_FLAG") - .allowlist_type("SIMCONNECT_DATA_SET_FLAG") - .allowlist_type("SIMCONNECT_CREATE_CLIENT_DATA_FLAG") - .allowlist_type("SIMCONNECT_CLIENT_DATA_REQUEST_FLAG") - .allowlist_type("SIMCONNECT_CLIENT_DATA_SET_FLAG") - .allowlist_type("SIMCONNECT_VIEW_SYSTEM_EVENT_DATA") - .allowlist_type("SIMCONNECT_SOUND_SYSTEM_EVENT_DATA") - .allowlist_type("SIMCONNECT_PICK_FLAGS") + for v in vars { + builder = builder.allowlist_var(v); + } - // ==================== STRUCTS ==================== - .allowlist_type("SIMCONNECT_RECV") - .allowlist_type("SIMCONNECT_RECV_EXCEPTION") - .allowlist_type("SIMCONNECT_RECV_OPEN") - .allowlist_type("SIMCONNECT_RECV_QUIT") - .allowlist_type("SIMCONNECT_RECV_EVENT") - .allowlist_type("SIMCONNECT_RECV_EVENT_FILENAME") - .allowlist_type("SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE") - .allowlist_type("SIMCONNECT_RECV_EVENT_FRAME") - .allowlist_type("SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED") - .allowlist_type("SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED") - .allowlist_type("SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED") - .allowlist_type("SIMCONNECT_RECV_EVENT_RACE_END") - .allowlist_type("SIMCONNECT_RECV_EVENT_RACE_LAP") - .allowlist_type("SIMCONNECT_RECV_SIMOBJECT_DATA") - .allowlist_type("SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE") - .allowlist_type("SIMCONNECT_RECV_CLIENT_DATA") - .allowlist_type("SIMCONNECT_RECV_WEATHER_OBSERVATION") - .allowlist_type("SIMCONNECT_RECV_CLOUD_STATE") - .allowlist_type("SIMCONNECT_RECV_ASSIGNED_OBJECT_ID") - .allowlist_type("SIMCONNECT_RECV_RESERVED_KEY") - .allowlist_type("SIMCONNECT_RECV_SYSTEM_STATE") - .allowlist_type("SIMCONNECT_RECV_CUSTOM_ACTION") - .allowlist_type("SIMCONNECT_RECV_EVENT_WEATHER_MODE") - .allowlist_type("SIMCONNECT_RECV_FACILITIES_LIST") - .allowlist_type("SIMCONNECT_DATA_FACILITY_AIRPORT") - .allowlist_type("SIMCONNECT_RECV_AIRPORT_LIST") - .allowlist_type("SIMCONNECT_DATA_FACILITY_WAYPOINT") - .allowlist_type("SIMCONNECT_RECV_WAYPOINT_LIST") - .allowlist_type("SIMCONNECT_DATA_FACILITY_NDB") - .allowlist_type("SIMCONNECT_RECV_NDB_LIST") - .allowlist_type("SIMCONNECT_DATA_FACILITY_VOR") - .allowlist_type("SIMCONNECT_RECV_VOR_LIST") - .allowlist_type("SIMCONNECT_RECV_PICK") - .allowlist_type("SIMCONNECT_RECV_EVENT_EX1") - .allowlist_type("SIMCONNECT_DATA_RACE_RESULT") - .allowlist_type("SIMCONNECT_RECV_FACILITY_DATA") - .allowlist_type("SIMCONNECT_RECV_FACILITY_DATA_END") - .allowlist_type("SIMCONNECT_ICAO") - .allowlist_type("SIMCONNECT_FACILITY_MINIMAL") - .allowlist_type("SIMCONNECT_RECV_FACILITY_MINIMAL_LIST") - .allowlist_type("SIMCONNECT_DATA_PBH") - .allowlist_type("SIMCONNECT_JETWAY_DATA") - .allowlist_type("SIMCONNECT_RECV_JETWAY_DATA") - .allowlist_type("SIMCONNECT_RECV_ACTION_CALLBACK") - .allowlist_type("SIMCONNECT_INPUT_EVENT_DESCRIPTOR") - .allowlist_type("SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS") - .allowlist_type("SIMCONNECT_RECV_GET_INPUT_EVENT") - .allowlist_type("SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT") - .allowlist_type("SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS") - .allowlist_type("SIMCONNECT_VERSION_BASE_TYPE") - .allowlist_type("SIMCONNECT_CONTROLLER_ITEM") - .allowlist_type("SIMCONNECT_RECV_CONTROLLERS_LIST") - .allowlist_type("SIMCONNECT_RECV_LIST_TEMPLATE") - .allowlist_type("SIMCONNECT_DATA_INITPOSITION") - .allowlist_type("SIMCONNECT_DATA_MARKERSTATE") - .allowlist_type("SIMCONNECT_DATA_WAYPOINT") - .allowlist_type("SIMCONNECT_DATA_LATLONALT") - .allowlist_type("SIMCONNECT_DATA_XYZ") + // ==================== TYPES / ENUMS ==================== + let types = [ + "HANDLE", + "SIMCONNECT_RECV_ID", + "SIMCONNECT_DATATYPE", + "SIMCONNECT_EXCEPTION", + "SIMCONNECT_SIMOBJECT_TYPE", + "SIMCONNECT_STATE", + "SIMCONNECT_PERIOD", + "SIMCONNECT_MISSION_END", + "SIMCONNECT_CLIENT_DATA_PERIOD", + "SIMCONNECT_TEXT_TYPE", + "SIMCONNECT_TEXT_RESULT", + "SIMCONNECT_WEATHER_MODE", + "SIMCONNECT_FACILITY_LIST_TYPE", + "SIMCONNECT_FACILITY_DATA_TYPE", + "SIMCONNECT_INPUT_EVENT_TYPE", + "SIMCONNECT_VOR_FLAGS", + "SIMCONNECT_WAYPOINT_FLAGS", + "SIMCONNECT_EVENT_FLAG", + "SIMCONNECT_DATA_REQUEST_FLAG", + "SIMCONNECT_DATA_SET_FLAG", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG", + "SIMCONNECT_CLIENT_DATA_SET_FLAG", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA", + "SIMCONNECT_SOUND_SYSTEM_EVENT_DATA", + "SIMCONNECT_PICK_FLAGS", + ]; - // ==================== FUNCTIONS ==================== - .allowlist_function("SimConnect_MapClientEventToSimEvent") - .allowlist_function("SimConnect_TransmitClientEvent") - .allowlist_function("SimConnect_SetSystemEventState") - .allowlist_function("SimConnect_AddClientEventToNotificationGroup") - .allowlist_function("SimConnect_RemoveClientEvent") - .allowlist_function("SimConnect_SetNotificationGroupPriority") - .allowlist_function("SimConnect_ClearNotificationGroup") - .allowlist_function("SimConnect_RequestNotificationGroup") - .allowlist_function("SimConnect_AddToDataDefinition") - .allowlist_function("SimConnect_ClearDataDefinition") - .allowlist_function("SimConnect_RequestDataOnSimObject") - .allowlist_function("SimConnect_RequestDataOnSimObjectType") - .allowlist_function("SimConnect_SetDataOnSimObject") - .allowlist_function("SimConnect_MapInputEventToClientEvent") - .allowlist_function("SimConnect_SetInputGroupPriority") - .allowlist_function("SimConnect_RemoveInputEvent") - .allowlist_function("SimConnect_ClearInputGroup") - .allowlist_function("SimConnect_SetInputGroupState") - .allowlist_function("SimConnect_RequestReservedKey") - .allowlist_function("SimConnect_SubscribeToSystemEvent") - .allowlist_function("SimConnect_UnsubscribeFromSystemEvent") - .allowlist_function("SimConnect_WeatherRequestInterpolatedObservation") - .allowlist_function("SimConnect_WeatherRequestObservationAtStation") - .allowlist_function("SimConnect_WeatherRequestObservationAtNearestStation") - .allowlist_function("SimConnect_WeatherCreateStation") - .allowlist_function("SimConnect_WeatherRemoveStation") - .allowlist_function("SimConnect_WeatherSetObservation") - .allowlist_function("SimConnect_WeatherSetModeServer") - .allowlist_function("SimConnect_WeatherSetModeTheme") - .allowlist_function("SimConnect_WeatherSetModeGlobal") - .allowlist_function("SimConnect_WeatherSetModeCustom") - .allowlist_function("SimConnect_WeatherSetDynamicUpdateRate") - .allowlist_function("SimConnect_WeatherRequestCloudState") - .allowlist_function("SimConnect_WeatherCreateThermal") - .allowlist_function("SimConnect_WeatherRemoveThermal") - .allowlist_function("SimConnect_AICreateParkedATCAircraft") - .allowlist_function("SimConnect_AICreateEnrouteATCAircraft") - .allowlist_function("SimConnect_AICreateNonATCAircraft") - .allowlist_function("SimConnect_AICreateSimulatedObject") - .allowlist_function("SimConnect_AIReleaseControl") - .allowlist_function("SimConnect_AIRemoveObject") - .allowlist_function("SimConnect_AISetAircraftFlightPlan") - .allowlist_function("SimConnect_ExecuteMissionAction") - .allowlist_function("SimConnect_CompleteCustomMissionAction") - .allowlist_function("SimConnect_Close") - .allowlist_function("SimConnect_RetrieveString") - .allowlist_function("SimConnect_GetLastSentPacketID") - .allowlist_function("SimConnect_Open") - .allowlist_function("SimConnect_CallDispatch") - .allowlist_function("SimConnect_GetNextDispatch") - .allowlist_function("SimConnect_RequestResponseTimes") - .allowlist_function("SimConnect_InsertString") - .allowlist_function("SimConnect_CameraSetRelative6DOF") - .allowlist_function("SimConnect_MenuAddItem") - .allowlist_function("SimConnect_MenuDeleteItem") - .allowlist_function("SimConnect_MenuAddSubItem") - .allowlist_function("SimConnect_MenuDeleteSubItem") - .allowlist_function("SimConnect_RequestSystemState") - .allowlist_function("SimConnect_SetSystemState") - .allowlist_function("SimConnect_MapClientDataNameToID") - .allowlist_function("SimConnect_CreateClientData") - .allowlist_function("SimConnect_AddToClientDataDefinition") - .allowlist_function("SimConnect_ClearClientDataDefinition") - .allowlist_function("SimConnect_RequestClientData") - .allowlist_function("SimConnect_SetClientData") - .allowlist_function("SimConnect_FlightLoad") - .allowlist_function("SimConnect_FlightSave") - .allowlist_function("SimConnect_FlightPlanLoad") - .allowlist_function("SimConnect_Text") - .allowlist_function("SimConnect_SubscribeToFacilities") - .allowlist_function("SimConnect_UnsubscribeToFacilities") - .allowlist_function("SimConnect_RequestFacilitiesList") - .allowlist_function("SimConnect_TransmitClientEvent_EX1") - .allowlist_function("SimConnect_AddToFacilityDefinition") - .allowlist_function("SimConnect_RequestFacilityData") - .allowlist_function("SimConnect_SubscribeToFacilities_EX1") - .allowlist_function("SimConnect_UnsubscribeToFacilities_EX1") - .allowlist_function("SimConnect_RequestFacilitiesList_EX1") - .allowlist_function("SimConnect_RequestFacilityData_EX1") - .allowlist_function("SimConnect_RequestJetwayData") - .allowlist_function("SimConnect_EnumerateControllers") - .allowlist_function("SimConnect_MapInputEventToClientEvent_EX1") - .allowlist_function("SimConnect_ExecuteAction") - .allowlist_function("SimConnect_EnumerateInputEvents") - .allowlist_function("SimConnect_GetInputEvent") - .allowlist_function("SimConnect_SetInputEvent") - .allowlist_function("SimConnect_SubscribeInputEvent") - .allowlist_function("SimConnect_UnsubscribeInputEvent") - .allowlist_function("SimConnect_EnumerateInputEventParams") - .allowlist_function("SimConnect_AddFacilityDataDefinitionFilter") - .allowlist_function("SimConnect_ClearAllFacilityDataDefinitionFilters") + for t in types { + builder = builder.allowlist_type(t); + } - .impl_debug(true) - .generate() - .expect("Unable to generate bindings"); + // ==================== STRUCTS ==================== + let structs = [ + "SIMCONNECT_RECV", + "SIMCONNECT_RECV_EXCEPTION", + "SIMCONNECT_RECV_OPEN", + "SIMCONNECT_RECV_QUIT", + "SIMCONNECT_RECV_EVENT", + "SIMCONNECT_RECV_EVENT_FILENAME", + "SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE", + "SIMCONNECT_RECV_EVENT_FRAME", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED", + "SIMCONNECT_RECV_EVENT_RACE_END", + "SIMCONNECT_RECV_EVENT_RACE_LAP", + "SIMCONNECT_RECV_SIMOBJECT_DATA", + "SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE", + "SIMCONNECT_RECV_CLIENT_DATA", + "SIMCONNECT_RECV_WEATHER_OBSERVATION", + "SIMCONNECT_RECV_CLOUD_STATE", + "SIMCONNECT_RECV_ASSIGNED_OBJECT_ID", + "SIMCONNECT_RECV_RESERVED_KEY", + "SIMCONNECT_RECV_SYSTEM_STATE", + "SIMCONNECT_RECV_CUSTOM_ACTION", + "SIMCONNECT_RECV_EVENT_WEATHER_MODE", + "SIMCONNECT_RECV_FACILITIES_LIST", + "SIMCONNECT_DATA_FACILITY_AIRPORT", + "SIMCONNECT_RECV_AIRPORT_LIST", + "SIMCONNECT_DATA_FACILITY_WAYPOINT", + "SIMCONNECT_RECV_WAYPOINT_LIST", + "SIMCONNECT_DATA_FACILITY_NDB", + "SIMCONNECT_RECV_NDB_LIST", + "SIMCONNECT_DATA_FACILITY_VOR", + "SIMCONNECT_RECV_VOR_LIST", + "SIMCONNECT_RECV_EVENT_EX1", + "SIMCONNECT_DATA_RACE_RESULT", + "SIMCONNECT_RECV_FACILITY_DATA", + "SIMCONNECT_RECV_FACILITY_DATA_END", + "SIMCONNECT_ICAO", + "SIMCONNECT_FACILITY_MINIMAL", + "SIMCONNECT_RECV_FACILITY_MINIMAL_LIST", + "SIMCONNECT_DATA_PBH", + "SIMCONNECT_JETWAY_DATA", + "SIMCONNECT_RECV_JETWAY_DATA", + "SIMCONNECT_RECV_ACTION_CALLBACK", + "SIMCONNECT_INPUT_EVENT_DESCRIPTOR", + "SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS", + "SIMCONNECT_RECV_GET_INPUT_EVENT", + "SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT", + "SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS", + "SIMCONNECT_VERSION_BASE_TYPE", + "SIMCONNECT_CONTROLLER_ITEM", + "SIMCONNECT_RECV_CONTROLLERS_LIST", + "SIMCONNECT_RECV_LIST_TEMPLATE", + "SIMCONNECT_DATA_INITPOSITION", + "SIMCONNECT_DATA_MARKERSTATE", + "SIMCONNECT_DATA_WAYPOINT", + "SIMCONNECT_DATA_LATLONALT", + "SIMCONNECT_DATA_XYZ", + "SIMCONNECT_RECV_PICK", + ]; - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("bindings.rs")) - .expect("Couldn't write bindings!"); -} + for s in structs { + builder = builder.allowlist_type(s); + } + + // ==================== FUNCTIONS ==================== + let functions = [ + "SimConnect_MapClientEventToSimEvent", + "SimConnect_TransmitClientEvent", + "SimConnect_SetSystemEventState", + "SimConnect_AddClientEventToNotificationGroup", + "SimConnect_RemoveClientEvent", + "SimConnect_SetNotificationGroupPriority", + "SimConnect_ClearNotificationGroup", + "SimConnect_RequestNotificationGroup", + "SimConnect_AddToDataDefinition", + "SimConnect_ClearDataDefinition", + "SimConnect_RequestDataOnSimObject", + "SimConnect_RequestDataOnSimObjectType", + "SimConnect_SetDataOnSimObject", + "SimConnect_MapInputEventToClientEvent", + "SimConnect_SetInputGroupPriority", + "SimConnect_RemoveInputEvent", + "SimConnect_ClearInputGroup", + "SimConnect_SetInputGroupState", + "SimConnect_RequestReservedKey", + "SimConnect_SubscribeToSystemEvent", + "SimConnect_UnsubscribeFromSystemEvent", + "SimConnect_WeatherRequestInterpolatedObservation", + "SimConnect_WeatherRequestObservationAtStation", + "SimConnect_WeatherRequestObservationAtNearestStation", + "SimConnect_WeatherCreateStation", + "SimConnect_WeatherRemoveStation", + "SimConnect_WeatherSetObservation", + "SimConnect_WeatherSetModeServer", + "SimConnect_WeatherSetModeTheme", + "SimConnect_WeatherSetModeGlobal", + "SimConnect_WeatherSetModeCustom", + "SimConnect_WeatherSetDynamicUpdateRate", + "SimConnect_WeatherRequestCloudState", + "SimConnect_WeatherCreateThermal", + "SimConnect_WeatherRemoveThermal", + "SimConnect_AICreateParkedATCAircraft", + "SimConnect_AICreateEnrouteATCAircraft", + "SimConnect_AICreateNonATCAircraft", + "SimConnect_AICreateSimulatedObject", + "SimConnect_AIReleaseControl", + "SimConnect_AIRemoveObject", + "SimConnect_AISetAircraftFlightPlan", + "SimConnect_ExecuteMissionAction", + "SimConnect_CompleteCustomMissionAction", + "SimConnect_Close", + "SimConnect_RetrieveString", + "SimConnect_GetLastSentPacketID", + "SimConnect_Open", + "SimConnect_CallDispatch", + "SimConnect_GetNextDispatch", + "SimConnect_RequestResponseTimes", + "SimConnect_InsertString", + "SimConnect_CameraSetRelative6DOF", + "SimConnect_MenuAddItem", + "SimConnect_MenuDeleteItem", + "SimConnect_MenuAddSubItem", + "SimConnect_MenuDeleteSubItem", + "SimConnect_RequestSystemState", + "SimConnect_SetSystemState", + "SimConnect_MapClientDataNameToID", + "SimConnect_CreateClientData", + "SimConnect_AddToClientDataDefinition", + "SimConnect_ClearClientDataDefinition", + "SimConnect_RequestClientData", + "SimConnect_SetClientData", + "SimConnect_FlightLoad", + "SimConnect_FlightSave", + "SimConnect_FlightPlanLoad", + "SimConnect_Text", + "SimConnect_SubscribeToFacilities", + "SimConnect_UnsubscribeToFacilities", + "SimConnect_RequestFacilitiesList", + "SimConnect_TransmitClientEvent_EX1", + "SimConnect_AddToFacilityDefinition", + "SimConnect_RequestFacilityData", + "SimConnect_SubscribeToFacilities_EX1", + "SimConnect_UnsubscribeToFacilities_EX1", + "SimConnect_RequestFacilitiesList_EX1", + "SimConnect_RequestFacilityData_EX1", + "SimConnect_RequestJetwayData", + "SimConnect_EnumerateControllers", + "SimConnect_MapInputEventToClientEvent_EX1", + "SimConnect_ExecuteAction", + "SimConnect_EnumerateInputEvents", + "SimConnect_GetInputEvent", + "SimConnect_SetInputEvent", + "SimConnect_SubscribeInputEvent", + "SimConnect_UnsubscribeInputEvent", + "SimConnect_EnumerateInputEventParams", + "SimConnect_AddFacilityDataDefinitionFilter", + "SimConnect_ClearAllFacilityDataDefinitionFilters", + ]; + + for f in functions { + builder = builder.allowlist_function(f); + } + + let bindings = builder + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); + }) + .expect("Failed to spawn bindgen thread"); + + handle.join().expect("Bindgen thread panicked"); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 9a47fe7..1cc9599 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,12 +4,10 @@ #![allow(non_snake_case)] use std::ffi::CString; -use std::mem::transmute_copy; use std::ptr; include!(concat!(env!("OUT_DIR"), "/bindings.rs")); -/// Enumerations for all the possible data types received from SimConnect #[derive(Debug)] pub enum DispatchResult<'a> { Null, @@ -52,17 +50,14 @@ pub enum DispatchResult<'a> { ControllersList(&'a SIMCONNECT_RECV_CONTROLLERS_LIST), } -/// Handles communication between the client program and SimConnect #[derive(Debug)] pub struct SimConnector { - sim_connect_handle: HANDLE, + handle: HANDLE, } impl Default for SimConnector { fn default() -> Self { - Self { - sim_connect_handle: std::ptr::null_mut(), - } + Self { handle: ptr::null_mut() } } } @@ -71,44 +66,52 @@ impl SimConnector { Self::default() } - pub fn connect(&mut self, program_name: &str) -> bool { - unsafe { - let temp_1 = ptr::null_mut(); - let temp_2 = ptr::null_mut(); + // ==================== Connection & Lifecycle ==================== - let program_name = CString::new(program_name).unwrap(); + pub fn connect(&mut self, program_name: &str) -> bool { + let name = cstring(program_name); + unsafe { SimConnect_Open( - &mut self.sim_connect_handle, - program_name.as_ptr(), - temp_1, + &mut self.handle, + name.as_ptr(), + ptr::null_mut(), 0, - temp_2, + ptr::null_mut(), 0, - ); + ) == 0 + } + } - !self.sim_connect_handle.is_null() + pub fn close(&mut self) -> bool { + if self.handle.is_null() { + return true; } + let result = unsafe { SimConnect_Close(self.handle) == 0 }; + self.handle = ptr::null_mut(); + result } + // ==================== Data Definition ==================== + pub fn add_data_definition( &self, define_id: SIMCONNECT_DATA_DEFINITION_ID, datum_name: &str, units_name: &str, datum_type: SIMCONNECT_DATATYPE, - datum_id: DWORD, epsilon: f32, + datum_id: DWORD, ) -> bool { - let datum_name = CString::new(datum_name).unwrap(); - let units_name = CString::new(units_name).unwrap(); + let name = cstring(datum_name); + let units = cstring(units_name); unsafe { SimConnect_AddToDataDefinition( - self.sim_connect_handle, + self.handle, define_id, - datum_name.as_ptr(), - units_name.as_ptr(), + name.as_ptr(), + units.as_ptr(), datum_type, epsilon, datum_id, @@ -116,327 +119,309 @@ impl SimConnector { } } - pub fn set_system_event_state( - &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - state: SIMCONNECT_STATE, - ) -> bool { - unsafe { SimConnect_SetSystemEventState(self.sim_connect_handle, event_id, state) == 0 } + pub fn clear_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { + unsafe { SimConnect_ClearDataDefinition(self.handle, define_id) == 0 } } - pub fn remove_client_event( + // ==================== Events ==================== + + pub fn map_client_event_to_sim_event( &self, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, event_id: SIMCONNECT_CLIENT_EVENT_ID, + event_name: &str, ) -> bool { - unsafe { SimConnect_RemoveClientEvent(self.sim_connect_handle, group_id, event_id) == 0 } - } - - pub fn clear_notification_group(&self, group_id: SIMCONNECT_NOTIFICATION_GROUP_ID) -> bool { - unsafe { SimConnect_ClearNotificationGroup(self.sim_connect_handle, group_id) == 0 } + let name = cstring(event_name); + unsafe { SimConnect_MapClientEventToSimEvent(self.handle, event_id, name.as_ptr()) == 0 } } - pub fn request_notification_group( + pub fn subscribe_to_system_event( &self, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - reserved: DWORD, - flags: DWORD, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + event_name: &str, ) -> bool { + let name = cstring(event_name); unsafe { - SimConnect_RequestNotificationGroup(self.sim_connect_handle, group_id, reserved, flags) - == 0 + SimConnect_SubscribeToSystemEvent(self.handle, event_id, name.as_ptr()) == 0 } } - pub fn clear_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { - unsafe { SimConnect_ClearDataDefinition(self.sim_connect_handle, define_id) == 0 } + pub fn unsubscribe_from_system_event(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { + unsafe { SimConnect_UnsubscribeFromSystemEvent(self.handle, event_id) == 0 } } - pub fn create_client_data( + pub fn set_system_event_state( &self, - data_id: SIMCONNECT_CLIENT_DATA_ID, - size: DWORD, - flags: SIMCONNECT_CREATE_CLIENT_DATA_FLAG, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + state: SIMCONNECT_STATE, ) -> bool { - unsafe { SimConnect_CreateClientData(self.sim_connect_handle, data_id, size, flags) == 0 } + unsafe { SimConnect_SetSystemEventState(self.handle, event_id, state) == 0 } } - pub fn request_data_on_sim_object_type( + pub fn transmit_client_event( &self, - request_id: SIMCONNECT_DATA_REQUEST_ID, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - radius_in_meters: DWORD, - object_type: SIMCONNECT_SIMOBJECT_TYPE, + object_id: SIMCONNECT_OBJECT_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + dw_data: DWORD, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + flags: SIMCONNECT_EVENT_FLAG, ) -> bool { unsafe { - SimConnect_RequestDataOnSimObjectType( - self.sim_connect_handle, - request_id, - define_id, - radius_in_meters, - object_type, + SimConnect_TransmitClientEvent( + self.handle, + object_id, + event_id, + dw_data, + group_id, + flags, ) == 0 } } - pub fn remove_input_event( + pub fn add_client_event_to_notification_group( &self, - group_id: SIMCONNECT_INPUT_GROUP_ID, - input_definition: &str, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + maskable: bool, ) -> bool { - let input_definition = CString::new(input_definition).unwrap(); - unsafe { - SimConnect_RemoveInputEvent( - self.sim_connect_handle, + SimConnect_AddClientEventToNotificationGroup( + self.handle, group_id, - input_definition.as_ptr(), + event_id, + maskable as i32, ) == 0 } } - pub fn clear_input_group(&self, group_id: SIMCONNECT_INPUT_GROUP_ID) -> bool { - unsafe { SimConnect_ClearInputGroup(self.sim_connect_handle, group_id) == 0 } - } - - pub fn request_reserved_key( + pub fn set_notification_group_priority( &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - key_choice_1: &str, - key_choice_2: &str, - key_choice_3: &str, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + priority: DWORD, ) -> bool { - let key_choice_1 = CString::new(key_choice_1).unwrap(); - let key_choice_2 = CString::new(key_choice_2).unwrap(); - let key_choice_3 = CString::new(key_choice_3).unwrap(); - unsafe { - SimConnect_RequestReservedKey( - self.sim_connect_handle, - event_id, - key_choice_1.as_ptr(), - key_choice_2.as_ptr(), - key_choice_3.as_ptr(), - ) == 0 + SimConnect_SetNotificationGroupPriority(self.handle, group_id, priority) == 0 } } - pub fn unsubscribe_from_system_event(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { - unsafe { SimConnect_UnsubscribeFromSystemEvent(self.sim_connect_handle, event_id) == 0 } - } - - pub fn ai_create_parked_atc_aircraft( + pub fn remove_client_event( &self, - container_title: &str, - tail_number: &str, - airport_id: &str, - request_id: SIMCONNECT_DATA_REQUEST_ID, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, ) -> bool { - let container_title = CString::new(container_title).unwrap(); - let tail_number = CString::new(tail_number).unwrap(); - let airport_id = CString::new(airport_id).unwrap(); + unsafe { SimConnect_RemoveClientEvent(self.handle, group_id, event_id) == 0 } + } - unsafe { - SimConnect_AICreateParkedATCAircraft( - self.sim_connect_handle, - container_title.as_ptr(), - tail_number.as_ptr(), - airport_id.as_ptr(), - request_id, - ) == 0 - } + pub fn clear_notification_group(&self, group_id: SIMCONNECT_NOTIFICATION_GROUP_ID) -> bool { + unsafe { SimConnect_ClearNotificationGroup(self.handle, group_id) == 0 } } - pub fn ai_create_enroute_atc_aircraft( + pub fn request_notification_group( &self, - container_title: &str, - tail_number: &str, - flight_number: i32, - flight_plan_path: &str, - flight_plan_position: f64, - touch_and_go: bool, - request_id: SIMCONNECT_DATA_REQUEST_ID, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + reserved: DWORD, + flags: DWORD, ) -> bool { - let container_title = CString::new(container_title).unwrap(); - let tail_number = CString::new(tail_number).unwrap(); - let flight_plan_path = CString::new(flight_plan_path).unwrap(); - unsafe { - SimConnect_AICreateEnrouteATCAircraft( - self.sim_connect_handle, - container_title.as_ptr(), - tail_number.as_ptr(), - flight_number, - flight_plan_path.as_ptr(), - flight_plan_position, - touch_and_go as i32, - request_id, - ) == 0 + SimConnect_RequestNotificationGroup(self.handle, group_id, reserved, flags) == 0 } } - pub fn ai_create_non_atc_aircraft( + pub fn transmit_client_event_ex1( &self, - container_title: &str, - tail_number: &str, - init_pos: SIMCONNECT_DATA_INITPOSITION, - request_id: SIMCONNECT_DATA_REQUEST_ID, + object_id: SIMCONNECT_OBJECT_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + flags: SIMCONNECT_EVENT_FLAG, + data0: DWORD, + data1: DWORD, + data2: DWORD, + data3: DWORD, + data4: DWORD, ) -> bool { - let container_title = CString::new(container_title).unwrap(); - let tail_number = CString::new(tail_number).unwrap(); - unsafe { - SimConnect_AICreateNonATCAircraft( - self.sim_connect_handle, - container_title.as_ptr(), - tail_number.as_ptr(), - init_pos, - request_id, + SimConnect_TransmitClientEvent_EX1( + self.handle, + object_id, + event_id, + group_id, + flags, + data0, + data1, + data2, + data3, + data4, ) == 0 } } - pub fn ai_create_simulated_object( + pub fn request_reserved_key( &self, - container_title: &str, - init_pos: SIMCONNECT_DATA_INITPOSITION, - request_id: SIMCONNECT_DATA_REQUEST_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + key_choice1: &str, + key_choice2: &str, + key_choice3: &str, ) -> bool { - let container_title = CString::new(container_title).unwrap(); + let k1 = cstring(key_choice1); + let k2 = cstring(key_choice2); + let k3 = cstring(key_choice3); unsafe { - SimConnect_AICreateSimulatedObject( - self.sim_connect_handle, - container_title.as_ptr(), - init_pos, - request_id, + SimConnect_RequestReservedKey( + self.handle, + event_id, + k1.as_ptr(), + k2.as_ptr(), + k3.as_ptr(), ) == 0 } } - pub fn ai_release_control( - &self, - object_id: SIMCONNECT_OBJECT_ID, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - unsafe { SimConnect_AIReleaseControl(self.sim_connect_handle, object_id, request_id) == 0 } - } + // ==================== Input Events ==================== - pub fn ai_remove_object( + pub fn map_input_event_to_client_event( &self, - object_id: SIMCONNECT_OBJECT_ID, - request_id: SIMCONNECT_DATA_REQUEST_ID, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, + down_event: SIMCONNECT_CLIENT_EVENT_ID, + down_return_value: DWORD, + up_event: SIMCONNECT_CLIENT_EVENT_ID, + up_return_value: DWORD, + maskable: bool, ) -> bool { - unsafe { SimConnect_AIRemoveObject(self.sim_connect_handle, object_id, request_id) == 0 } + let input = cstring(input_definition); + unsafe { + SimConnect_MapInputEventToClientEvent( + self.handle, + group_id, + input.as_ptr(), + down_event, + down_return_value, + up_event, + up_return_value, + maskable as i32, + ) == 0 + } } - pub fn ai_set_aircraft_flight_plan( + pub fn map_input_event_to_client_event_ex1( &self, - object_id: SIMCONNECT_OBJECT_ID, - flight_plan_path: &str, - request_id: SIMCONNECT_DATA_REQUEST_ID, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, + down_event: SIMCONNECT_CLIENT_EVENT_ID, + down_return_value: DWORD, + up_event: SIMCONNECT_CLIENT_EVENT_ID, + up_return_value: DWORD, + maskable: bool, ) -> bool { - let flight_plan_path = CString::new(flight_plan_path).unwrap(); - + let input = cstring(input_definition); unsafe { - SimConnect_AISetAircraftFlightPlan( - self.sim_connect_handle, - object_id, - flight_plan_path.as_ptr(), - request_id, + SimConnect_MapInputEventToClientEvent_EX1( + self.handle, + group_id, + input.as_ptr(), + down_event, + down_return_value, + up_event, + up_return_value, + maskable as i32, ) == 0 } } - pub fn execute_mission_action(&self, instance_id: GUID) -> bool { - unsafe { SimConnect_ExecuteMissionAction(self.sim_connect_handle, instance_id) == 0 } - } - - pub fn complete_custom_mission_action(&self, instance_id: GUID) -> bool { - unsafe { SimConnect_CompleteCustomMissionAction(self.sim_connect_handle, instance_id) == 0 } - } - - pub fn close(&self) -> bool { - unsafe { SimConnect_Close(self.sim_connect_handle) == 0 } + pub fn set_input_group_state(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, state: DWORD) -> bool { + unsafe { SimConnect_SetInputGroupState(self.handle, group_id, state) == 0 } } - pub unsafe fn get_last_sent_packet_id(&self, error: *mut DWORD) -> bool { - unsafe { SimConnect_GetLastSentPacketID(self.sim_connect_handle, error) == 0 } + pub fn set_input_priority(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, priority: DWORD) -> bool { + unsafe { SimConnect_SetInputGroupPriority(self.handle, group_id, priority) == 0 } } - pub unsafe fn call_dispatch( + pub fn remove_input_event( &self, - dispatch_callback: DispatchProc, - context: *mut std::os::raw::c_void, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, ) -> bool { - unsafe { SimConnect_CallDispatch(self.sim_connect_handle, dispatch_callback, context) == 0 } - } - - pub unsafe fn request_response_times(&self, count: DWORD, elapsed_seconds: *mut f32) -> bool { + let input = cstring(input_definition); unsafe { - SimConnect_RequestResponseTimes(self.sim_connect_handle, count, elapsed_seconds) == 0 + SimConnect_RemoveInputEvent(self.handle, group_id, input.as_ptr()) == 0 } } - pub fn camera_set_relative_6dof( + pub fn clear_input_group(&self, group_id: SIMCONNECT_INPUT_GROUP_ID) -> bool { + unsafe { SimConnect_ClearInputGroup(self.handle, group_id) == 0 } + } + + // ==================== Data Requests ==================== + + pub fn request_data_on_sim_object( &self, - delta_x: f32, - delta_y: f32, - delta_z: f32, - pitch: f32, - bank: f32, - heading: f32, + request_id: SIMCONNECT_DATA_REQUEST_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + object_id: SIMCONNECT_OBJECT_ID, + period: SIMCONNECT_PERIOD, + flags: SIMCONNECT_DATA_REQUEST_FLAG, + origin: DWORD, + interval: DWORD, + limit: DWORD, ) -> bool { unsafe { - SimConnect_CameraSetRelative6DOF( - self.sim_connect_handle, - delta_x, - delta_y, - delta_z, - pitch, - bank, - heading, + SimConnect_RequestDataOnSimObject( + self.handle, + request_id, + define_id, + object_id, + period, + flags, + origin, + interval, + limit, ) == 0 } } - pub fn menu_add_item( + pub fn request_data_on_sim_object_type( &self, - menu_item: &str, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - data: DWORD, + request_id: SIMCONNECT_DATA_REQUEST_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + radius_in_meters: DWORD, + object_type: SIMCONNECT_SIMOBJECT_TYPE, ) -> bool { - let menu_item = CString::new(menu_item).unwrap(); - unsafe { - SimConnect_MenuAddItem(self.sim_connect_handle, menu_item.as_ptr(), event_id, data) == 0 + SimConnect_RequestDataOnSimObjectType( + self.handle, + request_id, + define_id, + radius_in_meters, + object_type, + ) == 0 } } - pub fn menu_delete_item(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { - unsafe { SimConnect_MenuDeleteItem(self.sim_connect_handle, event_id) == 0 } - } - - pub fn menu_delete_sub_item( + pub unsafe fn set_data_on_sim_object( &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - sub_event_id: SIMCONNECT_CLIENT_EVENT_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + object_id: SIMCONNECT_OBJECT_ID, + flags: SIMCONNECT_DATA_SET_FLAG, + array_count: DWORD, + size: DWORD, + pntr: *mut std::os::raw::c_void, ) -> bool { unsafe { - SimConnect_MenuDeleteSubItem(self.sim_connect_handle, event_id, sub_event_id) == 0 + SimConnect_SetDataOnSimObject( + self.handle, define_id, object_id, flags, array_count, size, pntr, + ) == 0 } } - pub fn request_system_state( + // ==================== Client Data ==================== + + pub fn create_client_data( &self, - request_id: SIMCONNECT_DATA_REQUEST_ID, - state: &str, + data_id: SIMCONNECT_CLIENT_DATA_ID, + size: DWORD, + flags: SIMCONNECT_CREATE_CLIENT_DATA_FLAG, ) -> bool { - let state = CString::new(state).unwrap(); - - unsafe { - SimConnect_RequestSystemState(self.sim_connect_handle, request_id, state.as_ptr()) == 0 - } + unsafe { SimConnect_CreateClientData(self.handle, data_id, size, flags) == 0 } } pub fn map_client_data_name_to_id( @@ -444,14 +429,9 @@ impl SimConnector { client_data_name: &str, data_id: SIMCONNECT_CLIENT_DATA_ID, ) -> bool { - let client_data_name = CString::new(client_data_name).unwrap(); - + let name = cstring(client_data_name); unsafe { - SimConnect_MapClientDataNameToID( - self.sim_connect_handle, - client_data_name.as_ptr(), - data_id, - ) == 0 + SimConnect_MapClientDataNameToID(self.handle, name.as_ptr(), data_id) == 0 } } @@ -465,18 +445,13 @@ impl SimConnector { ) -> bool { unsafe { SimConnect_AddToClientDataDefinition( - self.sim_connect_handle, - define_id, - offset, - size_or_type, - epsilon, - datum_id, + self.handle, define_id, offset, size_or_type, epsilon, datum_id, ) == 0 } } pub fn clear_client_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { - unsafe { SimConnect_ClearClientDataDefinition(self.sim_connect_handle, define_id) == 0 } + unsafe { SimConnect_ClearClientDataDefinition(self.handle, define_id) == 0 } } pub fn request_client_data( @@ -492,7 +467,7 @@ impl SimConnector { ) -> bool { unsafe { SimConnect_RequestClientData( - self.sim_connect_handle, + self.handle, data_id, request_id, define_id, @@ -516,273 +491,352 @@ impl SimConnector { ) -> bool { unsafe { SimConnect_SetClientData( - self.sim_connect_handle, - data_id, - define_id, - flags, - reserved, - unit_size, - data_set, + self.handle, data_id, define_id, flags, reserved, unit_size, data_set, ) == 0 } } - pub fn flight_load(&self, file_name: &str) -> bool { - let file_name = CString::new(file_name).unwrap(); + // ==================== AI Objects ==================== - unsafe { SimConnect_FlightLoad(self.sim_connect_handle, file_name.as_ptr()) == 0 } - } - - pub unsafe fn text( + pub fn ai_create_parked_atc_aircraft( &self, - text_type: SIMCONNECT_TEXT_TYPE, - time_in_seconds: f32, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - unit_size: DWORD, - data_set: *mut std::os::raw::c_void, + container_title: &str, + tail_number: &str, + airport_id: &str, + request_id: SIMCONNECT_DATA_REQUEST_ID, ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + let airport = cstring(airport_id); + unsafe { - SimConnect_Text( - self.sim_connect_handle, - text_type, - time_in_seconds, - event_id, - unit_size, - data_set, + SimConnect_AICreateParkedATCAircraft( + self.handle, + title.as_ptr(), + tail.as_ptr(), + airport.as_ptr(), + request_id, ) == 0 } } - pub fn subscribe_to_facilities( + pub fn ai_create_enroute_atc_aircraft( &self, - list_type: SIMCONNECT_FACILITY_LIST_TYPE, + container_title: &str, + tail_number: &str, + flight_number: i32, + flight_plan_path: &str, + flight_plan_position: f64, + touch_and_go: bool, request_id: SIMCONNECT_DATA_REQUEST_ID, ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + let plan = cstring(flight_plan_path); + unsafe { - SimConnect_SubscribeToFacilities(self.sim_connect_handle, list_type, request_id) == 0 + SimConnect_AICreateEnrouteATCAircraft( + self.handle, + title.as_ptr(), + tail.as_ptr(), + flight_number, + plan.as_ptr(), + flight_plan_position, + touch_and_go as i32, + request_id, + ) == 0 } } - pub fn unsubscribe_to_facilities(&self, list_type: SIMCONNECT_FACILITY_LIST_TYPE) -> bool { - unsafe { SimConnect_UnsubscribeToFacilities(self.sim_connect_handle, list_type) == 0 } - } - - pub fn request_facilities_list( + pub fn ai_create_non_atc_aircraft( &self, - list_type: SIMCONNECT_FACILITY_LIST_TYPE, + container_title: &str, + tail_number: &str, + init_pos: SIMCONNECT_DATA_INITPOSITION, request_id: SIMCONNECT_DATA_REQUEST_ID, ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + unsafe { - SimConnect_RequestFacilitiesList(self.sim_connect_handle, list_type, request_id) == 0 + SimConnect_AICreateNonATCAircraft( + self.handle, title.as_ptr(), tail.as_ptr(), init_pos, request_id, + ) == 0 } } - pub fn request_data_on_sim_object( + pub fn ai_create_simulated_object( &self, + container_title: &str, + init_pos: SIMCONNECT_DATA_INITPOSITION, request_id: SIMCONNECT_DATA_REQUEST_ID, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - object_id: SIMCONNECT_OBJECT_ID, - period: SIMCONNECT_CLIENT_DATA_PERIOD, - flags: SIMCONNECT_DATA_REQUEST_FLAG, - origin: DWORD, - interval: DWORD, - limit: DWORD, ) -> bool { + let title = cstring(container_title); unsafe { - SimConnect_RequestDataOnSimObject( - self.sim_connect_handle, - request_id, - define_id, - object_id, - period, - flags, - origin, - interval, - limit, - ) == 0 + SimConnect_AICreateSimulatedObject(self.handle, title.as_ptr(), init_pos, request_id) == 0 } } - pub unsafe fn set_data_on_sim_object( + pub fn ai_release_control( &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, object_id: SIMCONNECT_OBJECT_ID, - flags: SIMCONNECT_DATA_SET_FLAG, - array_count: DWORD, - size: DWORD, - pntr: *mut ::std::os::raw::c_void, + request_id: SIMCONNECT_DATA_REQUEST_ID, ) -> bool { - unsafe { - SimConnect_SetDataOnSimObject( - self.sim_connect_handle, - define_id, - object_id, - flags, - array_count, - size, - pntr, - ) == 0 - } + unsafe { SimConnect_AIReleaseControl(self.handle, object_id, request_id) == 0 } } - pub fn subscribe_to_system_event( + pub fn ai_remove_object( &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - event_name: &str, + object_id: SIMCONNECT_OBJECT_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, ) -> bool { - let event_name = CString::new(event_name).unwrap(); - - unsafe { - SimConnect_SubscribeToSystemEvent( - self.sim_connect_handle, - event_id, - event_name.as_ptr(), - ) == 0 - } + unsafe { SimConnect_AIRemoveObject(self.handle, object_id, request_id) == 0 } } - pub fn map_client_event_to_sim_event( + pub fn ai_set_aircraft_flight_plan( &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - event_name: &str, + object_id: SIMCONNECT_OBJECT_ID, + flight_plan_path: &str, + request_id: SIMCONNECT_DATA_REQUEST_ID, ) -> bool { - let event_name = CString::new(event_name).unwrap(); - + let plan = cstring(flight_plan_path); unsafe { - SimConnect_MapClientEventToSimEvent( - self.sim_connect_handle, - event_id, - event_name.as_ptr(), + SimConnect_AISetAircraftFlightPlan( + self.handle, object_id, plan.as_ptr(), request_id, ) == 0 } } - pub fn transmit_client_event( + // ==================== Weather ==================== + + pub fn weather_request_interpolated_observation( &self, - object_id: SIMCONNECT_OBJECT_ID, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - dw_data: DWORD, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - flags: SIMCONNECT_EVENT_FLAG, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, + alt: f32, ) -> bool { unsafe { - SimConnect_TransmitClientEvent( - self.sim_connect_handle, - object_id, - event_id, - dw_data, - group_id, - flags, - ) == 0 + SimConnect_WeatherRequestInterpolatedObservation(self.handle, request_id, lat, lon, alt) == 0 } } - pub fn add_client_event_to_notification_group( + pub fn weather_request_observation_at_station( &self, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - maskable: bool, + request_id: SIMCONNECT_DATA_REQUEST_ID, + station: &str, ) -> bool { + let station = cstring(station); unsafe { - SimConnect_AddClientEventToNotificationGroup( - self.sim_connect_handle, - group_id, - event_id, - maskable as i32, - ) == 0 + SimConnect_WeatherRequestObservationAtStation(self.handle, request_id, station.as_ptr()) == 0 } } - pub fn set_notification_group_priority( + pub fn weather_request_observation_at_nearest_station( &self, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - priority: DWORD, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, ) -> bool { unsafe { - SimConnect_SetNotificationGroupPriority(self.sim_connect_handle, group_id, priority) - == 0 + SimConnect_WeatherRequestObservationAtNearestStation(self.handle, request_id, lat, lon) == 0 } } - pub fn map_input_event_to_client_event( + pub fn weather_create_station( &self, - group_id: SIMCONNECT_INPUT_GROUP_ID, - input_definition: &str, - down_event: SIMCONNECT_CLIENT_EVENT_ID, - down_return_value: DWORD, - up_event: SIMCONNECT_CLIENT_EVENT_ID, - up_return_value: DWORD, - maskable: bool, + request_id: SIMCONNECT_DATA_REQUEST_ID, + icao: &str, + name: &str, + lat: f32, + lon: f32, + alt: f32, ) -> bool { - let input_definition = CString::new(input_definition).unwrap(); + let icao_c = cstring(icao); + let name_c = cstring(name); unsafe { - SimConnect_MapInputEventToClientEvent( - self.sim_connect_handle, - group_id, - input_definition.as_ptr(), - down_event, - down_return_value, - up_event, - up_return_value, - maskable as i32, + SimConnect_WeatherCreateStation( + self.handle, + request_id, + icao_c.as_ptr(), + name_c.as_ptr(), + lat, + lon, + alt, ) == 0 } } - pub fn set_input_group_state(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, state: DWORD) -> bool { - unsafe { SimConnect_SetInputGroupState(self.sim_connect_handle, group_id, state) == 0 } + pub fn weather_remove_station(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, station: &str) -> bool { + let station = cstring(station); + unsafe { + SimConnect_WeatherRemoveStation(self.handle, request_id, station.as_ptr()) == 0 + } } - pub fn set_input_priority(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, priority: DWORD) -> bool { + pub fn weather_set_observation(&self, seconds: DWORD, observation: &str) -> bool { + let obs = cstring(observation); unsafe { - SimConnect_SetInputGroupPriority(self.sim_connect_handle, group_id, priority) == 0 + SimConnect_WeatherSetObservation(self.handle, seconds, obs.as_ptr()) == 0 } } - pub fn transmit_client_event_ex1( + pub fn weather_set_mode_server(&self, port: DWORD, seconds: DWORD) -> bool { + unsafe { SimConnect_WeatherSetModeServer(self.handle, port, seconds) == 0 } + } + + pub fn weather_set_mode_theme(&self, theme_name: &str) -> bool { + let theme = cstring(theme_name); + unsafe { SimConnect_WeatherSetModeTheme(self.handle, theme.as_ptr()) == 0 } + } + + pub fn weather_set_mode_global(&self) -> bool { + unsafe { SimConnect_WeatherSetModeGlobal(self.handle) == 0 } + } + + pub fn weather_set_mode_custom(&self) -> bool { + unsafe { SimConnect_WeatherSetModeCustom(self.handle) == 0 } + } + + pub fn weather_set_dynamic_update_rate(&self, rate: DWORD) -> bool { + unsafe { SimConnect_WeatherSetDynamicUpdateRate(self.handle, rate) == 0 } + } + + pub fn weather_request_cloud_state( &self, - object_id: SIMCONNECT_OBJECT_ID, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - flags: SIMCONNECT_EVENT_FLAG, - data0: DWORD, - data1: DWORD, - data2: DWORD, - data3: DWORD, - data4: DWORD, + request_id: SIMCONNECT_DATA_REQUEST_ID, + min_x: f32, + min_y: f32, + min_z: f32, + max_x: f32, + max_y: f32, + max_z: f32, + flags: DWORD, ) -> bool { unsafe { - SimConnect_TransmitClientEvent_EX1( - self.sim_connect_handle, - object_id, - event_id, - group_id, - flags, - data0, - data1, - data2, - data3, - data4, + SimConnect_WeatherRequestCloudState( + self.handle, request_id, min_x, min_y, min_z, max_x, max_y, max_z, flags, ) == 0 } } - pub fn add_to_facility_definition( + pub fn weather_create_thermal( &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - field_name: &str, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, + alt: f32, + radius: f32, + height: f32, + core_rate: f32, + core_turbulence: f32, + sink_rate: f32, + sink_turbulence: f32, + core_size: f32, + core_transition_size: f32, + sink_layer_size: f32, + sink_transition_size: f32, ) -> bool { - let field_name = CString::new(field_name).unwrap(); unsafe { - SimConnect_AddToFacilityDefinition( - self.sim_connect_handle, - define_id, - field_name.as_ptr(), + SimConnect_WeatherCreateThermal( + self.handle, + request_id, + lat, + lon, + alt, + radius, + height, + core_rate, + core_turbulence, + sink_rate, + sink_turbulence, + core_size, + core_transition_size, + sink_layer_size, + sink_transition_size, + ) == 0 + } + } + + pub fn weather_remove_thermal(&self, object_id: SIMCONNECT_OBJECT_ID) -> bool { + unsafe { SimConnect_WeatherRemoveThermal(self.handle, object_id) == 0 } + } + + // ==================== Mission & System ==================== + + pub fn execute_mission_action(&self, instance_id: GUID) -> bool { + unsafe { SimConnect_ExecuteMissionAction(self.handle, instance_id) == 0 } + } + + pub fn complete_custom_mission_action(&self, instance_id: GUID) -> bool { + unsafe { SimConnect_CompleteCustomMissionAction(self.handle, instance_id) == 0 } + } + + pub fn request_system_state(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, state: &str) -> bool { + let state = cstring(state); + unsafe { SimConnect_RequestSystemState(self.handle, request_id, state.as_ptr()) == 0 } + } + + pub fn set_system_state(&self, state: &str, integer: DWORD, float_val: f32, string_val: &str) -> bool { + let state_c = cstring(state); + let string_c = cstring(string_val); + + unsafe { + SimConnect_SetSystemState( + self.handle, + state_c.as_ptr(), + integer, + float_val, + string_c.as_ptr(), ) == 0 } } + pub fn flight_load(&self, file_name: &str) -> bool { + let name = cstring(file_name); + unsafe { SimConnect_FlightLoad(self.handle, name.as_ptr()) == 0 } + } + + pub fn flight_save(&self, file_name: &str, title: &str, description: &str, flags: DWORD) -> bool { + let name = cstring(file_name); + let t = cstring(title); + let d = cstring(description); + unsafe { SimConnect_FlightSave(self.handle, name.as_ptr(), t.as_ptr(), d.as_ptr(), flags) == 0 } + } + + pub fn flight_plan_load(&self, file_name: &str) -> bool { + let name = cstring(file_name); + unsafe { SimConnect_FlightPlanLoad(self.handle, name.as_ptr()) == 0 } + } + + // ==================== Facilities ==================== + + pub fn subscribe_to_facilities( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_SubscribeToFacilities(self.handle, list_type, request_id) == 0 } + } + + pub fn unsubscribe_to_facilities(&self, list_type: SIMCONNECT_FACILITY_LIST_TYPE) -> bool { + unsafe { SimConnect_UnsubscribeToFacilities(self.handle, list_type) == 0 } + } + + pub fn request_facilities_list( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_RequestFacilitiesList(self.handle, list_type, request_id) == 0 } + } + + pub fn add_to_facility_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID, field_name: &str) -> bool { + let field = cstring(field_name); + unsafe { SimConnect_AddToFacilityDefinition(self.handle, define_id, field.as_ptr()) == 0 } + } + pub fn request_facility_data( &self, define_id: SIMCONNECT_DATA_DEFINITION_ID, @@ -790,12 +844,11 @@ impl SimConnector { icao: &str, region: Option<&str>, ) -> bool { - let icao = CString::new(icao).unwrap(); - let region = region.map(|s| CString::new(s).unwrap()); - + let icao = cstring(icao); + let region = region.map(|s| cstring(s)); unsafe { SimConnect_RequestFacilityData( - self.sim_connect_handle, + self.handle, define_id, request_id, icao.as_ptr(), @@ -812,7 +865,7 @@ impl SimConnector { ) -> bool { unsafe { SimConnect_SubscribeToFacilities_EX1( - self.sim_connect_handle, + self.handle, list_type, new_in_range_request_id, old_out_of_range_request_id, @@ -828,7 +881,7 @@ impl SimConnector { ) -> bool { unsafe { SimConnect_UnsubscribeToFacilities_EX1( - self.sim_connect_handle, + self.handle, list_type, unsubscribe_new_in_range, unsubscribe_old_out_of_range, @@ -842,8 +895,7 @@ impl SimConnector { request_id: SIMCONNECT_DATA_REQUEST_ID, ) -> bool { unsafe { - SimConnect_RequestFacilitiesList_EX1(self.sim_connect_handle, list_type, request_id) - == 0 + SimConnect_RequestFacilitiesList_EX1(self.handle, list_type, request_id) == 0 } } @@ -855,12 +907,11 @@ impl SimConnector { region: Option<&str>, type_: Option, ) -> bool { - let icao = CString::new(icao).unwrap(); - let region = region.map(|s| CString::new(s).unwrap()); - + let icao = cstring(icao); + let region = region.map(|s| cstring(s)); unsafe { SimConnect_RequestFacilityData_EX1( - self.sim_connect_handle, + self.handle, define_id, request_id, icao.as_ptr(), @@ -876,72 +927,107 @@ impl SimConnector { array_count: DWORD, indexes: *mut i32, ) -> bool { - let airport_icao = CString::new(airport_icao).unwrap(); + let icao = cstring(airport_icao); unsafe { - SimConnect_RequestJetwayData( - self.sim_connect_handle, - airport_icao.as_ptr(), - array_count, - indexes, - ) == 0 + SimConnect_RequestJetwayData(self.handle, icao.as_ptr(), array_count, indexes) == 0 } } - pub fn enumerate_controllers(&self) -> bool { - unsafe { SimConnect_EnumerateControllers(self.sim_connect_handle) == 0 } + pub fn add_facility_data_definition_filter( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + filter_path: &str, + filter_data: *const std::os::raw::c_void, + cb_unit_size: DWORD, + ) -> bool { + let path = cstring(filter_path); + unsafe { + SimConnect_AddFacilityDataDefinitionFilter( + self.handle, + define_id, + path.as_ptr(), + cb_unit_size, + filter_data as *mut _, + ) == 0 + } } - pub fn map_input_event_to_client_event_ex1( + pub fn clear_all_facility_data_definition_filters( &self, - group_id: SIMCONNECT_INPUT_GROUP_ID, - input_definition: &str, - down_event: SIMCONNECT_CLIENT_EVENT_ID, - down_return_value: DWORD, - up_event: SIMCONNECT_CLIENT_EVENT_ID, - up_return_value: DWORD, - maskable: bool, + define_id: SIMCONNECT_DATA_DEFINITION_ID, ) -> bool { - let input_definition = CString::new(input_definition).unwrap(); + unsafe { + SimConnect_ClearAllFacilityDataDefinitionFilters(self.handle, define_id) == 0 + } + } + // ==================== Camera ==================== + + pub fn camera_set_relative_6dof( + &self, + delta_x: f32, + delta_y: f32, + delta_z: f32, + pitch: f32, + bank: f32, + heading: f32, + ) -> bool { unsafe { - SimConnect_MapInputEventToClientEvent_EX1( - self.sim_connect_handle, - group_id, - input_definition.as_ptr(), - down_event, - down_return_value, - up_event, - up_return_value, - maskable as i32, + SimConnect_CameraSetRelative6DOF( + self.handle, delta_x, delta_y, delta_z, pitch, bank, heading, ) == 0 } } - pub unsafe fn execute_action( + // ==================== Menu ==================== + + pub fn menu_add_item( &self, - request_id: DWORD, - action_id: &str, - unit_size: DWORD, - param_values: *mut std::os::raw::c_void, + menu_item: &str, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + data: DWORD, + ) -> bool { + let item = cstring(menu_item); + unsafe { SimConnect_MenuAddItem(self.handle, item.as_ptr(), event_id, data) == 0 } + } + + pub fn menu_add_sub_item( + &self, + menu_event_id: SIMCONNECT_CLIENT_EVENT_ID, + menu_item: &str, + sub_menu_event_id: SIMCONNECT_CLIENT_EVENT_ID, + data: DWORD, ) -> bool { - let action_id = CString::new(action_id).unwrap(); + let item = cstring(menu_item); unsafe { - SimConnect_ExecuteAction( - self.sim_connect_handle, - request_id, - action_id.as_ptr(), - unit_size, - param_values, - ) == 0 + SimConnect_MenuAddSubItem(self.handle, menu_event_id, item.as_ptr(), sub_menu_event_id, data) == 0 } } + pub fn menu_delete_item(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { + unsafe { SimConnect_MenuDeleteItem(self.handle, event_id) == 0 } + } + + pub fn menu_delete_sub_item( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + sub_event_id: SIMCONNECT_CLIENT_EVENT_ID, + ) -> bool { + unsafe { SimConnect_MenuDeleteSubItem(self.handle, event_id, sub_event_id) == 0 } + } + + // ==================== Other ==================== + + pub fn enumerate_controllers(&self) -> bool { + unsafe { SimConnect_EnumerateControllers(self.handle) == 0 } + } + pub fn enumerate_input_events(&self, request_id: SIMCONNECT_DATA_REQUEST_ID) -> bool { - unsafe { SimConnect_EnumerateInputEvents(self.sim_connect_handle, request_id) == 0 } + unsafe { SimConnect_EnumerateInputEvents(self.handle, request_id) == 0 } } pub fn get_input_event(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, hash: u64) -> bool { - unsafe { SimConnect_GetInputEvent(self.sim_connect_handle, request_id, hash) == 0 } + unsafe { SimConnect_GetInputEvent(self.handle, request_id, hash) == 0 } } pub unsafe fn set_input_event( @@ -950,247 +1036,143 @@ impl SimConnector { unit_size: DWORD, value: *mut std::os::raw::c_void, ) -> bool { - unsafe { SimConnect_SetInputEvent(self.sim_connect_handle, hash, unit_size, value) == 0 } + unsafe { SimConnect_SetInputEvent(self.handle, hash, unit_size, value) == 0 } } pub fn subscribe_input_event(&self, hash: u64) -> bool { - unsafe { SimConnect_SubscribeInputEvent(self.sim_connect_handle, hash) == 0 } + unsafe { SimConnect_SubscribeInputEvent(self.handle, hash) == 0 } } pub fn unsubscribe_input_event(&self, hash: u64) -> bool { - unsafe { SimConnect_UnsubscribeInputEvent(self.sim_connect_handle, hash) == 0 } + unsafe { SimConnect_UnsubscribeInputEvent(self.handle, hash) == 0 } } pub fn enumerate_input_event_params(&self, hash: u64) -> bool { - unsafe { SimConnect_EnumerateInputEventParams(self.sim_connect_handle, hash) == 0 } + unsafe { SimConnect_EnumerateInputEventParams(self.handle, hash) == 0 } } - pub fn add_facility_data_definition_filter( + pub unsafe fn execute_action( &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - filter_path: &str, - filter_data: *const std::os::raw::c_void, - cb_unit_size: DWORD, + request_id: DWORD, + action_id: &str, + unit_size: DWORD, + param_values: *mut std::os::raw::c_void, ) -> bool { - let filter_path = CString::new(filter_path).unwrap(); + let action = cstring(action_id); unsafe { - SimConnect_AddFacilityDataDefinitionFilter( - self.sim_connect_handle, - define_id, - filter_path.as_ptr(), - cb_unit_size, - filter_data as *mut _, - ) == 0 + SimConnect_ExecuteAction(self.handle, request_id, action.as_ptr(), unit_size, param_values) == 0 } } - pub fn clear_all_facility_data_definition_filters( + pub unsafe fn text( &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, + text_type: SIMCONNECT_TEXT_TYPE, + time_in_seconds: f32, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + unit_size: DWORD, + data_set: *mut std::os::raw::c_void, ) -> bool { unsafe { - SimConnect_ClearAllFacilityDataDefinitionFilters(self.sim_connect_handle, define_id) - == 0 + SimConnect_Text(self.handle, text_type, time_in_seconds, event_id, unit_size, data_set) == 0 } } - /// Retrieves the next message from SimConnect. Nonblocking. - pub fn get_next_message(&self) -> Result, &str> { - let mut data_buf: *mut SIMCONNECT_RECV = ptr::null_mut(); - let mut size_buf: DWORD = 0; - let size_buf_pointer: *mut DWORD = &mut size_buf; + pub unsafe fn get_last_sent_packet_id(&self, error: *mut DWORD) -> bool { + unsafe { SimConnect_GetLastSentPacketID(self.handle, error) == 0 } + } + + pub unsafe fn call_dispatch( + &self, + dispatch_callback: DispatchProc, + context: *mut std::os::raw::c_void, + ) -> bool { + unsafe { SimConnect_CallDispatch(self.handle, dispatch_callback, context) == 0 } + } + + pub unsafe fn request_response_times(&self, count: DWORD, elapsed_seconds: *mut f32) -> bool { + unsafe { SimConnect_RequestResponseTimes(self.handle, count, elapsed_seconds) == 0 } + } + // ==================== String Utilities ==================== + + pub unsafe fn retrieve_string( + p_data: *mut SIMCONNECT_RECV, + cb_data: DWORD, + p_string_v: *mut std::os::raw::c_void, + psz_string: *mut *mut std::os::raw::c_char, + pcb_string: *mut DWORD, + ) -> bool { + unsafe { + SimConnect_RetrieveString(p_data, cb_data, p_string_v, psz_string, pcb_string) == 0 + } + } + + pub unsafe fn insert_string( + p_dest: *mut std::os::raw::c_char, + cb_dest: DWORD, + pp_end: *mut *mut std::os::raw::c_void, + pcb_string: *mut DWORD, + p_source: *const std::os::raw::c_char, + ) -> bool { + unsafe { + SimConnect_InsertString(p_dest, cb_dest, pp_end, pcb_string, p_source) == 0 + } + } + + // ==================== Main Message Loop ==================== + + pub fn get_next_message(&self) -> Result, &str> { unsafe { - let result = SimConnect_GetNextDispatch( - self.sim_connect_handle, - &mut data_buf, - size_buf_pointer, - ); - - if result != 0 { - return Err("Failed getting data!"); + let mut data_buf: *mut SIMCONNECT_RECV = ptr::null_mut(); + let mut size_buf: DWORD = 0; + + if SimConnect_GetNextDispatch(self.handle, &mut data_buf, &mut size_buf) != 0 { + return Err("Failed getting data from SimConnect"); } - // SimConnect_GetNextDispatch returns S_OK with a NULL pointer when the queue is empty. - // Dereferencing a null pointer would be UB, so we must check this explicitly. if data_buf.is_null() { return Ok(DispatchResult::Null); } match (*data_buf).dwID as SIMCONNECT_RECV_ID { SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NULL => Ok(DispatchResult::Null), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EXCEPTION => Ok(DispatchResult::Exception( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_EXCEPTION)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_OPEN => Ok(DispatchResult::Open( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_OPEN)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_QUIT => Ok(DispatchResult::Quit( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_QUIT)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT => Ok(DispatchResult::Event( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_EVENT)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE => { - Ok(DispatchResult::EventObjectAddRemove(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FILENAME => { - Ok(DispatchResult::EventFilename(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_FILENAME), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FRAME => { - Ok(DispatchResult::EventFrame(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_FRAME), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => { - Ok(DispatchResult::SimObjectData(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE => { - Ok(DispatchResult::SimObjectDataByType(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WEATHER_OBSERVATION => { - Ok(DispatchResult::WeatherObservation(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_WEATHER_OBSERVATION), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLOUD_STATE => { - Ok(DispatchResult::CloudState(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_CLOUD_STATE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID => { - Ok(DispatchResult::AssignedObjectId(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_ASSIGNED_OBJECT_ID), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_RESERVED_KEY => { - Ok(DispatchResult::ReservedKey(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_RESERVED_KEY), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CUSTOM_ACTION => { - Ok(DispatchResult::CustomAction(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_CUSTOM_ACTION), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SYSTEM_STATE => { - Ok(DispatchResult::SystemState(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_SYSTEM_STATE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLIENT_DATA => { - Ok(DispatchResult::ClientData(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_CLIENT_DATA), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_WEATHER_MODE => { - Ok(DispatchResult::EventWeatherMode(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_WEATHER_MODE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_AIRPORT_LIST => { - Ok(DispatchResult::AirportList(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_AIRPORT_LIST), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_VOR_LIST => Ok(DispatchResult::VorList( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_VOR_LIST)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NDB_LIST => Ok(DispatchResult::NdbList( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_NDB_LIST)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WAYPOINT_LIST => { - Ok(DispatchResult::WaypointList(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_WAYPOINT_LIST), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SERVER_STARTED => Ok( - DispatchResult::EventMultiplayerServerStarted(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED), - )), - ), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_CLIENT_STARTED => Ok( - DispatchResult::EventMultiplayerClientStarted(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED), - )), - ), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SESSION_ENDED => Ok( - DispatchResult::EventMultiplayerSessionEnded(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED), - )), - ), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_END => { - Ok(DispatchResult::EventRaceEnd(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_END), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_LAP => { - Ok(DispatchResult::EventRaceLap(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_LAP), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_EX1 => Ok(DispatchResult::EventEx1( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_EVENT_EX1)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA => { - Ok(DispatchResult::FacilityData(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA_END => { - Ok(DispatchResult::FacilityDataEnd(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA_END), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_MINIMAL_LIST => { - Ok(DispatchResult::FacilityMinimalList(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_FACILITY_MINIMAL_LIST), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_JETWAY_DATA => { - Ok(DispatchResult::JetwayData(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_JETWAY_DATA), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CONTROLLERS_LIST => { - Ok(DispatchResult::ControllersList(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_CONTROLLERS_LIST), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ACTION_CALLBACK => { - Ok(DispatchResult::ActionCallback(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_ACTION_CALLBACK), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENTS => { - Ok(DispatchResult::EnumerateInputEvents(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_GET_INPUT_EVENT => { - Ok(DispatchResult::GetInputEvent(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_GET_INPUT_EVENT), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SUBSCRIBE_INPUT_EVENT => { - Ok(DispatchResult::SubscribeInputEvent(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENT_PARAMS => { - Ok(DispatchResult::EnumerateInputEventParams(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS), - ))) - } - + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EXCEPTION => Ok(DispatchResult::Exception(&*(data_buf as *const SIMCONNECT_RECV_EXCEPTION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_OPEN => Ok(DispatchResult::Open(&*(data_buf as *const SIMCONNECT_RECV_OPEN))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_QUIT => Ok(DispatchResult::Quit(&*(data_buf as *const SIMCONNECT_RECV_QUIT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT => Ok(DispatchResult::Event(&*(data_buf as *const SIMCONNECT_RECV_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE => Ok(DispatchResult::EventObjectAddRemove(&*(data_buf as *const SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FILENAME => Ok(DispatchResult::EventFilename(&*(data_buf as *const SIMCONNECT_RECV_EVENT_FILENAME))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FRAME => Ok(DispatchResult::EventFrame(&*(data_buf as *const SIMCONNECT_RECV_EVENT_FRAME))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => Ok(DispatchResult::SimObjectData(&*(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE => Ok(DispatchResult::SimObjectDataByType(&*(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WEATHER_OBSERVATION => Ok(DispatchResult::WeatherObservation(&*(data_buf as *const SIMCONNECT_RECV_WEATHER_OBSERVATION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLOUD_STATE => Ok(DispatchResult::CloudState(&*(data_buf as *const SIMCONNECT_RECV_CLOUD_STATE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID => Ok(DispatchResult::AssignedObjectId(&*(data_buf as *const SIMCONNECT_RECV_ASSIGNED_OBJECT_ID))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_RESERVED_KEY => Ok(DispatchResult::ReservedKey(&*(data_buf as *const SIMCONNECT_RECV_RESERVED_KEY))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CUSTOM_ACTION => Ok(DispatchResult::CustomAction(&*(data_buf as *const SIMCONNECT_RECV_CUSTOM_ACTION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SYSTEM_STATE => Ok(DispatchResult::SystemState(&*(data_buf as *const SIMCONNECT_RECV_SYSTEM_STATE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLIENT_DATA => Ok(DispatchResult::ClientData(&*(data_buf as *const SIMCONNECT_RECV_CLIENT_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_WEATHER_MODE => Ok(DispatchResult::EventWeatherMode(&*(data_buf as *const SIMCONNECT_RECV_EVENT_WEATHER_MODE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_AIRPORT_LIST => Ok(DispatchResult::AirportList(&*(data_buf as *const SIMCONNECT_RECV_AIRPORT_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_VOR_LIST => Ok(DispatchResult::VorList(&*(data_buf as *const SIMCONNECT_RECV_VOR_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NDB_LIST => Ok(DispatchResult::NdbList(&*(data_buf as *const SIMCONNECT_RECV_NDB_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WAYPOINT_LIST => Ok(DispatchResult::WaypointList(&*(data_buf as *const SIMCONNECT_RECV_WAYPOINT_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SERVER_STARTED => Ok(DispatchResult::EventMultiplayerServerStarted(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_CLIENT_STARTED => Ok(DispatchResult::EventMultiplayerClientStarted(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SESSION_ENDED => Ok(DispatchResult::EventMultiplayerSessionEnded(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_END => Ok(DispatchResult::EventRaceEnd(&*(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_END))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_LAP => Ok(DispatchResult::EventRaceLap(&*(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_LAP))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_EX1 => Ok(DispatchResult::EventEx1(&*(data_buf as *const SIMCONNECT_RECV_EVENT_EX1))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA => Ok(DispatchResult::FacilityData(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA_END => Ok(DispatchResult::FacilityDataEnd(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA_END))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_MINIMAL_LIST => Ok(DispatchResult::FacilityMinimalList(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_MINIMAL_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_JETWAY_DATA => Ok(DispatchResult::JetwayData(&*(data_buf as *const SIMCONNECT_RECV_JETWAY_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ACTION_CALLBACK => Ok(DispatchResult::ActionCallback(&*(data_buf as *const SIMCONNECT_RECV_ACTION_CALLBACK))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENTS => Ok(DispatchResult::EnumerateInputEvents(&*(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_GET_INPUT_EVENT => Ok(DispatchResult::GetInputEvent(&*(data_buf as *const SIMCONNECT_RECV_GET_INPUT_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SUBSCRIBE_INPUT_EVENT => Ok(DispatchResult::SubscribeInputEvent(&*(data_buf as *const SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENT_PARAMS => Ok(DispatchResult::EnumerateInputEventParams(&*(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CONTROLLERS_LIST => Ok(DispatchResult::ControllersList(&*(data_buf as *const SIMCONNECT_RECV_CONTROLLERS_LIST))), _ => Err("Unhandled RECV_ID"), } } @@ -1199,8 +1181,13 @@ impl SimConnector { impl Drop for SimConnector { fn drop(&mut self) { - if !self.sim_connect_handle.is_null() { - self.close(); + if !self.handle.is_null() { + let _ = self.close(); } } } + +#[inline] +fn cstring(s: &str) -> CString { + CString::new(s).expect("string contained interior nul byte") +} \ No newline at end of file