/// Creates a [`HashMap`](bevy_utils::HashMap) from a list of key-value pairs. /// /// Example: /// ```ignore /// let map = hashmap! { /// "key1" => "value1", /// "key2" => "value2" /// }; #[macro_export] macro_rules! hashmap { ($( $key: expr => $val: expr ),*) => {{ let mut map = HashMap::new(); $( map.insert($key, $val); )* map }}; } /// Applies common traits conditionally to items. /// /// This macro is designed to reduce repetition and maintenance overhead by /// automatically deriving specified traits for each item passed to it based /// on the feature flags. It's intended for use with almost all types in this module. /// /// # Features: /// - `serialize`: Derives `Serialize` and `Deserialize` traits and applies /// reflection for serialization if the `serialize` feature is enabled. /// - `reflect`: Derives the `Reflect` trait if the `reflect` feature is enabled. /// - `inspector-egui`: Derives `InspectorOptions` trait and applies reflection /// for the inspector if the `inspector-egui` feature is enabled. /// /// # Usage /// To use this macro, wrap any item(s) you want to apply the common traits to. /// Each item can be a struct or enum that you want to derive traits for based /// on the feature flags. /// /// # Example: /// ```ignore /// common_traits_conditions! { /// struct MyStruct { /// // fields /// } /// /// enum MyEnum { /// // variants /// } /// } /// ``` #[macro_export] macro_rules! common_traits_conditions { ($($item:item)*) => { $( #[cfg_attr( feature = "serialize", derive(Serialize, Deserialize), )] #[cfg_attr( feature = "reflect", derive(Reflect), )] #[cfg_attr( all(feature = "reflect", feature = "serialize"), reflect(Serialize, Deserialize), )] #[cfg_attr( feature = "inspector-egui", derive(InspectorOptions), reflect(InspectorOptions), )] $item )* }; } #[cfg(test)] pub mod test { use std::time::{Duration, Instant}; use bevy_derive::{Deref, DerefMut}; use log::Level; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deref, DerefMut)] pub struct Times(u64); impl Into for Times { fn into(self) -> u64 { self.0 } } impl Into for Times { fn into(self) -> usize { self.0 as usize } } impl Into for Times { fn into(self) -> u32 { self.0 as u32 } } impl Into for Times { fn into(self) -> i32 { self.0 as i32 } } impl From for Times { fn from(times: u64) -> Self { Self(times) } } impl From for Times { fn from(times: usize) -> Self { Self(times as u64) } } impl From for Times { fn from(times: u32) -> Self { Self(times as u64) } } impl From for Times { fn from(times: i32) -> Self { Self(times as u64) } } impl Default for Times { /// Value that may be enough for most cases fn default() -> Self { Self(100000) } } /// Enable logging for debug pub fn enable_loggings() { use std::env; use std::io::Write; let _ = env::set_var("RUST_LOG", "debug"); // FIXME: colorize logs // TODO: colorize thorwed args let _ = env_logger::builder() .is_test(true) .format(|buf, record| { let mut style = buf.style(); let level = record.level(); match level { Level::Trace => style.set_color(env_logger::fmt::Color::Magenta), Level::Debug => style.set_color(env_logger::fmt::Color::Blue), Level::Info => style.set_color(env_logger::fmt::Color::Green), Level::Warn => style.set_color(env_logger::fmt::Color::Yellow), Level::Error => style.set_color(env_logger::fmt::Color::Red), }; writeln!(buf, "{}: {}", style.value(level), record.args()) }) .try_init(); } /// Measure time of predicate pub fn measure_time(predicate: F, times: Times) -> Duration where F: FnOnce() -> (), { let start = Instant::now(); for _ in 0..times.clone().into() { predicate(); } let global_duration = start.elapsed(); global_duration / times.into() } }