diff --git a/eframe/src/epi.rs b/eframe/src/epi.rs index a5b32d7d..4bc54f3f 100644 --- a/eframe/src/epi.rs +++ b/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; + /// This is how your app is created. /// /// You can use the [`CreationContext`] to setup egui, restore state, setup OpenGL things, etc. @@ -49,6 +52,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/eframe/src/web/backend.rs b/eframe/src/web/backend.rs index 7c1a37a6..29eebd25 100644 --- a/eframe/src/web/backend.rs +++ b/eframe/src/web/backend.rs @@ -35,7 +35,7 @@ impl WebInput { // ---------------------------------------------------------------------------- -use std::sync::atomic::Ordering::SeqCst; +use std::{any::Any, sync::atomic::Ordering::SeqCst}; /// Stores when to do the next repaint. pub struct NeedRepaint(Mutex); @@ -265,6 +265,10 @@ impl AppRunner { &self.egui_ctx } + pub fn get_app_mut(&mut self) -> &mut dyn Any { + self.app.as_any_mut() + } + pub fn auto_save(&mut self) { let now = now_sec(); let time_since_last_save = now - self.last_save_time; diff --git a/egui_demo_app/src/apps/custom3d_glow.rs b/egui_demo_app/src/apps/custom3d_glow.rs index 9798dc15..3adcead5 100644 --- a/egui_demo_app/src/apps/custom3d_glow.rs +++ b/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; @@ -49,6 +52,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/egui_demo_app/src/apps/custom3d_wgpu.rs b/egui_demo_app/src/apps/custom3d_wgpu.rs index d868a57b..ebb84adf 100644 --- a/egui_demo_app/src/apps/custom3d_wgpu.rs +++ b/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/egui_demo_app/src/apps/http_app.rs b/egui_demo_app/src/apps/http_app.rs index df92e748..69648080 100644 --- a/egui_demo_app/src/apps/http_app.rs +++ b/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/egui_demo_app/src/lib.rs b/egui_demo_app/src/lib.rs index 8ae3f422..ed9a8732 100644 --- a/egui_demo_app/src/lib.rs +++ b/egui_demo_app/src/lib.rs @@ -43,6 +43,25 @@ impl WebHandle { res } + + // helper for mutating original app from javascript + fn with_app(&mut self, func: F) -> () + where + F: Fn(&mut WrapApp) -> (), + { + let mut runner_ref = self.handle.lock(); + let app_ref = runner_ref.get_app_mut(); + let app = app_ref.downcast_mut::().unwrap(); + func(app); + } + + #[wasm_bindgen] + #[cfg(target_arch = "wasm32")] + pub fn set_some_content_from_javasript(&mut self, _some_data: &str) { + self.with_app(|_app| { + // app.data = some_data; + }); + } } #[cfg(target_arch = "wasm32")] diff --git a/egui_demo_app/src/wrap_app.rs b/egui_demo_app/src/wrap_app.rs index 1a844b96..b1078d64 100644 --- a/egui_demo_app/src/wrap_app.rs +++ b/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 + } } // ---------------------------------------------------------------------------- @@ -214,6 +237,11 @@ impl eframe::App for WrapApp { fn on_exit(&mut self, gl: Option<&glow::Context>) { self.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 0ca9eb58..437d3548 100644 --- a/examples/custom_3d_three-d/src/main.rs +++ b/examples/custom_3d_three-d/src/main.rs @@ -47,6 +47,11 @@ impl eframe::App for MyApp { }); }); } + + #[cfg(target_arch = "wasm32")] + fn as_any_mut(&mut self) -> &mut dyn Any { + &mut *self + } } impl MyApp {