Add a dummy warm-up frame to the demo app to pre-cache emojis
This commit is contained in:
parent
4202c4b6a9
commit
14a96ca5d0
14 changed files with 144 additions and 55 deletions
|
@ -870,36 +870,36 @@ async function init(input) {
|
||||||
var ret = wasm.memory;
|
var ret = wasm.memory;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2178 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2332 = function(arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 536, __wbg_adapter_26);
|
var ret = makeMutClosure(arg0, arg1, 607, __wbg_adapter_26);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2179 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2333 = function(arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 536, __wbg_adapter_29);
|
var ret = makeMutClosure(arg0, arg1, 607, __wbg_adapter_29);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2182 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2336 = function(arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 536, __wbg_adapter_32);
|
var ret = makeMutClosure(arg0, arg1, 607, __wbg_adapter_32);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2184 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2338 = function(arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 536, __wbg_adapter_35);
|
var ret = makeMutClosure(arg0, arg1, 607, __wbg_adapter_35);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2186 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2340 = function(arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 536, __wbg_adapter_38);
|
var ret = makeMutClosure(arg0, arg1, 607, __wbg_adapter_38);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2188 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2342 = function(arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 536, __wbg_adapter_41);
|
var ret = makeMutClosure(arg0, arg1, 607, __wbg_adapter_41);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2190 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2344 = function(arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 536, __wbg_adapter_44);
|
var ret = makeMutClosure(arg0, arg1, 607, __wbg_adapter_44);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper3036 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper3087 = function(arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 608, __wbg_adapter_47);
|
var ret = makeMutClosure(arg0, arg1, 649, __wbg_adapter_47);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -35,7 +35,7 @@ impl State {
|
||||||
|
|
||||||
// Helper
|
// Helper
|
||||||
pub fn is_open(ctx: &Context, id: Id) -> Option<bool> {
|
pub fn is_open(ctx: &Context, id: Id) -> Option<bool> {
|
||||||
if ctx.memory().all_collpasing_are_open {
|
if ctx.memory().everything_is_visible() {
|
||||||
Some(true)
|
Some(true)
|
||||||
} else {
|
} else {
|
||||||
ctx.memory()
|
ctx.memory()
|
||||||
|
@ -52,7 +52,11 @@ impl State {
|
||||||
|
|
||||||
/// 0 for closed, 1 for open, with tweening
|
/// 0 for closed, 1 for open, with tweening
|
||||||
pub fn openness(&self, ctx: &Context, id: Id) -> f32 {
|
pub fn openness(&self, ctx: &Context, id: Id) -> f32 {
|
||||||
ctx.animate_bool(id, self.open || ctx.memory().all_collpasing_are_open)
|
if ctx.memory().everything_is_visible() {
|
||||||
|
1.0
|
||||||
|
} else {
|
||||||
|
ctx.animate_bool(id, self.open)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show contents if we are open, with a nice animation between closed and open
|
/// Show contents if we are open, with a nice animation between closed and open
|
||||||
|
|
|
@ -25,6 +25,8 @@ pub fn show_tooltip(ctx: &CtxRef, add_contents: impl FnOnce(&mut Ui)) {
|
||||||
let position = position.min(ctx.input().screen_rect().right_bottom() - expected_size);
|
let position = position.min(ctx.input().screen_rect().right_bottom() - expected_size);
|
||||||
let position = position.max(ctx.input().screen_rect().left_top());
|
let position = position.max(ctx.input().screen_rect().left_top());
|
||||||
position
|
position
|
||||||
|
} else if ctx.memory().everything_is_visible() {
|
||||||
|
Pos2::default()
|
||||||
} else {
|
} else {
|
||||||
return; // No good place for a tooltip :(
|
return; // No good place for a tooltip :(
|
||||||
};
|
};
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl<'open> Window<'open> {
|
||||||
with_title_bar,
|
with_title_bar,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
if matches!(open, Some(false)) && !ctx.memory().all_windows_are_open {
|
if matches!(open, Some(false)) && !ctx.memory().everything_is_visible() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ pub(crate) struct FrameState {
|
||||||
|
|
||||||
/// How much space is used by panels.
|
/// How much space is used by panels.
|
||||||
used_by_panels: Rect,
|
used_by_panels: Rect,
|
||||||
|
|
||||||
pub(crate) scroll_delta: Vec2,
|
pub(crate) scroll_delta: Vec2,
|
||||||
pub(crate) scroll_target: Option<(f32, Align)>,
|
pub(crate) scroll_target: Option<(f32, Align)>,
|
||||||
// TODO: move some things from `Memory` to here
|
// TODO: move some things from `Memory` to here
|
||||||
|
@ -56,7 +57,7 @@ impl Default for FrameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FrameState {
|
impl FrameState {
|
||||||
pub fn begin_frame(&mut self, input: &InputState) {
|
fn begin_frame(&mut self, input: &InputState) {
|
||||||
self.available_rect = input.screen_rect();
|
self.available_rect = input.screen_rect();
|
||||||
self.unused_rect = input.screen_rect();
|
self.unused_rect = input.screen_rect();
|
||||||
self.used_by_panels = Rect::nothing();
|
self.used_by_panels = Rect::nothing();
|
||||||
|
@ -717,6 +718,11 @@ impl Context {
|
||||||
}
|
}
|
||||||
animated_value
|
animated_value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear memory of any animations.
|
||||||
|
pub fn clear_animations(&self) {
|
||||||
|
*self.animation_manager.lock() = Default::default();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
|
|
@ -60,12 +60,8 @@ pub struct Memory {
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
#[cfg_attr(feature = "serde", serde(skip))]
|
||||||
pub(crate) tooltip_rect: Option<Rect>,
|
pub(crate) tooltip_rect: Option<Rect>,
|
||||||
|
|
||||||
/// Useful for debugging, benchmarking etc.
|
#[cfg_attr(feature = "serde", serde(skip))]
|
||||||
pub all_collpasing_are_open: bool,
|
everything_is_visible: bool,
|
||||||
/// Useful for debugging, benchmarking etc.
|
|
||||||
pub all_menus_are_open: bool,
|
|
||||||
/// Useful for debugging, benchmarking etc.
|
|
||||||
pub all_windows_are_open: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Say there is a button in a scroll area.
|
/// Say there is a button in a scroll area.
|
||||||
|
@ -258,7 +254,7 @@ impl Memory {
|
||||||
/// Only one can be be open at a time.
|
/// Only one can be be open at a time.
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub fn is_popup_open(&mut self, popup_id: Id) -> bool {
|
pub fn is_popup_open(&mut self, popup_id: Id) -> bool {
|
||||||
self.popup == Some(popup_id)
|
self.popup == Some(popup_id) || self.everything_is_visible()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_popup(&mut self, popup_id: Id) {
|
pub fn open_popup(&mut self, popup_id: Id) {
|
||||||
|
@ -276,6 +272,24 @@ impl Memory {
|
||||||
self.open_popup(popup_id);
|
self.open_popup(popup_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If true, all windows, menus, tooltips etc are to be visible at once.
|
||||||
|
///
|
||||||
|
/// This is useful for testing, benchmarking, pre-caching, etc.
|
||||||
|
///
|
||||||
|
/// Experimental feature!
|
||||||
|
pub fn everything_is_visible(&self) -> bool {
|
||||||
|
self.everything_is_visible
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If true, all windows, menus, tooltips etc are to be visible at once.
|
||||||
|
///
|
||||||
|
/// This is useful for testing, benchmarking, pre-caching, etc.
|
||||||
|
///
|
||||||
|
/// Experimental feature!
|
||||||
|
pub fn set_everything_is_visible(&mut self, value: bool) {
|
||||||
|
self.everything_is_visible = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -94,7 +94,7 @@ fn menu_impl<'c>(
|
||||||
bar_state.open_menu = Some(menu_id);
|
bar_state.open_menu = Some(menu_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if bar_state.open_menu == Some(menu_id) || ui.memory().all_menus_are_open {
|
if bar_state.open_menu == Some(menu_id) || ui.ctx().memory().everything_is_visible() {
|
||||||
let area = Area::new(menu_id)
|
let area = Area::new(menu_id)
|
||||||
.order(Order::Foreground)
|
.order(Order::Foreground)
|
||||||
.fixed_pos(button_response.rect.left_bottom());
|
.fixed_pos(button_response.rect.left_bottom());
|
||||||
|
|
|
@ -139,7 +139,7 @@ impl Response {
|
||||||
/// Show this UI if the item was hovered (i.e. a tooltip).
|
/// Show this UI if the item was hovered (i.e. a tooltip).
|
||||||
/// If you call this multiple times the tooltips will stack underneath the previous ones.
|
/// If you call this multiple times the tooltips will stack underneath the previous ones.
|
||||||
pub fn on_hover_ui(self, add_contents: impl FnOnce(&mut Ui)) -> Self {
|
pub fn on_hover_ui(self, add_contents: impl FnOnce(&mut Ui)) -> Self {
|
||||||
if self.hovered {
|
if self.hovered || self.ctx.memory().everything_is_visible() {
|
||||||
crate::containers::show_tooltip(&self.ctx, add_contents);
|
crate::containers::show_tooltip(&self.ctx, add_contents);
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ctx = egui::CtxRef::default();
|
let mut ctx = egui::CtxRef::default();
|
||||||
ctx.memory().all_collpasing_are_open = true; // expand the demo window with everything
|
ctx.memory().set_everything_is_visible(true); // give us everything
|
||||||
let mut demo_windows = egui_demo_lib::DemoWindows::default();
|
let mut demo_windows = egui_demo_lib::DemoWindows::default();
|
||||||
|
|
||||||
c.bench_function("demo_windows_full", |b| {
|
c.bench_function("demo_windows_full", |b| {
|
||||||
|
@ -32,7 +32,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ctx = egui::CtxRef::default();
|
let mut ctx = egui::CtxRef::default();
|
||||||
ctx.memory().all_collpasing_are_open = true; // expand the demo window with everything
|
ctx.memory().set_everything_is_visible(true); // give us everything
|
||||||
let mut demo_windows = egui_demo_lib::DemoWindows::default();
|
let mut demo_windows = egui_demo_lib::DemoWindows::default();
|
||||||
ctx.begin_frame(raw_input.clone());
|
ctx.begin_frame(raw_input.clone());
|
||||||
demo_windows.ui(&ctx);
|
demo_windows.ui(&ctx);
|
||||||
|
|
|
@ -42,6 +42,10 @@ impl epi::App for WrapApp {
|
||||||
epi::set_value(storage, epi::APP_KEY, self);
|
epi::set_value(storage, epi::APP_KEY, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn warm_up_enabled(&self) -> bool {
|
||||||
|
true // The example windows use a lot of emojis. Pre-cache them by running one frame where everything is open.
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&mut self, ctx: &egui::CtxRef, frame: &mut epi::Frame<'_>) {
|
fn update(&mut self, ctx: &egui::CtxRef, frame: &mut epi::Frame<'_>) {
|
||||||
if let Some(web_info) = frame.info().web_info.as_ref() {
|
if let Some(web_info) = frame.info().web_info.as_ref() {
|
||||||
if let Some(anchor) = web_info.web_location_hash.strip_prefix("#") {
|
if let Some(anchor) = web_info.web_location_hash.strip_prefix("#") {
|
||||||
|
@ -91,14 +95,14 @@ impl epi::App for WrapApp {
|
||||||
});
|
});
|
||||||
|
|
||||||
self.backend_panel.update(ctx, frame);
|
self.backend_panel.update(ctx, frame);
|
||||||
if self.backend_panel.open {
|
if self.backend_panel.open || ctx.memory().everything_is_visible() {
|
||||||
egui::SidePanel::left("backend_panel", 150.0).show(ctx, |ui| {
|
egui::SidePanel::left("backend_panel", 150.0).show(ctx, |ui| {
|
||||||
self.backend_panel.ui(ui, frame);
|
self.backend_panel.ui(ui, frame);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (anchor, app) in self.apps.iter_mut() {
|
for (anchor, app) in self.apps.iter_mut() {
|
||||||
if anchor == self.selected_anchor {
|
if anchor == self.selected_anchor || ctx.memory().everything_is_visible() {
|
||||||
app.update(ctx, frame);
|
app.update(ctx, frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,19 +196,6 @@ impl BackendPanel {
|
||||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame<'_>) {
|
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame<'_>) {
|
||||||
ui.heading("💻 Backend");
|
ui.heading("💻 Backend");
|
||||||
|
|
||||||
if frame.is_web() {
|
|
||||||
ui.label("Egui is an immediate mode GUI written in Rust, compiled to WebAssembly, rendered with WebGL.");
|
|
||||||
ui.label(
|
|
||||||
"Everything you see is rendered as textured triangles. There is no DOM. There are no HTML elements. \
|
|
||||||
This is not JavaScript. This is Rust, running at 60 FPS. This is the web page, reinvented with game tech.");
|
|
||||||
ui.label("This is also work in progress, and not ready for production... yet :)");
|
|
||||||
ui.horizontal(|ui| {
|
|
||||||
ui.label("Project home page:");
|
|
||||||
ui.hyperlink("https://github.com/emilk/egui");
|
|
||||||
});
|
|
||||||
ui.separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.run_mode_ui(ui);
|
self.run_mode_ui(ui);
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
@ -219,8 +210,19 @@ impl BackendPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !frame.is_web() {
|
ui.separator();
|
||||||
ui.separator();
|
|
||||||
|
if frame.is_web() {
|
||||||
|
ui.label("Egui is an immediate mode GUI written in Rust, compiled to WebAssembly, rendered with WebGL.");
|
||||||
|
ui.label(
|
||||||
|
"Everything you see is rendered as textured triangles. There is no DOM. There are no HTML elements. \
|
||||||
|
This is not JavaScript. This is Rust, running at 60 FPS. This is the web page, reinvented with game tech.");
|
||||||
|
ui.label("This is also work in progress, and not ready for production... yet :)");
|
||||||
|
ui.horizontal_wrapped_for_text(egui::TextStyle::Body, |ui| {
|
||||||
|
ui.label("Project home page:");
|
||||||
|
ui.hyperlink("https://github.com/emilk/egui");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
if ui
|
if ui
|
||||||
.button("📱 Phone Size")
|
.button("📱 Phone Size")
|
||||||
.on_hover_text("Resize the window to be small like a phone.")
|
.on_hover_text("Resize the window to be small like a phone.")
|
||||||
|
|
|
@ -90,6 +90,18 @@ fn create_storage(app_name: &str) -> Option<Box<dyn epi::Storage>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn integration_info(
|
||||||
|
display: &glium::Display,
|
||||||
|
previous_frame_time: Option<f32>,
|
||||||
|
) -> epi::IntegrationInfo {
|
||||||
|
epi::IntegrationInfo {
|
||||||
|
web_info: None,
|
||||||
|
cpu_usage: previous_frame_time,
|
||||||
|
seconds_since_midnight: Some(seconds_since_midnight()),
|
||||||
|
native_pixels_per_point: Some(native_pixels_per_point(&display)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Run an egui app
|
/// Run an egui app
|
||||||
pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
||||||
let mut storage = create_storage(app.name());
|
let mut storage = create_storage(app.name());
|
||||||
|
@ -113,6 +125,7 @@ pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.and_then(|storage| epi::get_value(storage.as_ref(), EGUI_MEMORY_KEY))
|
.and_then(|storage| epi::get_value(storage.as_ref(), EGUI_MEMORY_KEY))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
app.setup(&ctx);
|
app.setup(&ctx);
|
||||||
|
|
||||||
let mut input_state = GliumInputState::from_pixels_per_point(native_pixels_per_point(&display));
|
let mut input_state = GliumInputState::from_pixels_per_point(native_pixels_per_point(&display));
|
||||||
|
@ -126,6 +139,36 @@ pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
||||||
|
|
||||||
let http = std::sync::Arc::new(crate::http::GliumHttp {});
|
let http = std::sync::Arc::new(crate::http::GliumHttp {});
|
||||||
|
|
||||||
|
if app.warm_up_enabled() {
|
||||||
|
// let warm_up_start = Instant::now();
|
||||||
|
input_state.raw.time = Some(0.0);
|
||||||
|
input_state.raw.screen_rect = Some(Rect::from_min_size(
|
||||||
|
Default::default(),
|
||||||
|
screen_size_in_pixels(&display) / input_state.raw.pixels_per_point.unwrap(),
|
||||||
|
));
|
||||||
|
ctx.begin_frame(input_state.raw.take());
|
||||||
|
let mut app_output = epi::backend::AppOutput::default();
|
||||||
|
let mut frame = epi::backend::FrameBuilder {
|
||||||
|
info: integration_info(&display, None),
|
||||||
|
tex_allocator: Some(&mut painter),
|
||||||
|
http: http.clone(),
|
||||||
|
output: &mut app_output,
|
||||||
|
repaint_signal: repaint_signal.clone(),
|
||||||
|
}
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let saved_memory = ctx.memory().clone();
|
||||||
|
ctx.memory().set_everything_is_visible(true);
|
||||||
|
app.update(&ctx, &mut frame);
|
||||||
|
*ctx.memory() = saved_memory; // We don't want to remember that windows were huge.
|
||||||
|
ctx.clear_animations();
|
||||||
|
|
||||||
|
let (egui_output, _paint_commands) = ctx.end_frame();
|
||||||
|
handle_output(egui_output, &display, clipboard.as_mut());
|
||||||
|
// TODO: handle app_output
|
||||||
|
// eprintln!("Warmed up in {} ms", warm_up_start.elapsed().as_millis())
|
||||||
|
}
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
let mut redraw = || {
|
let mut redraw = || {
|
||||||
let frame_start = Instant::now();
|
let frame_start = Instant::now();
|
||||||
|
@ -138,12 +181,7 @@ pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
||||||
ctx.begin_frame(input_state.raw.take());
|
ctx.begin_frame(input_state.raw.take());
|
||||||
let mut app_output = epi::backend::AppOutput::default();
|
let mut app_output = epi::backend::AppOutput::default();
|
||||||
let mut frame = epi::backend::FrameBuilder {
|
let mut frame = epi::backend::FrameBuilder {
|
||||||
info: epi::IntegrationInfo {
|
info: integration_info(&display, previous_frame_time),
|
||||||
web_info: None,
|
|
||||||
cpu_usage: previous_frame_time,
|
|
||||||
seconds_since_midnight: Some(seconds_since_midnight()),
|
|
||||||
native_pixels_per_point: Some(native_pixels_per_point(&display)),
|
|
||||||
},
|
|
||||||
tex_allocator: Some(&mut painter),
|
tex_allocator: Some(&mut painter),
|
||||||
http: http.clone(),
|
http: http.clone(),
|
||||||
output: &mut app_output,
|
output: &mut app_output,
|
||||||
|
|
|
@ -179,6 +179,20 @@ impl AppRunner {
|
||||||
self.web_backend.canvas_id()
|
self.web_backend.canvas_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn warm_up(&mut self) -> Result<(), JsValue> {
|
||||||
|
if self.app.warm_up_enabled() {
|
||||||
|
let saved_memory = self.web_backend.ctx.memory().clone();
|
||||||
|
self.web_backend
|
||||||
|
.ctx
|
||||||
|
.memory()
|
||||||
|
.set_everything_is_visible(true);
|
||||||
|
self.logic()?;
|
||||||
|
*self.web_backend.ctx.memory() = saved_memory; // We don't want to remember that windows were huge.
|
||||||
|
self.web_backend.ctx.clear_animations();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn logic(&mut self) -> Result<(egui::Output, egui::PaintJobs), JsValue> {
|
pub fn logic(&mut self) -> Result<(egui::Output, egui::PaintJobs), JsValue> {
|
||||||
resize_canvas_to_screen_size(self.web_backend.canvas_id());
|
resize_canvas_to_screen_size(self.web_backend.canvas_id());
|
||||||
let canvas_size = canvas_size_in_points(self.web_backend.canvas_id());
|
let canvas_size = canvas_size_in_points(self.web_backend.canvas_id());
|
||||||
|
@ -227,7 +241,8 @@ impl AppRunner {
|
||||||
/// and start running the given app.
|
/// and start running the given app.
|
||||||
pub fn start(canvas_id: &str, app: Box<dyn epi::App>) -> Result<AppRunnerRef, JsValue> {
|
pub fn start(canvas_id: &str, app: Box<dyn epi::App>) -> Result<AppRunnerRef, JsValue> {
|
||||||
let backend = WebBackend::new(canvas_id)?;
|
let backend = WebBackend::new(canvas_id)?;
|
||||||
let runner = AppRunner::new(backend, app)?;
|
let mut runner = AppRunner::new(backend, app)?;
|
||||||
|
runner.warm_up()?;
|
||||||
start_runner(runner)
|
start_runner(runner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,14 @@ pub trait App {
|
||||||
/// Optional.
|
/// Optional.
|
||||||
fn setup(&mut self, _ctx: &egui::CtxRef) {}
|
fn setup(&mut self, _ctx: &egui::CtxRef) {}
|
||||||
|
|
||||||
|
/// If `true` a warm-up call to [`Self::update`] will be issued where
|
||||||
|
/// `ctx.memory().everything_is_visible()` will be set to `true`.
|
||||||
|
///
|
||||||
|
/// In this warm-up call, all paint commands will be ignored.
|
||||||
|
fn warm_up_enabled(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Called once on start. Allows you to restore state.
|
/// Called once on start. Allows you to restore state.
|
||||||
fn load(&mut self, _storage: &dyn Storage) {}
|
fn load(&mut self, _storage: &dyn Storage) {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue