Demo App: Add ability to close the Backend window

This commit is contained in:
Emil Ernerfeldt 2020-12-13 00:30:54 +01:00
parent 174c938d18
commit 6ff39d88bf
4 changed files with 48 additions and 20 deletions

View file

@ -13,7 +13,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("demo_windows_minimal", |b| { c.bench_function("demo_windows_minimal", |b| {
b.iter(|| { b.iter(|| {
ctx.begin_frame(raw_input.clone()); ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx, &Default::default(), &mut None); demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
ctx.end_frame() ctx.end_frame()
}) })
}); });
@ -27,7 +27,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("demo_windows_full", |b| { c.bench_function("demo_windows_full", |b| {
b.iter(|| { b.iter(|| {
ctx.begin_frame(raw_input.clone()); ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx, &Default::default(), &mut None); demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
ctx.end_frame() ctx.end_frame()
}) })
}); });
@ -38,7 +38,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
ctx.memory().all_collpasing_are_open = true; // expand the demo window with everything ctx.memory().all_collpasing_are_open = true; // expand the demo window with everything
let mut demo_windows = egui::demos::DemoWindows::default(); let mut demo_windows = egui::demos::DemoWindows::default();
ctx.begin_frame(raw_input.clone()); ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx, &Default::default(), &mut None); demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
let (_, paint_commands) = ctx.end_frame(); let (_, paint_commands) = ctx.end_frame();
c.bench_function("tesselate", |b| { c.bench_function("tesselate", |b| {

View file

@ -69,6 +69,10 @@ impl FrameHistory {
self.frame_times.add(now, previus_frame_time); // projected self.frame_times.add(now, previus_frame_time); // projected
} }
fn mean_frame_time(&self) -> f32 {
self.frame_times.average().unwrap_or_default()
}
fn fps(&self) -> f32 { fn fps(&self) -> f32 {
1.0 / self.frame_times.mean_time_interval().unwrap_or_default() 1.0 / self.frame_times.mean_time_interval().unwrap_or_default()
} }
@ -81,7 +85,7 @@ impl FrameHistory {
ui.label(format!( ui.label(format!(
"Mean CPU usage per frame: {:.2} ms / frame", "Mean CPU usage per frame: {:.2} ms / frame",
1e3 * self.frame_times.average().unwrap_or_default() 1e3 * self.mean_frame_time()
)) ))
.on_hover_text( .on_hover_text(
"Includes Egui layout and tesselation time.\n\ "Includes Egui layout and tesselation time.\n\
@ -174,6 +178,8 @@ impl FrameHistory {
pub struct DemoApp { pub struct DemoApp {
demo_windows: demos::DemoWindows, demo_windows: demos::DemoWindows,
backend_window_open: bool,
#[cfg_attr(feature = "serde", serde(skip))] // go back to `Reactive` mode each time we start #[cfg_attr(feature = "serde", serde(skip))] // go back to `Reactive` mode each time we start
run_mode: RunMode, run_mode: RunMode,
@ -186,9 +192,6 @@ pub struct DemoApp {
impl DemoApp { impl DemoApp {
fn backend_ui(&mut self, ui: &mut Ui, integration_context: &mut app::IntegrationContext<'_>) { fn backend_ui(&mut self, ui: &mut Ui, integration_context: &mut app::IntegrationContext<'_>) {
self.frame_history
.on_new_frame(ui.input().time, integration_context.info.cpu_usage);
let is_web = integration_context.info.web_info.is_some(); let is_web = integration_context.info.web_info.is_some();
if is_web { if is_web {
@ -280,6 +283,9 @@ impl app::App for DemoApp {
ctx: &Arc<Context>, ctx: &Arc<Context>,
integration_context: &mut crate::app::IntegrationContext<'_>, integration_context: &mut crate::app::IntegrationContext<'_>,
) { ) {
self.frame_history
.on_new_frame(ctx.input().time, integration_context.info.cpu_usage);
let web_location_hash = integration_context let web_location_hash = integration_context
.info .info
.web_info .web_info
@ -298,18 +304,36 @@ impl app::App for DemoApp {
link, link,
}; };
self.demo_windows.ui( let mean_frame_time = self.frame_history.mean_frame_time();
let Self {
demo_windows,
backend_window_open,
..
} = self;
demo_windows.ui(
ctx, ctx,
&demo_environment, &demo_environment,
&mut integration_context.tex_allocator, &mut integration_context.tex_allocator,
|ui| {
ui.separator();
ui.checkbox(backend_window_open, "💻 Backend");
ui.label(format!("{:.2} ms / frame", 1e3 * mean_frame_time))
.on_hover_text("CPU usage.");
},
); );
let mut backend_window_open = self.backend_window_open;
crate::Window::new("💻 Backend") crate::Window::new("💻 Backend")
.min_width(360.0) .min_width(360.0)
.scroll(false) .scroll(false)
.open(&mut backend_window_open)
.show(ctx, |ui| { .show(ctx, |ui| {
self.backend_ui(ui, integration_context); self.backend_ui(ui, integration_context);
}); });
self.backend_window_open = backend_window_open;
if self.run_mode == RunMode::Continuous { if self.run_mode == RunMode::Continuous {
// Tell the backend to repaint as soon as possible // Tell the backend to repaint as soon as possible

View file

@ -84,11 +84,13 @@ pub struct DemoWindows {
impl DemoWindows { impl DemoWindows {
/// Show the app ui (menu bar and windows). /// Show the app ui (menu bar and windows).
/// `sidebar_ui` can be used to optionally show some things in the sidebar
pub fn ui( pub fn ui(
&mut self, &mut self,
ctx: &Arc<Context>, ctx: &Arc<Context>,
env: &DemoEnvironment, env: &DemoEnvironment,
tex_allocator: &mut Option<&mut dyn app::TextureAllocator>, tex_allocator: &mut Option<&mut dyn app::TextureAllocator>,
sidebar_ui: impl FnOnce(&mut Ui),
) { ) {
if self.previous_link != env.link { if self.previous_link != env.link {
match env.link { match env.link {
@ -125,6 +127,8 @@ impl DemoWindows {
self.open_windows.checkboxes(ui); self.open_windows.checkboxes(ui);
self.demos.checkboxes(ui); self.demos.checkboxes(ui);
}); });
sidebar_ui(ui);
}); });
crate::TopPanel::top(Id::new("menu_bar")).show(ctx, |ui| { crate::TopPanel::top(Id::new("menu_bar")).show(ctx, |ui| {

View file

@ -116,8 +116,18 @@ pub use {
widgets::*, widgets::*,
}; };
#[cfg(debug_assertions)]
pub(crate) fn has_debug_assertions() -> bool {
true
}
#[cfg(not(debug_assertions))]
pub(crate) fn has_debug_assertions() -> bool {
false
}
#[test] #[test]
pub fn text_egui_e2e() { fn test_egui_e2e() {
let mut demo_windows = crate::demos::DemoWindows::default(); let mut demo_windows = crate::demos::DemoWindows::default();
let mut ctx = crate::Context::new(); let mut ctx = crate::Context::new();
let raw_input = crate::RawInput { let raw_input = crate::RawInput {
@ -128,19 +138,9 @@ pub fn text_egui_e2e() {
const NUM_FRAMES: usize = 5; const NUM_FRAMES: usize = 5;
for _ in 0..NUM_FRAMES { for _ in 0..NUM_FRAMES {
ctx.begin_frame(raw_input.clone()); ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx, &Default::default(), &mut None); demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
let (_output, paint_commands) = ctx.end_frame(); let (_output, paint_commands) = ctx.end_frame();
let paint_jobs = ctx.tesselate(paint_commands); let paint_jobs = ctx.tesselate(paint_commands);
assert!(!paint_jobs.is_empty()); assert!(!paint_jobs.is_empty());
} }
} }
#[cfg(debug_assertions)]
pub(crate) fn has_debug_assertions() -> bool {
true
}
#[cfg(not(debug_assertions))]
pub(crate) fn has_debug_assertions() -> bool {
false
}