use std::collections::VecDeque;
use std::time;
use eframe::egui;
use egui_plot::{Line, Plot, PlotPoints};
#[cfg(not(target_arch = "wasm32"))]
type TimeInstant = time::Instant;
#[cfg(target_arch = "wasm32")]
type TimeInstant = f64;
fn now() -> TimeInstant {
#[cfg(not(target_arch = "wasm32"))]
return time::Instant::now();
#[cfg(target_arch = "wasm32")]
web_sys::window()
.expect("no window")
.performance()
.expect("no performance")
.now()
}
#[derive(Default)]
pub struct Tracing {
pub name: String,
current: Option<TimeInstant>,
max_buffer_size: usize,
buffer: VecDeque<time::Duration>,
}
impl Tracing {
pub fn new(name: &str, max_buffer_size: usize) -> Tracing {
Tracing {
name: name.into(),
current: None,
max_buffer_size,
buffer: VecDeque::with_capacity(max_buffer_size),
}
}
pub fn buffer_size(&self) -> usize {
self.buffer.len()
}
pub fn start(&mut self) {
self.current = Some(now());
}
pub fn measure(&mut self) {
if self.buffer.len() == self.max_buffer_size {
self.buffer.pop_front();
}
let current = self.current.expect("missing start()");
#[cfg(not(target_arch = "wasm32"))]
self.buffer.push_back(current.elapsed());
#[cfg(target_arch = "wasm32")]
self.buffer.push_back(time::Duration::from_micros(
((now() - current) * 1e3) as u64,
));
}
pub fn plot(&self, ui: &mut egui::Ui) {
let points: PlotPoints = (0..self.buffer_size())
.map(|i| {
[
i as f64,
self.buffer.get(i).expect("missing duration").as_secs_f64(),
]
})
.collect();
Plot::new(self.name.as_str())
.view_aspect(2.0)
.show(ui, |plot_ui| plot_ui.line(Line::new("duration", points)));
}
}