Skip to main content

orbiter_rs/
macros.rs

1/// Helper macro for defining [`Vector3`](super::VECTOR3) objects
2#[macro_export]
3macro_rules! V {
4    ($x:expr, $y:expr, $z:expr) => {
5        $crate::Vector3::new($x, $y, $z)
6    };
7}
8/// Macro for defining ctype wrappers
9///
10/// Adapted from [comment](https://github.com/dtolnay/cxx/issues/254#issuecomment-747860504) by Adrian Taylor
11#[macro_export]
12macro_rules! ctype_wrapper {
13    ($r:ident, $c:ty) => {
14        #[doc = "Newtype wrapper for `"]
15        #[doc = stringify!($r)]
16        #[doc = "` as a [`"]
17        #[doc = stringify!($c)]
18        #[doc = "`]"]
19        #[derive(Debug, Eq, Clone, PartialEq, Hash, Default, Copy)]
20        #[allow(non_camel_case_types)]
21        #[repr(transparent)]
22        pub struct $r(pub $c);
23        unsafe impl cxx::ExternType for $r {
24            type Id = cxx::type_id!($r);
25            type Kind = cxx::kind::Trivial;
26        }
27    };
28    ($r:ident, $c:ty, $nice_name:ident) => {
29        #[doc = "Newtype wrapper for `"]
30        #[doc = stringify!($r)]
31        #[doc = "` as a ["]
32        #[doc = stringify!($c)]
33        #[doc = "]"]
34        #[derive(Debug, Eq, Clone, PartialEq, Hash, Default, Copy)]
35        #[allow(non_camel_case_types)]
36        #[repr(transparent)]
37        pub struct $r(pub $c);
38        unsafe impl cxx::ExternType for $r {
39            type Id = cxx::type_id!($r);
40            type Kind = cxx::kind::Trivial;
41        }
42        #[doc = "Type alias for ["]
43        #[doc = stringify!($r)]
44        #[doc = "]"]
45        pub type $nice_name = $r;
46    };
47}
48
49/// Helper macro for defining entry point into a Vessel addon
50///
51/// Inspired by emgre's [orbiter-rs](https://github.com/emgre/orbiter-rs/blob/107068c6e66564b9dff86c8b964515da9771a3af/orbiter/src/lib.rs#L37)
52///
53/// The macro should contain two function blocks `init()` and `exit()`. The `init` function takes one argument,
54/// an `[SDKVessel]` instance. It is expected that this `[SDKVessel]` instance is passed to and stored in the Rust code implementing the addon.
55///
56/// The `exit` function is called at the end of a simulation session and can be used to perform cleanup functions.
57///
58/// Example:
59/// ```no_run
60/// fn init(vessel)
61/// {
62///     Surveyor::new(vessel)
63/// }
64/// fn exit() {}
65/// ```
66#[macro_export]
67macro_rules! init_vessel {
68    (fn init($vessel_ident:ident) $init_block:block fn exit() $body_exit:block) => {
69        #[no_mangle]
70        pub extern "C" fn ovcInit (hvessel: $crate::OBJHANDLE, flightmodel: i32) -> *mut $crate::ffi::VESSEL
71        {
72            // The init function pointer gets stored in the C++ object
73            // and gets triggered on clbkSetClassCaps() before the trait method
74            unsafe { $crate::ffi::vessel_ovcInit(hvessel, flightmodel, vessel_init) }
75        }
76        #[no_mangle]
77        pub extern "C" fn ovcExit (vessel: *mut $crate::ffi::VESSEL)
78        {
79            $body_exit
80            unsafe { $crate::ffi::vessel_ovcExit(vessel); }
81        }
82        pub fn vessel_init<'a> (vessel: std::pin::Pin<&'static mut $crate::ffi::VesselContext>) -> Box<dyn $crate::OrbiterVessel + 'static>
83        {
84            let $vessel_ident = vessel;
85            let spacecraft = {
86                $init_block
87            };
88            return Box::new(spacecraft);
89        }
90    };
91}
92
93/// Displays a string in the lower left corner of the viewport.
94///
95/// This macro uses the exact same parameters as the [`format!`] macro of the
96/// standard library.
97///
98/// Due to how Orbiter handles this string, its length is limited to 255 characters.
99/// The Rust code truncates the formatted string to 255 characters to make sure that
100/// no buffer overflow occurs.
101///
102/// **This function should only be used for debugging purposes.**
103///
104/// # Examples
105///
106/// ```
107/// use orbiter_rs::debug_string;
108///
109/// let some_value = 42;
110/// debug_string!("This is my value: {}", 42);
111/// ```
112///
113/// [`format!`]: https://doc.rust-lang.org/std/fmt/index.html
114///
115/// Macro adapted from Émile Grégoire's version at
116/// <https://github.com/emgre/orbiter-rs/blob/107068c6e66564b9dff86c8b964515da9771a3af/orbiter/src/lib.rs#L96>
117#[macro_export]
118macro_rules! debug_string {
119    ($($args:tt)+) => {
120        $crate::ODebug(format!($($args)*));
121    }
122}