diff --git a/crates/bevy_diagnostic/Cargo.toml b/crates/bevy_diagnostic/Cargo.toml index 034f04ddcd909..e82d08f22910b 100644 --- a/crates/bevy_diagnostic/Cargo.toml +++ b/crates/bevy_diagnostic/Cargo.toml @@ -21,6 +21,8 @@ bevy_log = { path = "../bevy_log", version = "0.12.0" } bevy_time = { path = "../bevy_time", version = "0.12.0" } bevy_utils = { path = "../bevy_utils", version = "0.12.0" } +const-fnv1a-hash = "1.1.0" + # MacOS [target.'cfg(all(target_os="macos"))'.dependencies] # Some features of sysinfo are not supported by apple. This will disable those features on apple devices diff --git a/crates/bevy_diagnostic/src/diagnostic.rs b/crates/bevy_diagnostic/src/diagnostic.rs index 1d01376f94b93..f3b0bb04c0934 100644 --- a/crates/bevy_diagnostic/src/diagnostic.rs +++ b/crates/bevy_diagnostic/src/diagnostic.rs @@ -1,24 +1,108 @@ +use std::hash::{Hash, Hasher}; +use std::{borrow::Cow, collections::VecDeque}; + use bevy_app::App; use bevy_ecs::system::{Deferred, Res, Resource, SystemBuffer, SystemParam}; -use bevy_log::warn; -use bevy_utils::{Duration, Instant, StableHashMap, Uuid}; -use std::{borrow::Cow, collections::VecDeque}; +use bevy_utils::{hashbrown::HashMap, Duration, Instant, PassHash}; +use const_fnv1a_hash::fnv1a_hash_str_64; + +use crate::DEFAULT_MAX_HISTORY_LENGTH; + +/// Unique diagnostic path, separated by `/`. +/// +/// Requirements: +/// - Can't be empty +/// - Can't have leading or trailing `/` +/// - Can't have empty components. +#[derive(Debug, Clone)] +pub struct DiagnosticPath { + path: Cow<'static, str>, + hash: u64, +} + +impl DiagnosticPath { + /// Create a new `DiagnosticPath`. Usable in const contexts. + /// + /// **Note**: path is not validated, so make sure it follows all the requirements. + pub const fn const_new(path: &'static str) -> DiagnosticPath { + DiagnosticPath { + path: Cow::Borrowed(path), + hash: fnv1a_hash_str_64(path), + } + } + + /// Create a new `DiagnosticPath` from the specified string. + pub fn new(path: impl Into>) -> DiagnosticPath { + let path = path.into(); + + debug_assert!(!path.is_empty(), "diagnostic path can't be empty"); + debug_assert!( + !path.starts_with('/'), + "diagnostic path can't be start with `/`" + ); + debug_assert!( + !path.ends_with('/'), + "diagnostic path can't be end with `/`" + ); + debug_assert!( + !path.contains("//"), + "diagnostic path can't contain empty components" + ); + + DiagnosticPath { + hash: fnv1a_hash_str_64(&path), + path, + } + } + + /// Create a new `DiagnosticPath` from an iterator over components. + pub fn from_components<'a>(components: impl IntoIterator) -> DiagnosticPath { + let mut buf = String::new(); + + for (i, component) in components.into_iter().enumerate() { + if i > 0 { + buf.push('/'); + } + buf.push_str(component); + } + + DiagnosticPath::new(buf) + } -use crate::MAX_DIAGNOSTIC_NAME_WIDTH; + /// Returns full path, joined by `/` + pub fn as_str(&self) -> &str { + &self.path + } -/// Unique identifier for a [`Diagnostic`]. -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)] -pub struct DiagnosticId(pub Uuid); + /// Returns an iterator over path components. + pub fn components(&self) -> impl Iterator + '_ { + self.path.split('/') + } +} -impl DiagnosticId { - pub const fn from_u128(value: u128) -> Self { - DiagnosticId(Uuid::from_u128(value)) +impl From for String { + fn from(path: DiagnosticPath) -> Self { + path.path.into() } } -impl Default for DiagnosticId { - fn default() -> Self { - DiagnosticId(Uuid::new_v4()) +impl Eq for DiagnosticPath {} + +impl PartialEq for DiagnosticPath { + fn eq(&self, other: &Self) -> bool { + self.hash == other.hash && self.path == other.path + } +} + +impl Hash for DiagnosticPath { + fn hash(&self, state: &mut H) { + state.write_u64(self.hash); + } +} + +impl std::fmt::Display for DiagnosticPath { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.path.fmt(f) } } @@ -33,8 +117,7 @@ pub struct DiagnosticMeasurement { /// Diagnostic examples: frames per second, CPU usage, network latency #[derive(Debug)] pub struct Diagnostic { - pub id: DiagnosticId, - pub name: Cow<'static, str>, + path: DiagnosticPath, pub suffix: Cow<'static, str>, history: VecDeque, sum: f64, @@ -71,27 +154,13 @@ impl Diagnostic { self.history.push_back(measurement); } - /// Create a new diagnostic with the given ID, name and maximum history. - pub fn new( - id: DiagnosticId, - name: impl Into>, - max_history_length: usize, - ) -> Diagnostic { - let name = name.into(); - if name.chars().count() > MAX_DIAGNOSTIC_NAME_WIDTH { - // This could be a false positive due to a unicode width being shorter - warn!( - "Diagnostic {:?} has name longer than {} characters, and so might overflow in the LogDiagnosticsPlugin\ - Consider using a shorter name.", - name, MAX_DIAGNOSTIC_NAME_WIDTH - ); - } + /// Create a new diagnostic with the given path. + pub fn new(path: DiagnosticPath) -> Diagnostic { Diagnostic { - id, - name, + path, suffix: Cow::Borrowed(""), - history: VecDeque::with_capacity(max_history_length), - max_history_length, + history: VecDeque::with_capacity(DEFAULT_MAX_HISTORY_LENGTH), + max_history_length: DEFAULT_MAX_HISTORY_LENGTH, sum: 0.0, ema: 0.0, ema_smoothing_factor: 2.0 / 21.0, @@ -99,6 +168,15 @@ impl Diagnostic { } } + /// Set the maximum history length. + #[must_use] + pub fn with_max_history_length(mut self, max_history_length: usize) -> Self { + self.max_history_length = max_history_length; + self.history.reserve(self.max_history_length); + self.history.shrink_to(self.max_history_length); + self + } + /// Add a suffix to use when logging the value, can be used to show a unit. #[must_use] pub fn with_suffix(mut self, suffix: impl Into>) -> Self { @@ -122,6 +200,10 @@ impl Diagnostic { self } + pub fn path(&self) -> &DiagnosticPath { + &self.path + } + /// Get the latest measurement from this diagnostic. #[inline] pub fn measurement(&self) -> Option<&DiagnosticMeasurement> { @@ -198,9 +280,7 @@ impl Diagnostic { /// A collection of [`Diagnostic`]s. #[derive(Debug, Default, Resource)] pub struct DiagnosticsStore { - // This uses a [`StableHashMap`] to ensure that the iteration order is deterministic between - // runs when all diagnostics are inserted in the same order. - diagnostics: StableHashMap, + diagnostics: HashMap, } impl DiagnosticsStore { @@ -208,21 +288,21 @@ impl DiagnosticsStore { /// /// If possible, prefer calling [`App::register_diagnostic`]. pub fn add(&mut self, diagnostic: Diagnostic) { - self.diagnostics.insert(diagnostic.id, diagnostic); + self.diagnostics.insert(diagnostic.path.clone(), diagnostic); } - pub fn get(&self, id: DiagnosticId) -> Option<&Diagnostic> { - self.diagnostics.get(&id) + pub fn get(&self, path: &DiagnosticPath) -> Option<&Diagnostic> { + self.diagnostics.get(path) } - pub fn get_mut(&mut self, id: DiagnosticId) -> Option<&mut Diagnostic> { - self.diagnostics.get_mut(&id) + pub fn get_mut(&mut self, path: &DiagnosticPath) -> Option<&mut Diagnostic> { + self.diagnostics.get_mut(path) } /// Get the latest [`DiagnosticMeasurement`] from an enabled [`Diagnostic`]. - pub fn get_measurement(&self, id: DiagnosticId) -> Option<&DiagnosticMeasurement> { + pub fn get_measurement(&self, path: &DiagnosticPath) -> Option<&DiagnosticMeasurement> { self.diagnostics - .get(&id) + .get(path) .filter(|diagnostic| diagnostic.is_enabled) .and_then(|diagnostic| diagnostic.measurement()) } @@ -249,13 +329,13 @@ impl<'w, 's> Diagnostics<'w, 's> { /// Add a measurement to an enabled [`Diagnostic`]. The measurement is passed as a function so that /// it will be evaluated only if the [`Diagnostic`] is enabled. This can be useful if the value is /// costly to calculate. - pub fn add_measurement(&mut self, id: DiagnosticId, value: F) + pub fn add_measurement(&mut self, path: &DiagnosticPath, value: F) where F: FnOnce() -> f64, { if self .store - .get(id) + .get(path) .filter(|diagnostic| diagnostic.is_enabled) .is_some() { @@ -263,13 +343,13 @@ impl<'w, 's> Diagnostics<'w, 's> { time: Instant::now(), value: value(), }; - self.queue.0.insert(id, measurement); + self.queue.0.insert(path.clone(), measurement); } } } #[derive(Default)] -struct DiagnosticsBuffer(StableHashMap); +struct DiagnosticsBuffer(HashMap); impl SystemBuffer for DiagnosticsBuffer { fn apply( @@ -278,8 +358,8 @@ impl SystemBuffer for DiagnosticsBuffer { world: &mut bevy_ecs::world::World, ) { let mut diagnostics = world.resource_mut::(); - for (id, measurement) in self.0.drain() { - if let Some(diagnostic) = diagnostics.get_mut(id) { + for (path, measurement) in self.0.drain() { + if let Some(diagnostic) = diagnostics.get_mut(&path) { diagnostic.add_measurement(measurement); } } @@ -298,12 +378,12 @@ impl RegisterDiagnostic for App { /// /// ``` /// use bevy_app::App; - /// use bevy_diagnostic::{Diagnostic, DiagnosticsPlugin, DiagnosticId, RegisterDiagnostic}; + /// use bevy_diagnostic::{Diagnostic, DiagnosticsPlugin, DiagnosticPath, RegisterDiagnostic}; /// - /// const UNIQUE_DIAG_ID: DiagnosticId = DiagnosticId::from_u128(42); + /// const UNIQUE_DIAG_PATH: DiagnosticPath = DiagnosticPath::const_new("foo/bar"); /// /// App::new() - /// .register_diagnostic(Diagnostic::new(UNIQUE_DIAG_ID, "example", 10)) + /// .register_diagnostic(Diagnostic::new(UNIQUE_DIAG_PATH)) /// .add_plugins(DiagnosticsPlugin) /// .run(); /// ``` diff --git a/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs index 6c501986b350a..91874a390c0f6 100644 --- a/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs @@ -1,7 +1,7 @@ use bevy_app::prelude::*; use bevy_ecs::entity::Entities; -use crate::{Diagnostic, DiagnosticId, Diagnostics, RegisterDiagnostic}; +use crate::{Diagnostic, DiagnosticPath, Diagnostics, RegisterDiagnostic}; /// Adds "entity count" diagnostic to an App. /// @@ -13,16 +13,15 @@ pub struct EntityCountDiagnosticsPlugin; impl Plugin for EntityCountDiagnosticsPlugin { fn build(&self, app: &mut App) { - app.register_diagnostic(Diagnostic::new(Self::ENTITY_COUNT, "entity_count", 20)) + app.register_diagnostic(Diagnostic::new(Self::ENTITY_COUNT)) .add_systems(Update, Self::diagnostic_system); } } impl EntityCountDiagnosticsPlugin { - pub const ENTITY_COUNT: DiagnosticId = - DiagnosticId::from_u128(187513512115068938494459732780662867798); + pub const ENTITY_COUNT: DiagnosticPath = DiagnosticPath::const_new("entity_count"); pub fn diagnostic_system(mut diagnostics: Diagnostics, entities: &Entities) { - diagnostics.add_measurement(Self::ENTITY_COUNT, || entities.len() as f64); + diagnostics.add_measurement(&Self::ENTITY_COUNT, || entities.len() as f64); } } diff --git a/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs index b5a8625821004..3586960443414 100644 --- a/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs @@ -1,4 +1,4 @@ -use crate::{Diagnostic, DiagnosticId, Diagnostics, RegisterDiagnostic}; +use crate::{Diagnostic, DiagnosticPath, Diagnostics, RegisterDiagnostic}; use bevy_app::prelude::*; use bevy_core::FrameCount; use bevy_ecs::prelude::*; @@ -13,39 +13,33 @@ use bevy_time::{Real, Time}; pub struct FrameTimeDiagnosticsPlugin; impl Plugin for FrameTimeDiagnosticsPlugin { - fn build(&self, app: &mut App) { - app.register_diagnostic( - Diagnostic::new(Self::FRAME_TIME, "frame_time", 20).with_suffix("ms"), - ) - .register_diagnostic(Diagnostic::new(Self::FPS, "fps", 20)) - .register_diagnostic( - Diagnostic::new(Self::FRAME_COUNT, "frame_count", 1).with_smoothing_factor(0.0), - ) - .add_systems(Update, Self::diagnostic_system); + fn build(&self, app: &mut bevy_app::App) { + app.register_diagnostic(Diagnostic::new(Self::FRAME_TIME).with_suffix("ms")) + .register_diagnostic(Diagnostic::new(Self::FPS)) + .register_diagnostic(Diagnostic::new(Self::FRAME_COUNT).with_smoothing_factor(0.0)) + .add_systems(Update, Self::diagnostic_system); } } impl FrameTimeDiagnosticsPlugin { - pub const FPS: DiagnosticId = DiagnosticId::from_u128(288146834822086093791974408528866909483); - pub const FRAME_COUNT: DiagnosticId = - DiagnosticId::from_u128(54021991829115352065418785002088010277); - pub const FRAME_TIME: DiagnosticId = - DiagnosticId::from_u128(73441630925388532774622109383099159699); + pub const FPS: DiagnosticPath = DiagnosticPath::const_new("fps"); + pub const FRAME_COUNT: DiagnosticPath = DiagnosticPath::const_new("frame_count"); + pub const FRAME_TIME: DiagnosticPath = DiagnosticPath::const_new("frame_time"); pub fn diagnostic_system( mut diagnostics: Diagnostics, time: Res>, frame_count: Res, ) { - diagnostics.add_measurement(Self::FRAME_COUNT, || frame_count.0 as f64); + diagnostics.add_measurement(&Self::FRAME_COUNT, || frame_count.0 as f64); let delta_seconds = time.delta_seconds_f64(); if delta_seconds == 0.0 { return; } - diagnostics.add_measurement(Self::FRAME_TIME, || delta_seconds * 1000.0); + diagnostics.add_measurement(&Self::FRAME_TIME, || delta_seconds * 1000.0); - diagnostics.add_measurement(Self::FPS, || 1.0 / delta_seconds); + diagnostics.add_measurement(&Self::FPS, || 1.0 / delta_seconds); } } diff --git a/crates/bevy_diagnostic/src/lib.rs b/crates/bevy_diagnostic/src/lib.rs index bca1f9433c241..e16360a2d4962 100644 --- a/crates/bevy_diagnostic/src/lib.rs +++ b/crates/bevy_diagnostic/src/lib.rs @@ -28,6 +28,5 @@ impl Plugin for DiagnosticsPlugin { } } -/// The width which diagnostic names will be printed as -/// Plugin names should not be longer than this value -pub const MAX_DIAGNOSTIC_NAME_WIDTH: usize = 32; +/// Default max history length for new diagnostics. +pub const DEFAULT_MAX_HISTORY_LENGTH: usize = 120; diff --git a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs index 7c24811869040..f3f57683086c1 100644 --- a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs @@ -1,4 +1,4 @@ -use super::{Diagnostic, DiagnosticId, DiagnosticsStore}; +use super::{Diagnostic, DiagnosticPath, DiagnosticsStore}; use bevy_app::prelude::*; use bevy_ecs::prelude::*; use bevy_log::{debug, info}; @@ -15,14 +15,14 @@ use bevy_utils::Duration; pub struct LogDiagnosticsPlugin { pub debug: bool, pub wait_duration: Duration, - pub filter: Option>, + pub filter: Option>, } /// State used by the [`LogDiagnosticsPlugin`] #[derive(Resource)] struct LogDiagnosticsState { timer: Timer, - filter: Option>, + filter: Option>, } impl Default for LogDiagnosticsPlugin { @@ -51,63 +51,84 @@ impl Plugin for LogDiagnosticsPlugin { } impl LogDiagnosticsPlugin { - pub fn filtered(filter: Vec) -> Self { + pub fn filtered(filter: Vec) -> Self { LogDiagnosticsPlugin { filter: Some(filter), ..Default::default() } } - fn log_diagnostic(diagnostic: &Diagnostic) { - if let Some(value) = diagnostic.smoothed() { - if diagnostic.get_max_history_length() > 1 { - if let Some(average) = diagnostic.average() { - info!( - target: "bevy diagnostic", - // Suffix is only used for 's' or 'ms' currently, - // so we reserve two columns for it; however, - // Do not reserve columns for the suffix in the average - // The ) hugging the value is more aesthetically pleasing - "{name:11.6}{suffix:2} (avg {average:>.6}{suffix:})", - name = diagnostic.name, - suffix = diagnostic.suffix, - name_width = crate::MAX_DIAGNOSTIC_NAME_WIDTH, - ); - return; + fn for_each_diagnostic( + state: &LogDiagnosticsState, + diagnostics: &DiagnosticsStore, + mut callback: impl FnMut(&Diagnostic), + ) { + if let Some(filter) = &state.filter { + for path in filter { + if let Some(diagnostic) = diagnostics.get(path) { + if diagnostic.is_enabled { + callback(diagnostic); + } + } + } + } else { + for diagnostic in diagnostics.iter() { + if diagnostic.is_enabled { + callback(diagnostic); } } + } + } + + fn log_diagnostic(path_width: usize, diagnostic: &Diagnostic) { + let Some(value) = diagnostic.smoothed() else { + return; + }; + + if diagnostic.get_max_history_length() > 1 { + let Some(average) = diagnostic.average() else { + return; + }; + info!( target: "bevy diagnostic", - "{name:.6}{suffix:}", - name = diagnostic.name, + // Suffix is only used for 's' or 'ms' currently, + // so we reserve two columns for it; however, + // Do not reserve columns for the suffix in the average + // The ) hugging the value is more aesthetically pleasing + "{path:11.6}{suffix:2} (avg {average:>.6}{suffix:})", + path = diagnostic.path(), + suffix = diagnostic.suffix, + ); + } else { + info!( + target: "bevy diagnostic", + "{path:.6}{suffix:}", + path = diagnostic.path(), suffix = diagnostic.suffix, - name_width = crate::MAX_DIAGNOSTIC_NAME_WIDTH, ); } } + fn log_diagnostics(state: &LogDiagnosticsState, diagnostics: &DiagnosticsStore) { + let mut path_width = 0; + Self::for_each_diagnostic(state, diagnostics, |diagnostic| { + let width = diagnostic.path().as_str().len(); + path_width = path_width.max(width); + }); + + Self::for_each_diagnostic(state, diagnostics, |diagnostic| { + Self::log_diagnostic(path_width, diagnostic); + }); + } + fn log_diagnostics_system( mut state: ResMut, time: Res>, diagnostics: Res, ) { if state.timer.tick(time.delta()).finished() { - if let Some(ref filter) = state.filter { - for diagnostic in filter.iter().flat_map(|id| { - diagnostics - .get(*id) - .filter(|diagnostic| diagnostic.is_enabled) - }) { - Self::log_diagnostic(diagnostic); - } - } else { - for diagnostic in diagnostics - .iter() - .filter(|diagnostic| diagnostic.is_enabled) - { - Self::log_diagnostic(diagnostic); - } - } + Self::log_diagnostics(&state, &diagnostics); } } @@ -117,22 +138,9 @@ impl LogDiagnosticsPlugin { diagnostics: Res, ) { if state.timer.tick(time.delta()).finished() { - if let Some(ref filter) = state.filter { - for diagnostic in filter.iter().flat_map(|id| { - diagnostics - .get(*id) - .filter(|diagnostic| diagnostic.is_enabled) - }) { - debug!("{:#?}\n", diagnostic); - } - } else { - for diagnostic in diagnostics - .iter() - .filter(|diagnostic| diagnostic.is_enabled) - { - debug!("{:#?}\n", diagnostic); - } - } + Self::for_each_diagnostic(&state, &diagnostics, |diagnostic| { + debug!("{:#?}\n", diagnostic); + }); } } } diff --git a/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs index c0265f48972ed..e8c88a2f5a91e 100644 --- a/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs @@ -1,4 +1,4 @@ -use crate::DiagnosticId; +use crate::DiagnosticPath; use bevy_app::prelude::*; /// Adds a System Information Diagnostic, specifically `cpu_usage` (in %) and `mem_usage` (in %) @@ -24,10 +24,8 @@ impl Plugin for SystemInformationDiagnosticsPlugin { } impl SystemInformationDiagnosticsPlugin { - pub const CPU_USAGE: DiagnosticId = - DiagnosticId::from_u128(78494871623549551581510633532637320956); - pub const MEM_USAGE: DiagnosticId = - DiagnosticId::from_u128(42846254859293759601295317811892519825); + pub const CPU_USAGE: DiagnosticPath = DiagnosticPath::const_new("system/cpu_usage"); + pub const MEM_USAGE: DiagnosticPath = DiagnosticPath::const_new("system/mem_usage"); } // NOTE: sysinfo fails to compile when using bevy dynamic or on iOS and does nothing on wasm @@ -47,25 +45,15 @@ pub mod internal { use crate::{Diagnostic, Diagnostics, DiagnosticsStore}; + use super::SystemInformationDiagnosticsPlugin; + const BYTES_TO_GIB: f64 = 1.0 / 1024.0 / 1024.0 / 1024.0; pub(crate) fn setup_system(mut diagnostics: ResMut) { - diagnostics.add( - Diagnostic::new( - super::SystemInformationDiagnosticsPlugin::CPU_USAGE, - "cpu_usage", - 20, - ) - .with_suffix("%"), - ); - diagnostics.add( - Diagnostic::new( - super::SystemInformationDiagnosticsPlugin::MEM_USAGE, - "mem_usage", - 20, - ) - .with_suffix("%"), - ); + diagnostics + .add(Diagnostic::new(SystemInformationDiagnosticsPlugin::CPU_USAGE).with_suffix("%")); + diagnostics + .add(Diagnostic::new(SystemInformationDiagnosticsPlugin::MEM_USAGE).with_suffix("%")); } pub(crate) fn diagnostic_system( @@ -91,10 +79,10 @@ pub mod internal { let used_mem = sys.used_memory() as f64 / BYTES_TO_GIB; let current_used_mem = used_mem / total_mem * 100.0; - diagnostics.add_measurement(super::SystemInformationDiagnosticsPlugin::CPU_USAGE, || { + diagnostics.add_measurement(&SystemInformationDiagnosticsPlugin::CPU_USAGE, || { current_cpu_usage as f64 }); - diagnostics.add_measurement(super::SystemInformationDiagnosticsPlugin::MEM_USAGE, || { + diagnostics.add_measurement(&SystemInformationDiagnosticsPlugin::MEM_USAGE, || { current_used_mem }); } diff --git a/examples/diagnostics/custom_diagnostic.rs b/examples/diagnostics/custom_diagnostic.rs index 60bf0342920fc..062632a0af7d7 100644 --- a/examples/diagnostics/custom_diagnostic.rs +++ b/examples/diagnostics/custom_diagnostic.rs @@ -1,7 +1,9 @@ //! This example illustrates how to create a custom diagnostic. use bevy::{ - diagnostic::{Diagnostic, DiagnosticId, Diagnostics, LogDiagnosticsPlugin, RegisterDiagnostic}, + diagnostic::{ + Diagnostic, DiagnosticPath, Diagnostics, LogDiagnosticsPlugin, RegisterDiagnostic, + }, prelude::*, }; @@ -14,20 +16,16 @@ fn main() { LogDiagnosticsPlugin::default(), )) // Diagnostics must be initialized before measurements can be added. - .register_diagnostic( - Diagnostic::new(SYSTEM_ITERATION_COUNT, "system_iteration_count", 10) - .with_suffix(" iterations"), - ) + .register_diagnostic(Diagnostic::new(SYSTEM_ITERATION_COUNT).with_suffix(" iterations")) .add_systems(Update, my_system) .run(); } -// All diagnostics should have a unique DiagnosticId. -// For each new diagnostic, generate a new random number. -pub const SYSTEM_ITERATION_COUNT: DiagnosticId = - DiagnosticId::from_u128(337040787172757619024841343456040760896); +// All diagnostics should have a unique DiagnosticPath. +pub const SYSTEM_ITERATION_COUNT: DiagnosticPath = + DiagnosticPath::const_new("system_iteration_count"); fn my_system(mut diagnostics: Diagnostics) { // Add a measurement of 10.0 for our diagnostic each time this system runs. - diagnostics.add_measurement(SYSTEM_ITERATION_COUNT, || 10.0); + diagnostics.add_measurement(&SYSTEM_ITERATION_COUNT, || 10.0); } diff --git a/examples/stress_tests/bevymark.rs b/examples/stress_tests/bevymark.rs index c59f2047e0c21..02278e6610ad9 100644 --- a/examples/stress_tests/bevymark.rs +++ b/examples/stress_tests/bevymark.rs @@ -517,7 +517,7 @@ fn counter_system( text.sections[1].value = counter.count.to_string(); } - if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) { + if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) { if let Some(raw) = fps.value() { text.sections[3].value = format!("{raw:.2}"); } diff --git a/examples/stress_tests/many_gizmos.rs b/examples/stress_tests/many_gizmos.rs index 20296f9f91ae4..08b64317eb1c6 100644 --- a/examples/stress_tests/many_gizmos.rs +++ b/examples/stress_tests/many_gizmos.rs @@ -93,7 +93,7 @@ fn ui_system(mut query: Query<&mut Text>, config: Res, diag: Res>, ) { for mut text in &mut query { - if let Some(fps) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) { + if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) { if let Some(value) = fps.smoothed() { // Update the value of the second section text.sections[1].value = format!("{value:.2}"); diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index e9dd0869f09ed..f0414a560a007 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -197,14 +197,15 @@ fn change_text_system( ) { for mut text in &mut query { let mut fps = 0.0; - if let Some(fps_diagnostic) = diagnostics.get(FrameTimeDiagnosticsPlugin::FPS) { + if let Some(fps_diagnostic) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) { if let Some(fps_smoothed) = fps_diagnostic.smoothed() { fps = fps_smoothed; } } let mut frame_time = time.delta_seconds_f64(); - if let Some(frame_time_diagnostic) = diagnostics.get(FrameTimeDiagnosticsPlugin::FRAME_TIME) + if let Some(frame_time_diagnostic) = + diagnostics.get(&FrameTimeDiagnosticsPlugin::FRAME_TIME) { if let Some(frame_time_smoothed) = frame_time_diagnostic.smoothed() { frame_time = frame_time_smoothed;