use std::collections::HashMap;
use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
use std::sync::Arc;
use flight_log::{
LogData, LogStateRef, LogTimer, LogValue, end_log_timer, log_debug, start_log_timer,
};
use crate::debug::is_debug_enabled;
use crate::types::DebugStateRef;
pub fn begin_debug_span(
state: &DebugStateRef,
now_ms: f64,
name: &str,
channel: Option<String>,
) -> Option<LogTimer> {
if !is_debug_enabled(state) {
return None;
}
return Some(start_log_timer(name, channel, now_ms));
}
pub fn end_debug_span(log_state: &LogStateRef, now_ms: f64, timer: Option<&LogTimer>) -> f64 {
let Some(timer) = timer else {
return -1.0;
};
return end_log_timer(log_state, now_ms, timer);
}
pub fn mark_debug_frame(
state: &DebugStateRef,
log_state: &LogStateRef,
now_ms: f64,
label: Option<&str>,
channel: Option<String>,
) {
if !is_debug_enabled(state) {
return;
}
let frame = match label {
Some(label) => LogValue::Str(label.to_string()),
None => {
let mut current = state.write().unwrap();
current.frame_number += 1;
LogValue::Int(current.frame_number)
}
};
let mut data = HashMap::new();
data.insert("frame".to_string(), frame);
log_debug(log_state, now_ms, LogData::Record(data).into(), channel);
}
pub fn measure_debug_span<T>(
state: &DebugStateRef,
log_state: &LogStateRef,
clock: &Arc<dyn Fn() -> f64 + Send + Sync>,
name: &str,
run: impl FnOnce() -> T,
channel: Option<String>,
) -> T {
let timer = begin_debug_span(state, clock(), name, channel);
let result = catch_unwind(AssertUnwindSafe(run));
if timer.is_some() {
end_debug_span(log_state, clock(), timer.as_ref());
}
return match result {
Ok(value) => value,
Err(error) => resume_unwind(error),
};
}