use std::cell::RefCell;
use std::collections::VecDeque;
use web_time::Instant;
struct Event {
t: Instant,
tag: &'static str,
size: Option<(u32, u32)>,
note: Option<String>,
}
const CAPACITY: usize = 16384;
thread_local! {
static EVENTS: RefCell<VecDeque<Event>> = RefCell::new(VecDeque::with_capacity(CAPACITY));
static START: Instant = Instant::now();
}
pub fn record(tag: &'static str) {
push(tag, None, None);
}
pub fn record_size(tag: &'static str, width: u32, height: u32) {
push(tag, Some((width, height)), None);
}
pub fn record_note(tag: &'static str, note: impl Into<String>) {
push(tag, None, Some(note.into()));
}
pub fn record_size_note(tag: &'static str, width: u32, height: u32, note: impl Into<String>) {
push(tag, Some((width, height)), Some(note.into()));
}
fn push(tag: &'static str, size: Option<(u32, u32)>, note: Option<String>) {
EVENTS.with(|events| {
let mut events = events.borrow_mut();
if events.len() == CAPACITY {
events.pop_front();
}
events.push_back(Event { t: Instant::now(), tag, size, note });
});
}
pub fn dump(label: &str) {
let start = START.with(|s| *s);
EVENTS.with(|events| {
let mut events = events.borrow_mut();
log::info!("=== devtools dump: {label} ({} events) ===", events.len());
for event in events.iter() {
let us = event.t.duration_since(start).as_micros();
match (&event.size, &event.note) {
(Some((w, h)), Some(note)) =>
log::info!("[{us:>12}us] {:<28} {w}x{h} {note}", event.tag),
(Some((w, h)), None) => log::info!("[{us:>12}us] {:<28} {w}x{h}", event.tag),
(None, Some(note)) => log::info!("[{us:>12}us] {:<28} {note}", event.tag),
(None, None) => log::info!("[{us:>12}us] {}", event.tag),
}
}
log::info!("=== end dump ===");
events.clear();
});
}
pub fn clear() {
EVENTS.with(|events| events.borrow_mut().clear());
}