From 2b0bf82b51d0fafbcc04069fc3165b0dc7a48234 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 20 Sep 2022 13:58:55 +0200 Subject: [PATCH] Make eframe::App::as_any_mut optional to implement (#2061) --- crates/eframe/CHANGELOG.md | 2 ++ crates/eframe/src/epi.rs | 17 ++++++++----- crates/eframe/src/web/backend.rs | 8 ++++++- .../egui_demo_app/src/apps/custom3d_glow.rs | 8 ------- .../egui_demo_app/src/apps/custom3d_wgpu.rs | 8 ------- crates/egui_demo_app/src/apps/http_app.rs | 8 ------- crates/egui_demo_app/src/wrap_app.rs | 24 ++----------------- examples/custom_3d_three-d/src/main.rs | 5 ---- 8 files changed, 22 insertions(+), 58 deletions(-) diff --git a/crates/eframe/CHANGELOG.md b/crates/eframe/CHANGELOG.md index 3b10b41a733..6af5e4976f4 100644 --- a/crates/eframe/CHANGELOG.md +++ b/crates/eframe/CHANGELOG.md @@ -12,6 +12,8 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C * Added `shader_version` to `NativeOptions` for cross compiling support on different target OpenGL | ES versions (on native `glow` renderer only) ([#1993](https://github.com/emilk/egui/pull/1993)). * Fix: app state is now saved when user presses Cmd-Q on Mac ([#2013](https://github.com/emilk/egui/pull/2013)). * Added `center` to `NativeOptions` and `monitor_size` to `WindowInfo` on desktop ([#2035](https://github.com/emilk/egui/pull/2035)). +* Web: you can access your application from JS using `AppRunner::app_mut`. See `crates/egui_demo_app/src/lib.rs`. + ## 0.19.0 - 2022-08-20 * MSRV (Minimum Supported Rust Version) is now `1.61.0` ([#1846](https://github.com/emilk/egui/pull/1846)). diff --git a/crates/eframe/src/epi.rs b/crates/eframe/src/epi.rs index 434fe8a6a11..278f5a177f1 100644 --- a/crates/eframe/src/epi.rs +++ b/crates/eframe/src/epi.rs @@ -69,20 +69,25 @@ pub trait App { /// To force a repaint, call [`egui::Context::request_repaint`] at any time (e.g. from another thread). fn update(&mut self, ctx: &egui::Context, frame: &mut Frame); - /// Handle to the app. + /// Get a handle to the app. /// - /// Can be used from web to interact or other external context - /// Implementation is needed, because downcasting Box -> Box to get &ConcreteApp is not simple in current rust. + /// Can be used from web to interact or other external context. + /// + /// You need to implement this if you want to be able to access the application from JS using [`AppRunner::app_mut`]. + /// + /// This is needed because downcasting Box -> Box to get &ConcreteApp is not simple in current rust. /// /// Just copy-paste this as your implementation: /// ```ignore /// #[cfg(target_arch = "wasm32")] - /// fn as_any_mut(&mut self) -> &mut dyn std::any::Any { - /// &mut *self + /// fn as_any_mut(&mut self) -> Option<&mut dyn std::any::Any> { + /// Some(&mut *self) /// } /// ``` #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any; + fn as_any_mut(&mut self) -> Option<&mut dyn Any> { + None + } /// Called on shutdown, and perhaps at regular intervals. Allows you to save state. /// diff --git a/crates/eframe/src/web/backend.rs b/crates/eframe/src/web/backend.rs index a7a9f95b25f..ea92b39b619 100644 --- a/crates/eframe/src/web/backend.rs +++ b/crates/eframe/src/web/backend.rs @@ -266,8 +266,14 @@ impl AppRunner { } /// Get mutable access to the concrete [`App`] we enclose. + /// + /// This will panic if your app does not implement [`App::as_any_mut`]. pub fn app_mut(&mut self) -> &mut ConreteApp { - self.app.as_any_mut().downcast_mut::().unwrap() + self.app + .as_any_mut() + .expect("Your app must implement `as_any_mut`, but it doesn't") + .downcast_mut::() + .unwrap() } pub fn auto_save(&mut self) { diff --git a/crates/egui_demo_app/src/apps/custom3d_glow.rs b/crates/egui_demo_app/src/apps/custom3d_glow.rs index fe6999b6a5f..5d82d75c244 100644 --- a/crates/egui_demo_app/src/apps/custom3d_glow.rs +++ b/crates/egui_demo_app/src/apps/custom3d_glow.rs @@ -1,8 +1,5 @@ use std::sync::Arc; -#[cfg(target_arch = "wasm32")] -use core::any::Any; - use eframe::egui_glow; use egui::mutex::Mutex; use egui_glow::glow; @@ -51,11 +48,6 @@ impl eframe::App for Custom3d { self.rotating_triangle.lock().destroy(gl); } } - - #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self - } } impl Custom3d { diff --git a/crates/egui_demo_app/src/apps/custom3d_wgpu.rs b/crates/egui_demo_app/src/apps/custom3d_wgpu.rs index 1c43b10bf2b..0ef65f2bfb0 100644 --- a/crates/egui_demo_app/src/apps/custom3d_wgpu.rs +++ b/crates/egui_demo_app/src/apps/custom3d_wgpu.rs @@ -1,8 +1,5 @@ use std::sync::Arc; -#[cfg(target_arch = "wasm32")] -use core::any::Any; - use eframe::{ egui_wgpu::{self, wgpu}, wgpu::util::DeviceExt, @@ -120,11 +117,6 @@ impl eframe::App for Custom3d { }); }); } - - #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self - } } impl Custom3d { diff --git a/crates/egui_demo_app/src/apps/http_app.rs b/crates/egui_demo_app/src/apps/http_app.rs index 69648080670..df92e7489f6 100644 --- a/crates/egui_demo_app/src/apps/http_app.rs +++ b/crates/egui_demo_app/src/apps/http_app.rs @@ -1,9 +1,6 @@ use egui_extras::RetainedImage; use poll_promise::Promise; -#[cfg(target_arch = "wasm32")] -use core::any::Any; - struct Resource { /// HTTP response response: ehttp::Response, @@ -109,11 +106,6 @@ impl eframe::App for HttpApp { } }); } - - #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self - } } fn ui_url(ui: &mut egui::Ui, frame: &mut eframe::Frame, url: &mut String) -> bool { diff --git a/crates/egui_demo_app/src/wrap_app.rs b/crates/egui_demo_app/src/wrap_app.rs index c9f820f62fb..6abe45debc3 100644 --- a/crates/egui_demo_app/src/wrap_app.rs +++ b/crates/egui_demo_app/src/wrap_app.rs @@ -16,11 +16,6 @@ impl eframe::App for EasyMarkApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { self.editor.panels(ctx); } - - #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self - } } // ---------------------------------------------------------------------------- @@ -35,11 +30,6 @@ impl eframe::App for DemoApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { self.demo_windows.ui(ctx); } - - #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self - } } // ---------------------------------------------------------------------------- @@ -59,11 +49,6 @@ impl eframe::App for FractalClockApp { .ui(ui, Some(crate::seconds_since_midnight())); }); } - - #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self - } } // ---------------------------------------------------------------------------- @@ -88,11 +73,6 @@ impl eframe::App for ColorTestApp { }); }); } - - #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self - } } // ---------------------------------------------------------------------------- @@ -250,8 +230,8 @@ impl eframe::App for WrapApp { } #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self + fn as_any_mut(&mut self) -> Option<&mut dyn Any> { + Some(&mut *self) } } diff --git a/examples/custom_3d_three-d/src/main.rs b/examples/custom_3d_three-d/src/main.rs index 0233bd585b2..cd310cfaa85 100644 --- a/examples/custom_3d_three-d/src/main.rs +++ b/examples/custom_3d_three-d/src/main.rs @@ -70,11 +70,6 @@ impl eframe::App for MyApp { }); }); } - - #[cfg(target_arch = "wasm32")] - fn as_any_mut(&mut self) -> &mut dyn Any { - &mut *self - } } /// We get a [`glow::Context`] from `eframe` and we want to construct a [`ThreeDApp`].