#![feature(fundamental)] pub mod userdata_dir; pub use userdata_dir::userdata_dir; #[cfg(feature = "tracy")] pub use tracy_client; #[macro_export] macro_rules! plot { ($name:expr, $value:expr) => { #[cfg(feature = "tracy")] { use $crate::tracy_client::{create_plot, Plot}; static PLOT: Plot = create_plot!($name); PLOT.point($value); } #[cfg(not(feature = "tracy"))] { // type check let _: f64 = $value; } }; } // https://discordapp.com/channels/676678179678715904/676685797524766720/723358438943621151 #[macro_export] macro_rules! span { ($guard_name:tt, $level:ident, $name:expr, $($fields:tt)*) => { let span = tracing::span!(tracing::Level::$level, $name, $($fields)*); let $guard_name = span.enter(); }; ($guard_name:tt, $level:ident, $name:expr) => { let span = tracing::span!(tracing::Level::$level, $name); let $guard_name = span.enter(); }; ($guard_name:tt, $name:expr) => { #[cfg(not(feature = "tracy"))] let span = tracing::span!(tracing::Level::TRACE, $name); #[cfg(not(feature = "tracy"))] let $guard_name = span.enter(); // Directly use `tracy_client` to decrease overhead for better timing #[cfg(feature = "tracy")] let $guard_name = $crate::tracy_client::Span::new( $name, "", module_path!(), line!(), // No callstack since this has significant overhead 0, ); }; ($guard_name:tt, $no_tracy_name:expr, $tracy_name:expr) => { #[cfg(not(feature = "tracy"))] $crate::span!($guard_name, $no_tracy_name); #[cfg(feature = "tracy")] $crate::span!($guard_name, $tracy_name); }; } pub struct DummySpan; /// Like the span macro but only used when profiling and not in regular tracing /// operations #[macro_export] macro_rules! prof_span { ($guard_name:tt, $name:expr) => { #[cfg(feature = "tracy")] let $guard_name = $crate::tracy_client::Span::new( $name, "", module_path!(), line!(), // No callstack since this has significant overhead 0, ); #[cfg(not(feature = "tracy"))] let $guard_name = $crate::DummySpan; }; } /// There's no guard, but really this is actually the guard pub struct GuardlessSpan { span: tracing::Span, subscriber: tracing::Dispatch, } impl GuardlessSpan { pub fn new(span: tracing::Span) -> Self { let subscriber = tracing::dispatcher::get_default(|d| d.clone()); if let Some(id) = span.id() { subscriber.enter(&id) } Self { span, subscriber } } } impl Drop for GuardlessSpan { fn drop(&mut self) { if let Some(id) = self.span.id() { self.subscriber.exit(&id) } } } #[macro_export] macro_rules! no_guard_span { ($level:ident, $name:expr, $($fields:tt)*) => { GuardlessSpan::new( tracing::span!(tracing::Level::$level, $name, $($fields)*) ) }; ($level:ident, $name:expr) => { GuardlessSpan::new( tracing::span!(tracing::Level::$level, $name) ) }; ($name:expr) => { GuardlessSpan::new( tracing::span!(tracing::Level::TRACE, $name) ) }; }