Skip to main content

source2_demo/
macros.rs

1/// Internal macro for calling observer methods efficiently.
2///
3/// This macro checks if any observers are interested in a particular event type
4/// before iterating through them, improving performance.
5#[doc(hidden)]
6#[macro_export]
7macro_rules! try_observers {
8    ($self:ident, $flag:ident, $method:ident ( $($arg:expr),* )) => {{
9        use $crate::Interests;
10        if !$self.global_mask.intersects(Interests::$flag) {
11            Ok(())
12        } else {
13            ($self.observers.iter().zip($self.observer_masks.iter()))
14                .try_for_each(|(obs, &mask)| {
15                    if mask.intersects(Interests::$flag) {
16                        obs.borrow_mut().$method($($arg),*)
17                    } else {
18                        Ok(())
19                    }
20                })
21        }
22    }};
23}
24/// Macro for getting property from [`crate::Entity`].
25///
26/// # Examples
27/// ```no_compile
28/// let x: i32 = property!(entity, "property_name");
29/// let y = property!(entity, i32, "property_name");
30/// ```
31#[macro_export]
32macro_rules! property {
33    ($ent:expr, $ty:ty, $fmt:literal, $($arg:tt)*) => {
34        {
35            let x: $ty = $ent.get_property_by_name(&format!($fmt, $($arg)*))?.try_into()?;
36            x
37        }
38    };
39    ($ent:expr, $ty:ty, $fmt:literal) => {
40        {
41            let x: $ty = $ent.get_property_by_name(&format!($fmt))?.try_into()?;
42            x
43        }
44    };
45    ($ent:expr, $fmt:expr, $($arg:tt)*) => {
46        $ent.get_property_by_name(&format!($fmt, $($arg)*))?.try_into()?
47    };
48    ($ent:expr, $fmt:expr) => {{
49        $ent.get_property_by_name(&format!($fmt))?.try_into()?
50    }};
51}
52
53/// Same as [`crate::property`] but returns `None` if property doesn't exist for given
54/// [`crate::Entity`] or cannot be converted into given type.
55///
56/// # Examples
57/// ```no_compile
58/// let x: i32 = try_property!(entity, "property_name").unwrap_or_default();
59/// let y = try_property!(entity, i32, "property_name").unwrap_or_default();
60/// ```
61#[macro_export]
62macro_rules! try_property {
63    ($ent:expr, $ty:ty, $fmt:expr, $($arg:tt)*) => {
64        {
65            let x: Option<$ty> = $ent
66                .get_property_by_name(&format!($fmt, $($arg)*))
67                .ok()
68                .and_then(|x| {
69                    x.try_into().ok()
70                });
71            x
72        }
73    };
74
75    ($ent:expr, $ty:ty, $fmt:expr) => {
76        {
77            let x: Option<$ty> = $ent
78                .get_property_by_name(&format!($fmt))
79                .ok()
80                .and_then(|x| {
81                    x.try_into().ok()
82                });
83            x
84        }
85    };
86
87    ($ent:expr, $fmt:expr, $($arg:tt)*) => {
88        $ent
89            .get_property_by_name(&format!($fmt, $($arg)*))
90            .ok()
91            .and_then(|x| {
92                x.try_into().ok()
93            })
94    };
95
96    ($ent:expr, $fmt:expr) => {{
97        $ent
98            .get_property_by_name(&format!($fmt))
99            .ok()
100            .and_then(|x| {
101                x.try_into().ok()
102            })
103    }};
104}