libobs_wrapper/
macros.rs

1#[macro_export]
2macro_rules! run_with_obs_impl {
3    ($runtime:expr, $operation:expr) => {
4        $crate::run_with_obs_impl!($runtime, (), $operation)
5    };
6    ($runtime:expr, ($($var:ident),* $(,)*), $operation:expr) => {
7        {
8            $(let $var = $var.clone();)*
9            $runtime.run_with_obs_result(move || {
10                $(let $var = $var;)*
11                let inner_obs_run = {
12                    //$(let $var = $var.0;)*
13                    $operation
14                };
15                return inner_obs_run()
16            })
17        }
18    };
19    (SEPARATE_THREAD, $runtime:expr, ($($var:ident),* $(,)*), $operation:expr) => {
20        {
21            $(let $var = $var.clone();)*
22
23            tokio::task::spawn_blocking(move || {
24                $runtime.run_with_obs_result(move || {
25                    $(let $var = $var;)*
26                    let e = {
27                        //$(let $var = $var.0;)*
28                        $operation
29                    };
30                    return e()
31                }).unwrap()
32            })
33        }
34    };
35}
36
37#[macro_export]
38macro_rules! run_with_obs {
39    ($runtime:expr, $operation:expr) => {
40        {
41            $crate::run_with_obs_impl!($runtime, $operation)
42                .map_err(|e| $crate::utils::ObsError::InvocationError(e.to_string()))
43        }
44    };
45    ($runtime:expr, ($($var:ident),* $(,)*), $operation:expr) => {
46        {
47            $crate::run_with_obs_impl!($runtime, ($($var),*), $operation)
48                .map_err(|e| $crate::utils::ObsError::InvocationError(e.to_string()))
49        }
50    };
51}
52
53#[macro_export]
54macro_rules! impl_obs_drop {
55    ($struct_name: ident, $operation:expr) => {
56        $crate::impl_obs_drop!($struct_name, (), $operation);
57    };
58    ($struct_name: ident, ($($var:ident),* $(,)*), $operation:expr) => {
59        impl Drop for $struct_name {
60            fn drop(&mut self) {
61                log::trace!("Dropping {}...", stringify!($struct_name));
62
63                $(let $var = self.$var.clone();)*
64                #[cfg(any(
65                    not(feature = "no_blocking_drops"),
66                    test,
67                    feature="__test_environment",
68                    not(feature="enable_runtime")
69                ))]
70                {
71                    let run_with_obs_result = $crate::run_with_obs!(self.runtime, ($($var),*), $operation);
72                    if std::thread::panicking() {
73                        return;
74                    }
75
76                    run_with_obs_result.unwrap();
77                }
78
79                #[cfg(all(
80                    feature = "no_blocking_drops",
81                    not(test),
82                    not(feature="__test_environment"),
83                    feature="enable_runtime"
84                ))]
85                {
86                    let __runtime = self.runtime.clone();
87                    $crate::run_with_obs_impl!(SEPARATE_THREAD, __runtime, ($($var),*), $operation);
88                }
89            }
90        }
91    };
92}
93
94/// Implements PartialEq, Eq and Hash für a struct by comparing the inner pointer given by `as_ptr()`.
95macro_rules! impl_eq_of_ptr {
96    ($struct: ty) => {
97        impl PartialEq for $struct {
98            fn eq(&self, other: &Self) -> bool {
99                #[allow(unused_imports)]
100                use crate::data::object::ObsObjectTrait;
101                self.as_ptr().get_ptr() == other.as_ptr().get_ptr()
102            }
103        }
104
105        impl Eq for $struct {}
106
107        impl std::hash::Hash for $struct {
108            fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
109                #[allow(unused_imports)]
110                use crate::data::object::ObsObjectTrait;
111                self.as_ptr().get_ptr().hash(state);
112            }
113        }
114    };
115}
116
117#[cfg(windows)]
118macro_rules! enum_from_number {
119    ($var: ident, $numb: expr) => {{
120        use num_traits::FromPrimitive;
121        $var::from_i32($numb)
122    }};
123}
124
125#[cfg(not(windows))]
126macro_rules! enum_from_number {
127    ($var: ident, $numb: expr) => {{
128        use num_traits::FromPrimitive;
129        $var::from_u32($numb)
130    }};
131}
132
133/// Defines a trait that conditionally includes Send + Sync bounds when the enable_runtime feature is enabled.
134/// This avoids duplicating trait definitions for runtime vs non-runtime scenarios.
135///
136/// # Example
137/// ```ignore
138/// trait_with_optional_send_sync! {
139///     #[doc(hidden)]
140///     pub trait MyTrait: Debug {
141///         fn my_method(&self);
142///     }
143/// }
144/// ```
145/// This expands to two trait definitions:
146/// - With enable_runtime: `pub trait MyTrait: Debug + Send + Sync { ... }`
147/// - Without enable_runtime: `pub trait MyTrait: Debug { ... }`
148macro_rules! trait_with_optional_send_sync {
149    (
150        $(#[$meta:meta])*
151        $vis:vis trait $trait_name:ident: $base_bound:path {
152            $($body:tt)*
153        }
154    ) => {
155        #[cfg(feature="enable_runtime")]
156        $(#[$meta])*
157        $vis trait $trait_name: $base_bound + Send + Sync {
158            $($body)*
159        }
160
161        #[cfg(not(feature="enable_runtime"))]
162        $(#[$meta])*
163        $vis trait $trait_name: $base_bound {
164            $($body)*
165        }
166    };
167}
168
169pub(crate) use enum_from_number;
170pub(crate) use impl_eq_of_ptr;
171pub(crate) use trait_with_optional_send_sync;