Skip to content

Commit b28365f

Browse files
authored
updates on diagnostics (log + new diagnostics) (#1085)
* move print diagnostics to log * entity count diagnostic * asset count diagnostic * remove useless `pub`s * use `BTreeMap` instead of `HashMap` * get entity count from world * keep ordered list of diagnostics
1 parent d3d6c35 commit b28365f

File tree

17 files changed

+144
-45
lines changed

17 files changed

+144
-45
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ name = "custom_diagnostic"
191191
path = "examples/diagnostics/custom_diagnostic.rs"
192192

193193
[[example]]
194-
name = "print_diagnostics"
195-
path = "examples/diagnostics/print_diagnostics.rs"
194+
name = "log_diagnostics"
195+
path = "examples/diagnostics/log_diagnostics.rs"
196196

197197
[[example]]
198198
name = "event"

crates/bevy_asset/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ filesystem_watcher = ["notify"]
1919
[dependencies]
2020
# bevy
2121
bevy_app = { path = "../bevy_app", version = "0.4.0" }
22+
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.4.0" }
2223
bevy_ecs = { path = "../bevy_ecs", version = "0.4.0" }
2324
bevy_reflect = { path = "../bevy_reflect", version = "0.4.0", features = ["bevy"] }
2425
bevy_tasks = { path = "../bevy_tasks", version = "0.4.0" }
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::{Asset, Assets};
2+
use bevy_app::prelude::*;
3+
use bevy_diagnostic::{Diagnostic, DiagnosticId, Diagnostics};
4+
use bevy_ecs::{IntoSystem, Res, ResMut};
5+
6+
/// Adds "asset count" diagnostic to an App
7+
#[derive(Default)]
8+
pub struct AssetCountDiagnosticsPlugin<T: Asset> {
9+
marker: std::marker::PhantomData<T>,
10+
}
11+
12+
impl<T: Asset> Plugin for AssetCountDiagnosticsPlugin<T> {
13+
fn build(&self, app: &mut AppBuilder) {
14+
app.add_startup_system(Self::setup_system.system())
15+
.add_system(Self::diagnostic_system.system());
16+
}
17+
}
18+
19+
impl<T: Asset> AssetCountDiagnosticsPlugin<T> {
20+
pub fn diagnostic_id() -> DiagnosticId {
21+
DiagnosticId(T::TYPE_UUID)
22+
}
23+
24+
pub fn setup_system(mut diagnostics: ResMut<Diagnostics>) {
25+
diagnostics.add(Diagnostic::new(
26+
Self::diagnostic_id(),
27+
&format!("asset_count {}", std::any::type_name::<T>()),
28+
20,
29+
));
30+
}
31+
32+
pub fn diagnostic_system(mut diagnostics: ResMut<Diagnostics>, assets: Res<Assets<T>>) {
33+
diagnostics.add_measurement(Self::diagnostic_id(), assets.len() as f64);
34+
}
35+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mod asset_count_diagnostics_plugin;
2+
pub use asset_count_diagnostics_plugin::AssetCountDiagnosticsPlugin;

crates/bevy_asset/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod asset_server;
22
mod assets;
3+
pub mod diagnostic;
34
#[cfg(all(
45
feature = "filesystem_watcher",
56
all(not(target_arch = "wasm32"), not(target_os = "android"))

crates/bevy_diagnostic/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ keywords = ["bevy"]
1818
bevy_app = { path = "../bevy_app", version = "0.4.0" }
1919
bevy_core = { path = "../bevy_core", version = "0.4.0" }
2020
bevy_ecs = { path = "../bevy_ecs", version = "0.4.0" }
21+
bevy_log = { path = "../bevy_log", version = "0.4.0" }
2122
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
2223

2324
# other

crates/bevy_diagnostic/src/diagnostic.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use bevy_utils::{Duration, HashMap, Instant, Uuid};
2-
use std::collections::VecDeque;
2+
use std::collections::{BTreeSet, VecDeque};
33

44
/// Unique identifier for a [Diagnostic]
5-
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
5+
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
66
pub struct DiagnosticId(pub Uuid);
77

88
impl DiagnosticId {
@@ -102,10 +102,12 @@ impl Diagnostic {
102102
#[derive(Debug, Default)]
103103
pub struct Diagnostics {
104104
diagnostics: HashMap<DiagnosticId, Diagnostic>,
105+
ordered_diagnostics: BTreeSet<DiagnosticId>,
105106
}
106107

107108
impl Diagnostics {
108109
pub fn add(&mut self, diagnostic: Diagnostic) {
110+
self.ordered_diagnostics.insert(diagnostic.id);
109111
self.diagnostics.insert(diagnostic.id, diagnostic);
110112
}
111113

@@ -132,4 +134,10 @@ impl Diagnostics {
132134
pub fn iter(&self) -> impl Iterator<Item = &Diagnostic> {
133135
self.diagnostics.values()
134136
}
137+
138+
pub fn ordered_iter(&self) -> impl Iterator<Item = &Diagnostic> {
139+
self.ordered_diagnostics
140+
.iter()
141+
.filter_map(move |k| self.diagnostics.get(k))
142+
}
135143
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use crate::{Diagnostic, DiagnosticId, Diagnostics};
2+
use bevy_app::prelude::*;
3+
use bevy_ecs::{IntoSystem, ResMut, Resources, World};
4+
5+
/// Adds "entity count" diagnostic to an App
6+
#[derive(Default)]
7+
pub struct EntityCountDiagnosticsPlugin;
8+
9+
impl Plugin for EntityCountDiagnosticsPlugin {
10+
fn build(&self, app: &mut AppBuilder) {
11+
app.add_startup_system(Self::setup_system.system())
12+
.add_system(Self::diagnostic_system.system());
13+
}
14+
}
15+
16+
impl EntityCountDiagnosticsPlugin {
17+
pub const ENTITY_COUNT: DiagnosticId =
18+
DiagnosticId::from_u128(187513512115068938494459732780662867798);
19+
20+
pub fn setup_system(mut diagnostics: ResMut<Diagnostics>) {
21+
diagnostics.add(Diagnostic::new(Self::ENTITY_COUNT, "entity_count", 20));
22+
}
23+
24+
pub fn diagnostic_system(world: &mut World, resources: &mut Resources) {
25+
if let Some(mut diagnostics) = resources.get_mut::<Diagnostics>() {
26+
diagnostics.add_measurement(Self::ENTITY_COUNT, world.entity_count() as f64);
27+
}
28+
}
29+
}

crates/bevy_diagnostic/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
mod diagnostic;
2+
mod entity_count_diagnostics_plugin;
23
mod frame_time_diagnostics_plugin;
3-
mod print_diagnostics_plugin;
4+
mod log_diagnostics_plugin;
45
pub use diagnostic::*;
6+
pub use entity_count_diagnostics_plugin::EntityCountDiagnosticsPlugin;
57
pub use frame_time_diagnostics_plugin::FrameTimeDiagnosticsPlugin;
6-
pub use print_diagnostics_plugin::PrintDiagnosticsPlugin;
8+
pub use log_diagnostics_plugin::LogDiagnosticsPlugin;
79

810
use bevy_app::prelude::*;
911

crates/bevy_diagnostic/src/print_diagnostics_plugin.rs renamed to crates/bevy_diagnostic/src/log_diagnostics_plugin.rs

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,103 +2,102 @@ use super::{Diagnostic, DiagnosticId, Diagnostics};
22
use bevy_app::prelude::*;
33
use bevy_core::{Time, Timer};
44
use bevy_ecs::{IntoSystem, Res, ResMut};
5+
use bevy_log::{debug, info};
56
use bevy_utils::Duration;
67

7-
/// An App Plugin that prints diagnostics to the console
8-
pub struct PrintDiagnosticsPlugin {
8+
/// An App Plugin that logs diagnostics to the console
9+
pub struct LogDiagnosticsPlugin {
910
pub debug: bool,
1011
pub wait_duration: Duration,
1112
pub filter: Option<Vec<DiagnosticId>>,
1213
}
1314

14-
/// State used by the [PrintDiagnosticsPlugin]
15-
pub struct PrintDiagnosticsState {
15+
/// State used by the [LogDiagnosticsPlugin]
16+
struct LogDiagnosticsState {
1617
timer: Timer,
1718
filter: Option<Vec<DiagnosticId>>,
1819
}
1920

20-
impl Default for PrintDiagnosticsPlugin {
21+
impl Default for LogDiagnosticsPlugin {
2122
fn default() -> Self {
22-
PrintDiagnosticsPlugin {
23+
LogDiagnosticsPlugin {
2324
debug: false,
2425
wait_duration: Duration::from_secs(1),
2526
filter: None,
2627
}
2728
}
2829
}
2930

30-
impl Plugin for PrintDiagnosticsPlugin {
31+
impl Plugin for LogDiagnosticsPlugin {
3132
fn build(&self, app: &mut bevy_app::AppBuilder) {
32-
app.add_resource(PrintDiagnosticsState {
33+
app.add_resource(LogDiagnosticsState {
3334
timer: Timer::new(self.wait_duration, true),
3435
filter: self.filter.clone(),
3536
});
3637

3738
if self.debug {
3839
app.add_system_to_stage(
3940
stage::POST_UPDATE,
40-
Self::print_diagnostics_debug_system.system(),
41+
Self::log_diagnostics_debug_system.system(),
4142
);
4243
} else {
43-
app.add_system_to_stage(stage::POST_UPDATE, Self::print_diagnostics_system.system());
44+
app.add_system_to_stage(stage::POST_UPDATE, Self::log_diagnostics_system.system());
4445
}
4546
}
4647
}
4748

48-
impl PrintDiagnosticsPlugin {
49+
impl LogDiagnosticsPlugin {
4950
pub fn filtered(filter: Vec<DiagnosticId>) -> Self {
50-
PrintDiagnosticsPlugin {
51+
LogDiagnosticsPlugin {
5152
filter: Some(filter),
5253
..Default::default()
5354
}
5455
}
5556

56-
fn print_diagnostic(diagnostic: &Diagnostic) {
57+
fn log_diagnostic(diagnostic: &Diagnostic) {
5758
if let Some(value) = diagnostic.value() {
58-
print!("{:<65}: {:<10.6}", diagnostic.name, value);
5959
if let Some(average) = diagnostic.average() {
60-
print!(" (avg {:.6})", average);
60+
info!(
61+
"{:<65}: {:<10.6} (avg {:.6})",
62+
diagnostic.name, value, average
63+
);
64+
} else {
65+
info!("{:<65}: {:<10.6}", diagnostic.name, value);
6166
}
62-
63-
println!("\n");
6467
}
6568
}
6669

67-
pub fn print_diagnostics_system(
68-
mut state: ResMut<PrintDiagnosticsState>,
70+
fn log_diagnostics_system(
71+
mut state: ResMut<LogDiagnosticsState>,
6972
time: Res<Time>,
7073
diagnostics: Res<Diagnostics>,
7174
) {
7275
if state.timer.tick(time.delta_seconds()).finished() {
73-
println!("Diagnostics:");
74-
println!("{}", "-".repeat(93));
7576
if let Some(ref filter) = state.filter {
7677
for diagnostic in filter.iter().map(|id| diagnostics.get(*id).unwrap()) {
77-
Self::print_diagnostic(diagnostic);
78+
Self::log_diagnostic(diagnostic);
7879
}
7980
} else {
80-
for diagnostic in diagnostics.iter() {
81-
Self::print_diagnostic(diagnostic);
81+
for diagnostic in diagnostics.ordered_iter() {
82+
Self::log_diagnostic(diagnostic);
8283
}
8384
}
8485
}
8586
}
8687

87-
pub fn print_diagnostics_debug_system(
88-
mut state: ResMut<PrintDiagnosticsState>,
88+
fn log_diagnostics_debug_system(
89+
mut state: ResMut<LogDiagnosticsState>,
8990
time: Res<Time>,
9091
diagnostics: Res<Diagnostics>,
9192
) {
9293
if state.timer.tick(time.delta_seconds()).finished() {
93-
println!("Diagnostics (Debug):");
94-
println!("{}", "-".repeat(93));
9594
if let Some(ref filter) = state.filter {
9695
for diagnostic in filter.iter().map(|id| diagnostics.get(*id).unwrap()) {
97-
println!("{:#?}\n", diagnostic);
96+
debug!("{:#?}\n", diagnostic);
9897
}
9998
} else {
100-
for diagnostic in diagnostics.iter() {
101-
println!("{:#?}\n", diagnostic);
99+
for diagnostic in diagnostics.ordered_iter() {
100+
debug!("{:#?}\n", diagnostic);
102101
}
103102
}
104103
}

0 commit comments

Comments
 (0)