/* wearechat - generic multiplayer game with voip Copyright (C) 2025 metamuffin This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License only. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use super::InterfaceData; use egui::{Grid, Widget}; use std::{sync::Arc, time::Instant}; pub struct Profiler { pub idata: Arc, } impl Widget for &mut Profiler { fn ui(self, ui: &mut egui::Ui) -> egui::Response { ui.collapsing("Scene", |ui| { self.idata.scene_prepare.ui(ui); }); ui.collapsing("Download", |ui| { ui.add(&*self.idata.downloader); }); ui.collapsing("Render", |ui| { ui.add(&*self.idata.render_timing.lock().unwrap()); }); ui.response() } } pub struct TimingProfiler { last_cp: Instant, cur_cp: &'static str, checkpoints: Vec<(&'static str, f32)>, } impl Default for TimingProfiler { fn default() -> Self { Self { last_cp: Instant::now(), checkpoints: Default::default(), cur_cp: "none", } } } impl TimingProfiler { pub fn begin(&mut self, name: &'static str) { self.checkpoints.clear(); self.last_cp = Instant::now(); self.cur_cp = name; } pub fn checkpoint(&mut self, name: &'static str) { let now = Instant::now(); let dur = (now - self.last_cp).as_secs_f32(); self.last_cp = now; self.checkpoints.push((self.cur_cp, dur)); self.cur_cp = name; } } impl Widget for &TimingProfiler { fn ui(self, ui: &mut egui::Ui) -> egui::Response { Grid::new("tp") .num_columns(2) .show(ui, |ui| { for (name, dur) in &self.checkpoints { ui.label(*name); ui.label(format!("{:.02}ms", dur * 1000.)); ui.end_row(); } }) .response } }