diff --git a/crates/eframe/src/epi.rs b/crates/eframe/src/epi.rs index 720a65e80ab..1a45ee83b6e 100644 --- a/crates/eframe/src/epi.rs +++ b/crates/eframe/src/epi.rs @@ -6,6 +6,9 @@ #![warn(missing_docs)] // Let's keep `epi` well-documented. +#[cfg(target_arch = "wasm32")] +use std::any::Any; + #[cfg(not(target_arch = "wasm32"))] pub use crate::native::run::RequestRepaintEvent; #[cfg(not(target_arch = "wasm32"))] @@ -66,6 +69,15 @@ 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. + /// + /// 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. + /// + /// Just return &mut *self + #[cfg(target_arch = "wasm32")] + fn as_any_mut(&mut self) -> &mut dyn Any; + /// Called on shutdown, and perhaps at regular intervals. Allows you to save state. /// /// Only called when the "persistence" feature is enabled. diff --git a/crates/eframe/src/web/backend.rs b/crates/eframe/src/web/backend.rs index ba657615d14..a7a9f95b25f 100644 --- a/crates/eframe/src/web/backend.rs +++ b/crates/eframe/src/web/backend.rs @@ -265,6 +265,11 @@ impl AppRunner { &self.egui_ctx } + /// Get mutable access to the concrete [`App`] we enclose. + pub fn app_mut(&mut self) -> &mut ConreteApp { + self.app.as_any_mut().downcast_mut::().unwrap() + } + pub fn auto_save(&mut self) { let now = now_sec(); let time_since_last_save = now - self.last_save_time; diff --git a/crates/egui_demo_app/src/apps/custom3d_glow.rs b/crates/egui_demo_app/src/apps/custom3d_glow.rs index 5d82d75c244..fe6999b6a5f 100644 --- a/crates/egui_demo_app/src/apps/custom3d_glow.rs +++ b/crates/egui_demo_app/src/apps/custom3d_glow.rs @@ -1,5 +1,8 @@ use std::sync::Arc; +#[cfg(target_arch = "wasm32")] +use core::any::Any; + use eframe::egui_glow; use egui::mutex::Mutex; use egui_glow::glow; @@ -48,6 +51,11 @@ 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 0ef65f2bfb0..1c43b10bf2b 100644 --- a/crates/egui_demo_app/src/apps/custom3d_wgpu.rs +++ b/crates/egui_demo_app/src/apps/custom3d_wgpu.rs @@ -1,5 +1,8 @@ use std::sync::Arc; +#[cfg(target_arch = "wasm32")] +use core::any::Any; + use eframe::{ egui_wgpu::{self, wgpu}, wgpu::util::DeviceExt, @@ -117,6 +120,11 @@ 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 df92e7489f6..69648080670 100644 --- a/crates/egui_demo_app/src/apps/http_app.rs +++ b/crates/egui_demo_app/src/apps/http_app.rs @@ -1,6 +1,9 @@ use egui_extras::RetainedImage; use poll_promise::Promise; +#[cfg(target_arch = "wasm32")] +use core::any::Any; + struct Resource { /// HTTP response response: ehttp::Response, @@ -106,6 +109,11 @@ 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/lib.rs b/crates/egui_demo_app/src/lib.rs index 8ae3f42292b..aafd53ae261 100644 --- a/crates/egui_demo_app/src/lib.rs +++ b/crates/egui_demo_app/src/lib.rs @@ -32,7 +32,6 @@ pub struct WebHandle { #[wasm_bindgen] impl WebHandle { #[wasm_bindgen] - #[cfg(target_arch = "wasm32")] pub fn stop_web(&self) -> Result<(), wasm_bindgen::JsValue> { let mut app = self.handle.lock(); let res = app.destroy(); @@ -43,6 +42,12 @@ impl WebHandle { res } + + #[wasm_bindgen] + pub fn set_some_content_from_javasript(&mut self, _some_data: &str) { + let _app = self.handle.lock().app_mut::(); + // _app.data = some_data; + } } #[cfg(target_arch = "wasm32")] diff --git a/crates/egui_demo_app/src/wrap_app.rs b/crates/egui_demo_app/src/wrap_app.rs index a0d69c50928..c9f820f62fb 100644 --- a/crates/egui_demo_app/src/wrap_app.rs +++ b/crates/egui_demo_app/src/wrap_app.rs @@ -3,6 +3,9 @@ use egui_demo_lib::is_mobile; #[cfg(feature = "glow")] use eframe::glow; +#[cfg(target_arch = "wasm32")] +use core::any::Any; + #[derive(Default)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] struct EasyMarkApp { @@ -13,6 +16,11 @@ 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 + } } // ---------------------------------------------------------------------------- @@ -27,6 +35,11 @@ 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 + } } // ---------------------------------------------------------------------------- @@ -46,6 +59,11 @@ 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 + } } // ---------------------------------------------------------------------------- @@ -70,6 +88,11 @@ impl eframe::App for ColorTestApp { }); }); } + + #[cfg(target_arch = "wasm32")] + fn as_any_mut(&mut self) -> &mut dyn Any { + &mut *self + } } // ---------------------------------------------------------------------------- @@ -225,6 +248,11 @@ impl eframe::App for WrapApp { custom3d.on_exit(gl); } } + + #[cfg(target_arch = "wasm32")] + fn as_any_mut(&mut self) -> &mut dyn Any { + &mut *self + } } impl WrapApp { diff --git a/examples/custom_3d_three-d/src/main.rs b/examples/custom_3d_three-d/src/main.rs index cd310cfaa85..0233bd585b2 100644 --- a/examples/custom_3d_three-d/src/main.rs +++ b/examples/custom_3d_three-d/src/main.rs @@ -70,6 +70,11 @@ 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`].