Skip to content

Commit f004789

Browse files
authored
Allow users to customize history length in FrameTimeDiagnosticsPlugin (#17259)
# Objective I have an application where I'd like to measure average frame rate over the entire life of the application, and it would be handy if I could just configure this on the existing `FrameTimeDiagnosticsPlugin`. Probably fixes #10948? ## Solution Add `max_history_length` to `FrameTimeDiagnosticsPlugin`, and because `smoothing_factor` seems to be based on history length, add that too. ## Discussion I'm not totally sure that `DEFAULT_MAX_HISTORY_LENGTH` is a great default for `FrameTimeDiagnosticsPlugin` (or any diagnostic?). That's 1/3 of a second at typical game frame rates. Moreover, the default print interval for `LogDiagnosticsPlugin` is 1 second. So when the two are combined, you are printing the average over the last third of the duration between now and the previous print, which seems a bit wonky. (related: #11429) I'm pretty sure this default value discussed and the current value wasn't totally arbitrary though. Maybe it would be nice for `Diagnostic` to have a `with_max_history_length_and_also_calculate_a_good_default_smoothing_factor` method? And then make an explicit smoothing factor in `FrameTimeDiagnosticsPlugin` optional? Or add a `new(max_history_length: usize)` method to `FrameTimeDiagnosticsPlugin` that sets a reasonable default `smoothing_factor`? edit: This one seems like a no-brainer, doing it. ## Alternatives It's really easy to roll your own `FrameTimeDiagnosticsPlugin`, but that might not be super interoperable with, for example, third party FPS overlays. Still, might be the right call. ## Testing `cargo run --example many_sprites` (modified to use a custom `max_history_length`) ## Migration Guide `FrameTimeDiagnosticsPlugin` now contains two fields. Use `FrameTimeDiagnosticsPlugin::default()` to match Bevy's previous behavior or, for example, `FrameTimeDiagnosticsPlugin::new(60)` to configure it.
1 parent bb0a82b commit f004789

20 files changed

+63
-26
lines changed

crates/bevy_dev_tools/src/fps_overlay.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl Plugin for FpsOverlayPlugin {
4242
fn build(&self, app: &mut bevy_app::App) {
4343
// TODO: Use plugin dependencies, see https://github.com/bevyengine/bevy/issues/69
4444
if !app.is_plugin_added::<FrameTimeDiagnosticsPlugin>() {
45-
app.add_plugins(FrameTimeDiagnosticsPlugin);
45+
app.add_plugins(FrameTimeDiagnosticsPlugin::default());
4646
}
4747
app.insert_resource(self.config.clone())
4848
.add_systems(Startup, setup)

crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::{Diagnostic, DiagnosticPath, Diagnostics, FrameCount, RegisterDiagnostic};
1+
use crate::{
2+
Diagnostic, DiagnosticPath, Diagnostics, FrameCount, RegisterDiagnostic,
3+
DEFAULT_MAX_HISTORY_LENGTH,
4+
};
25
use bevy_app::prelude::*;
36
use bevy_ecs::prelude::*;
47
use bevy_time::{Real, Time};
@@ -8,15 +11,49 @@ use bevy_time::{Real, Time};
811
/// # See also
912
///
1013
/// [`LogDiagnosticsPlugin`](crate::LogDiagnosticsPlugin) to output diagnostics to the console.
11-
#[derive(Default)]
12-
pub struct FrameTimeDiagnosticsPlugin;
14+
pub struct FrameTimeDiagnosticsPlugin {
15+
/// The total number of values to keep for averaging.
16+
pub max_history_length: usize,
17+
/// The smoothing factor for the exponential moving average. Usually `(history_length + 1.0) / 2.0)`.
18+
pub smoothing_factor: f64,
19+
}
20+
impl Default for FrameTimeDiagnosticsPlugin {
21+
fn default() -> Self {
22+
Self::new(DEFAULT_MAX_HISTORY_LENGTH)
23+
}
24+
}
25+
impl FrameTimeDiagnosticsPlugin {
26+
/// Creates a new `FrameTimeDiagnosticsPlugin` with the specified `max_history_length` and a
27+
/// reasonable `smoothing_factor`.
28+
pub fn new(max_history_length: usize) -> Self {
29+
Self {
30+
max_history_length,
31+
smoothing_factor: (max_history_length as f64 + 1.0) / 2.0,
32+
}
33+
}
34+
}
1335

1436
impl Plugin for FrameTimeDiagnosticsPlugin {
1537
fn build(&self, app: &mut App) {
16-
app.register_diagnostic(Diagnostic::new(Self::FRAME_TIME).with_suffix("ms"))
17-
.register_diagnostic(Diagnostic::new(Self::FPS))
18-
.register_diagnostic(Diagnostic::new(Self::FRAME_COUNT).with_smoothing_factor(0.0))
19-
.add_systems(Update, Self::diagnostic_system);
38+
app.register_diagnostic(
39+
Diagnostic::new(Self::FRAME_TIME)
40+
.with_suffix("ms")
41+
.with_max_history_length(self.max_history_length)
42+
.with_smoothing_factor(self.smoothing_factor),
43+
)
44+
.register_diagnostic(
45+
Diagnostic::new(Self::FPS)
46+
.with_max_history_length(self.max_history_length)
47+
.with_smoothing_factor(self.smoothing_factor),
48+
)
49+
// An average frame count would be nonsensical, so we set the max history length
50+
// to zero and disable smoothing.
51+
.register_diagnostic(
52+
Diagnostic::new(Self::FRAME_COUNT)
53+
.with_smoothing_factor(0.0)
54+
.with_max_history_length(0),
55+
)
56+
.add_systems(Update, Self::diagnostic_system);
2057
}
2158
}
2259

examples/diagnostics/enabling_disabling_diagnostic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() {
1212
App::new()
1313
.add_plugins((
1414
DefaultPlugins,
15-
FrameTimeDiagnosticsPlugin,
15+
FrameTimeDiagnosticsPlugin::default(),
1616
LogDiagnosticsPlugin::default(),
1717
))
1818
.add_systems(

examples/diagnostics/log_diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn main() {
1010
.add_plugins((
1111
DefaultPlugins,
1212
// Adds frame time diagnostics
13-
FrameTimeDiagnosticsPlugin,
13+
FrameTimeDiagnosticsPlugin::default(),
1414
// Adds a system that prints diagnostics to the console
1515
LogDiagnosticsPlugin::default(),
1616
// Any plugin can register diagnostics. Uncomment this to add an entity count diagnostics:

examples/stress_tests/bevymark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ fn main() {
142142
}),
143143
..default()
144144
}),
145-
FrameTimeDiagnosticsPlugin,
145+
FrameTimeDiagnosticsPlugin::default(),
146146
LogDiagnosticsPlugin::default(),
147147
))
148148
.insert_resource(WinitSettings {

examples/stress_tests/many_animated_sprites.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn main() {
2121
// Since this is also used as a benchmark, we want it to display performance data.
2222
.add_plugins((
2323
LogDiagnosticsPlugin::default(),
24-
FrameTimeDiagnosticsPlugin,
24+
FrameTimeDiagnosticsPlugin::default(),
2525
DefaultPlugins.set(WindowPlugin {
2626
primary_window: Some(Window {
2727
present_mode: PresentMode::AutoNoVsync,

examples/stress_tests/many_buttons.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn main() {
7373
}),
7474
..default()
7575
}),
76-
FrameTimeDiagnosticsPlugin,
76+
FrameTimeDiagnosticsPlugin::default(),
7777
LogDiagnosticsPlugin::default(),
7878
))
7979
.insert_resource(WinitSettings {

examples/stress_tests/many_components.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ fn stress_test(num_entities: u32, num_components: u32, num_systems: u32) {
146146
app.add_plugins(MinimalPlugins)
147147
.add_plugins(DiagnosticsPlugin)
148148
.add_plugins(LogPlugin::default())
149-
.add_plugins(FrameTimeDiagnosticsPlugin)
149+
.add_plugins(FrameTimeDiagnosticsPlugin::default())
150150
.add_plugins(LogDiagnosticsPlugin::filtered(vec![DiagnosticPath::new(
151151
"fps",
152152
)]));

examples/stress_tests/many_cubes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ fn main() {
111111
}),
112112
..default()
113113
}),
114-
FrameTimeDiagnosticsPlugin,
114+
FrameTimeDiagnosticsPlugin::default(),
115115
LogDiagnosticsPlugin::default(),
116116
))
117117
.insert_resource(WinitSettings {

examples/stress_tests/many_foxes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fn main() {
5151
}),
5252
..default()
5353
}),
54-
FrameTimeDiagnosticsPlugin,
54+
FrameTimeDiagnosticsPlugin::default(),
5555
LogDiagnosticsPlugin::default(),
5656
))
5757
.insert_resource(WinitSettings {

examples/stress_tests/many_gizmos.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() {
2323
}),
2424
..default()
2525
}),
26-
FrameTimeDiagnosticsPlugin,
26+
FrameTimeDiagnosticsPlugin::default(),
2727
LogDiagnosticsPlugin::default(),
2828
))
2929
.insert_resource(WinitSettings {

examples/stress_tests/many_glyphs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn main() {
4848
}),
4949
..default()
5050
}),
51-
FrameTimeDiagnosticsPlugin,
51+
FrameTimeDiagnosticsPlugin::default(),
5252
LogDiagnosticsPlugin::default(),
5353
))
5454
.insert_resource(WinitSettings {

examples/stress_tests/many_lights.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn main() {
2828
}),
2929
..default()
3030
}),
31-
FrameTimeDiagnosticsPlugin,
31+
FrameTimeDiagnosticsPlugin::default(),
3232
LogDiagnosticsPlugin::default(),
3333
LogVisibleLights,
3434
))

examples/stress_tests/many_sprites.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn main() {
3232
// Since this is also used as a benchmark, we want it to display performance data.
3333
.add_plugins((
3434
LogDiagnosticsPlugin::default(),
35-
FrameTimeDiagnosticsPlugin,
35+
FrameTimeDiagnosticsPlugin::default(),
3636
DefaultPlugins.set(WindowPlugin {
3737
primary_window: Some(Window {
3838
present_mode: PresentMode::AutoNoVsync,

examples/stress_tests/many_text2d.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ fn main() {
6666
let mut app = App::new();
6767

6868
app.add_plugins((
69-
FrameTimeDiagnosticsPlugin,
69+
FrameTimeDiagnosticsPlugin::default(),
7070
LogDiagnosticsPlugin::default(),
7171
DefaultPlugins.set(WindowPlugin {
7272
primary_window: Some(Window {

examples/stress_tests/text_pipeline.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() {
2323
}),
2424
..default()
2525
}),
26-
FrameTimeDiagnosticsPlugin,
26+
FrameTimeDiagnosticsPlugin::default(),
2727
LogDiagnosticsPlugin::default(),
2828
))
2929
.insert_resource(WinitSettings {

examples/stress_tests/transform_hierarchy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ fn main() {
193193
exit_condition: ExitCondition::DontExit,
194194
..default()
195195
}),
196-
FrameTimeDiagnosticsPlugin,
196+
FrameTimeDiagnosticsPlugin::default(),
197197
LogDiagnosticsPlugin::default(),
198198
))
199199
.add_systems(Startup, setup)

examples/ui/text.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use bevy::{
1111

1212
fn main() {
1313
App::new()
14-
.add_plugins((DefaultPlugins, FrameTimeDiagnosticsPlugin))
14+
.add_plugins((DefaultPlugins, FrameTimeDiagnosticsPlugin::default()))
1515
.add_systems(Startup, setup)
1616
.add_systems(Update, (text_update_system, text_color_system))
1717
.run();

examples/ui/text_debug.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn main() {
2020
}),
2121
..default()
2222
}),
23-
FrameTimeDiagnosticsPlugin,
23+
FrameTimeDiagnosticsPlugin::default(),
2424
))
2525
.add_systems(Startup, infotext_system)
2626
.add_systems(Update, change_text_system)

examples/window/window_settings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn main() {
3737
..default()
3838
}),
3939
LogDiagnosticsPlugin::default(),
40-
FrameTimeDiagnosticsPlugin,
40+
FrameTimeDiagnosticsPlugin::default(),
4141
))
4242
.add_systems(Startup, init_cursor_icons)
4343
.add_systems(

0 commit comments

Comments
 (0)