Skip to content

Commit

Permalink
Add bevy_framepace to control the framerate in the demos
Browse files Browse the repository at this point in the history
  • Loading branch information
idanarye committed Jun 28, 2024
1 parent 17c4ec5 commit d9a6c09
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 18 deletions.
8 changes: 6 additions & 2 deletions demos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ exclude = [

[features]
default = [
# Comment this out when Bevy gets upgraded and bevy_egui lags behind
"egui",
"bevy_xpbd_3d?/parry-f32",
"bevy_xpbd_2d?/parry-f32",
# Comment these out when Bevy gets upgraded and a dependency lags behind
"egui",
"framepace",
]
egui = ["dep:bevy_egui", "dep:egui_plot", "dep:egui_extras"]
framepace = ["dep:bevy_framepace"]
rapier = []
rapier2d = ["rapier", "dep:bevy_rapier2d", "dep:bevy-tnua-rapier2d"]
rapier3d = ["rapier", "dep:bevy_rapier3d", "dep:bevy-tnua-rapier3d"]
Expand Down Expand Up @@ -63,6 +65,8 @@ bevy_egui = { version = "0.27", optional = true, default-features = false, featu
egui_plot = { version = "0.27", optional = true }
egui_extras = { version = "0.27", optional = true }

bevy_framepace = { version = "0.16.0", optional = true }

clap = { version = "^4", features = ["derive"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down
112 changes: 112 additions & 0 deletions demos/src/ui/framerate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use bevy::{
diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin},
ecs::system::SystemParam,
prelude::*,
};
use bevy_egui::egui;
#[cfg(feature = "framepace")]
use bevy_framepace::{
debug::DiagnosticsPlugin as FramepaceDiagnosticsPlugin, FramepacePlugin, FramepaceSettings,
Limiter,
};

pub struct DemoFrameratePlugin;

impl Plugin for DemoFrameratePlugin {
fn build(&self, app: &mut App) {
app.add_plugins(FrameTimeDiagnosticsPlugin);

#[cfg(feature = "framepace")]
{
app.add_plugins((FramepacePlugin, FramepaceDiagnosticsPlugin));
app.insert_resource(FramepaceSettings {
limiter: Limiter::Off,
});
}
}
}

#[derive(SystemParam)]
pub struct DemoFramerateParam<'w> {
diagnostics_store: Res<'w, DiagnosticsStore>,
#[cfg(feature = "framepace")]
framepace_settings: ResMut<'w, FramepaceSettings>,
}

impl DemoFramerateParam<'_> {
pub fn show_in_ui(&mut self, ui: &mut egui::Ui) {
for (diagnostic_path, range) in [
(FrameTimeDiagnosticsPlugin::FPS, 0.0..120.0),
(FrameTimeDiagnosticsPlugin::FRAME_TIME, 0.0..50.0),
#[cfg(feature = "framepace")]
(FramepaceDiagnosticsPlugin::FRAMEPACE_FRAMETIME, 0.0..50.0),
#[cfg(feature = "framepace")]
(
FramepaceDiagnosticsPlugin::FRAMEPACE_OVERSLEEP,
0.0..40_000.0,
),
] {
if let Some(diagnostic) = self.diagnostics_store.get(&diagnostic_path) {
if let Some(value) = diagnostic.smoothed() {
ui.add(
egui::widgets::ProgressBar::new(
(value as f32 - range.start) / (range.end - range.start),
)
.text(format!("{}: {:.0}", diagnostic_path, value)),
);
}
}
}
#[cfg(feature = "framepace")]
{
use std::time::Duration;

let limiter = &mut self.framepace_settings.limiter;
egui::ComboBox::from_label("Framepace Limiter")
.selected_text(match limiter {
Limiter::Auto => "auto",
Limiter::Manual(_) => "manual",
Limiter::Off => "off",
})
.show_ui(ui, |ui| {
if ui
.selectable_label(matches!(limiter, Limiter::Auto), "auto")
.clicked()
{
*limiter = Limiter::Auto;
}
if ui
.selectable_label(matches!(limiter, Limiter::Manual(_)), "manual")
.clicked()
{
#[allow(clippy::collapsible_if)]
if !matches!(limiter, Limiter::Manual(_)) {
*limiter = Limiter::Manual(Duration::from_secs_f32(1.0 / 60.0));
}
}
if ui
.selectable_label(matches!(limiter, Limiter::Off), "off")
.clicked()
{
*limiter = Limiter::Off;
}
});
if let Limiter::Manual(limit) = limiter {
const MIN_FPS: f64 = 1.0;
const MAX_FPS: f64 = 120.0;
let mut limit_secs = limit.as_secs_f64();

let mut fps_limit = 1.0 / limit_secs;
ui.add(egui::Slider::new(&mut fps_limit, MIN_FPS..=MAX_FPS).text("FPS Limit"));
limit_secs = 1.0 / fps_limit;

ui.add(
egui::Slider::new(&mut limit_secs, (1.0 / MIN_FPS)..=(1.0 / MAX_FPS))
.text("Frame Time Limit"),
);

*limit = Duration::from_secs_f64(limit_secs);
}
}
}
}
22 changes: 6 additions & 16 deletions demos/src/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
pub mod component_alterbation;
#[cfg(feature = "egui")]
mod framerate;
pub mod info;
#[cfg(feature = "egui")]
pub mod plotting;
Expand All @@ -7,7 +9,6 @@ pub mod tuning;
use std::marker::PhantomData;

#[cfg(feature = "egui")]
use bevy::diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
use bevy::prelude::*;
#[cfg(feature = "egui")]
use bevy::window::{PresentMode, PrimaryWindow};
Expand Down Expand Up @@ -53,8 +54,9 @@ impl<C: Component + UiTunable> Plugin for DemoUi<C> {
app.add_systems(Update, ui_system::<C>.after(DemoInfoUpdateSystemSet));
#[cfg(feature = "egui")]
app.add_systems(Update, plot_source_rolling_update);

#[cfg(feature = "egui")]
app.add_plugins(FrameTimeDiagnosticsPlugin);
app.add_plugins(framerate::DemoFrameratePlugin);

#[cfg(feature = "egui")]
{
Expand Down Expand Up @@ -126,7 +128,7 @@ fn ui_system<C: Component + UiTunable>(
)>,
mut commands: Commands,
mut primary_window_query: Query<&mut Window, With<PrimaryWindow>>,
diagnostics_store: Res<DiagnosticsStore>,
mut framerate: framerate::DemoFramerateParam,
#[cfg(target_arch = "wasm32")] app_setup_configuration: Res<
crate::app_setup_options::AppSetupConfiguration,
>,
Expand Down Expand Up @@ -167,19 +169,7 @@ fn ui_system<C: Component + UiTunable>(
ui.selectable_value(present_mode, PresentMode::Immediate, "Immediate");
ui.selectable_value(present_mode, PresentMode::Mailbox, "Mailbox");
});
for (diagnostic_path, range) in [
(FrameTimeDiagnosticsPlugin::FPS, 0.0..120.0),
(FrameTimeDiagnosticsPlugin::FRAME_TIME, 0.0..50.0),
] {
if let Some(diagnostic) = diagnostics_store.get(&diagnostic_path) {
if let Some(value) = diagnostic.smoothed() {
ui.add(
egui::widgets::ProgressBar::new((value as f32 - range.start) / (range.end - range.start))
.text(format!("{}: {:.0}", diagnostic_path, value))
);
}
}
}
framerate.show_in_ui(ui);
egui::CollapsingHeader::new("Controls:")
.default_open(false)
.show(ui, |ui| {
Expand Down

0 comments on commit d9a6c09

Please sign in to comment.