1use crate::prelude::*;
4
5#[derive(HasSchema, Clone)]
7#[allow(missing_docs)]
8pub struct FrameDiagState {
9 pub fps: f64,
10 pub fps_avg: f64,
11 pub min_fps: f64,
12 pub max_fps: f64,
13 pub frame_time: f64,
14 pub frame_time_avg: f64,
15 pub min_frame_time: f64,
16 pub max_frame_time: f64,
17}
18
19impl Default for FrameDiagState {
20 fn default() -> Self {
21 Self {
22 fps: 0.0,
23 fps_avg: 0.0,
24 min_fps: f64::MAX,
25 max_fps: 0.0,
26 frame_time: 0.0,
27 frame_time_avg: 0.0,
28 min_frame_time: f64::MAX,
29 max_frame_time: 0.0,
30 }
31 }
32}
33
34impl FrameDiagState {
35 pub fn reset(&mut self) {
37 self.min_fps = f64::MAX;
38 self.max_fps = 0.0;
39 self.min_frame_time = f64::MAX;
40 self.max_frame_time = 0.0;
41 }
42}
43
44#[derive(Clone, Default)]
47pub struct FrameTimeWindowState {
48 pub open: bool,
50}
51
52pub fn frame_time_diagnostics_plugin(core: &mut SessionBuilder) {
55 core.stages
56 .add_system_to_stage(CoreStage::Last, frame_diagnostic_window);
57}
58
59pub fn frame_diagnostic_window(
62 mut state: Option<ResMut<FrameDiagState>>,
63 egui_ctx: ResMut<EguiCtx>,
65) {
66 let mut window_state = egui_ctx.get_state::<FrameTimeWindowState>();
67 let window_open = &mut window_state.open;
68
69 if *window_open {
70 egui::Window::new("Frame Diagnostics")
72 .id(egui::Id::new("frame_diagnostics"))
73 .default_width(500.0)
74 .open(window_open)
75 .show(&egui_ctx, |ui| {
76 if let Some(state) = state.as_mut() {
77 if ui.button("Reset Min/Max").clicked() {
79 state.reset();
80 }
81
82 ui.monospace(format!(
83 "{label:20}: {fps:4.0}{suffix:3} ( {min:4.0}{suffix:3}, {avg:4.0}{suffix:3}, {max:4.0}{suffix:3} )",
84 label = "Frames Per Second",
86 fps = state.fps,
87 suffix = "fps",
89 min = state.min_fps,
90 avg = state.fps_avg,
91 max = state.max_fps,
92 ));
93 ui.monospace(format!(
94 "{label:20}: {fps:4.1}{suffix:3} ( {min:4.1}{suffix:3}, {avg:4.0}{suffix:3}, {max:4.1}{suffix:3} )",
95 label = "Frame Time",
97 fps = state.frame_time,
98 suffix = "ms",
99 min = state.min_frame_time,
100 avg = state.frame_time_avg,
101 max = state.max_frame_time,
102 ));
103 }
104 else {
105 ui.monospace(
106 "No frame time data from Bevy diagnostics.",
107 );
108 }
109 });
110 }
111
112 egui_ctx.set_state(window_state);
113}