Path: blob/main/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs
6595 views
use crate::{1Diagnostic, DiagnosticPath, Diagnostics, FrameCount, RegisterDiagnostic,2DEFAULT_MAX_HISTORY_LENGTH,3};4use bevy_app::prelude::*;5use bevy_ecs::prelude::*;6use bevy_time::{Real, Time};78/// Adds "frame time" diagnostic to an App, specifically "frame time", "fps" and "frame count"9///10/// # See also11///12/// [`LogDiagnosticsPlugin`](crate::LogDiagnosticsPlugin) to output diagnostics to the console.13pub struct FrameTimeDiagnosticsPlugin {14/// The total number of values to keep for averaging.15pub max_history_length: usize,16/// The smoothing factor for the exponential moving average. Usually `2.0 / (history_length + 1.0)`.17pub smoothing_factor: f64,18}1920impl Default for FrameTimeDiagnosticsPlugin {21fn default() -> Self {22Self::new(DEFAULT_MAX_HISTORY_LENGTH)23}24}2526impl FrameTimeDiagnosticsPlugin {27/// Creates a new `FrameTimeDiagnosticsPlugin` with the specified `max_history_length` and a28/// reasonable `smoothing_factor`.29pub fn new(max_history_length: usize) -> Self {30Self {31max_history_length,32smoothing_factor: 2.0 / (max_history_length as f64 + 1.0),33}34}35}3637impl Plugin for FrameTimeDiagnosticsPlugin {38fn build(&self, app: &mut App) {39app.register_diagnostic(40Diagnostic::new(Self::FRAME_TIME)41.with_suffix("ms")42.with_max_history_length(self.max_history_length)43.with_smoothing_factor(self.smoothing_factor),44)45.register_diagnostic(46Diagnostic::new(Self::FPS)47.with_max_history_length(self.max_history_length)48.with_smoothing_factor(self.smoothing_factor),49)50// An average frame count would be nonsensical, so we set the max history length51// to zero and disable smoothing.52.register_diagnostic(53Diagnostic::new(Self::FRAME_COUNT)54.with_smoothing_factor(0.0)55.with_max_history_length(0),56)57.add_systems(Update, Self::diagnostic_system);58}59}6061impl FrameTimeDiagnosticsPlugin {62/// Frames per second.63pub const FPS: DiagnosticPath = DiagnosticPath::const_new("fps");6465/// Total frames since application start.66pub const FRAME_COUNT: DiagnosticPath = DiagnosticPath::const_new("frame_count");6768/// Frame time in ms.69pub const FRAME_TIME: DiagnosticPath = DiagnosticPath::const_new("frame_time");7071/// Updates frame count, frame time and fps measurements.72pub fn diagnostic_system(73mut diagnostics: Diagnostics,74time: Res<Time<Real>>,75frame_count: Res<FrameCount>,76) {77diagnostics.add_measurement(&Self::FRAME_COUNT, || frame_count.0 as f64);7879let delta_seconds = time.delta_secs_f64();80if delta_seconds == 0.0 {81return;82}8384diagnostics.add_measurement(&Self::FRAME_TIME, || delta_seconds * 1000.0);8586diagnostics.add_measurement(&Self::FPS, || 1.0 / delta_seconds);87}88}899091