mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 21:30:03 -04:00
Make App 'static
This commit is contained in:
@@ -43,8 +43,7 @@ type DynError = Box<dyn std::error::Error + Send + Sync>;
|
|||||||
/// This is how your app is created.
|
/// This is how your app is created.
|
||||||
///
|
///
|
||||||
/// You can use the [`CreationContext`] to setup egui, restore state, setup OpenGL things, etc.
|
/// You can use the [`CreationContext`] to setup egui, restore state, setup OpenGL things, etc.
|
||||||
pub type AppCreator<'app> =
|
pub type AppCreator = Box<dyn FnOnce(&CreationContext<'_>) -> Result<Box<dyn App>, DynError>>;
|
||||||
Box<dyn 'app + FnOnce(&CreationContext<'_>) -> Result<Box<dyn 'app + App>, DynError>>;
|
|
||||||
|
|
||||||
/// Data that is passed to [`AppCreator`] that can be used to setup and initialize your app.
|
/// Data that is passed to [`AppCreator`] that can be used to setup and initialize your app.
|
||||||
pub struct CreationContext<'s> {
|
pub struct CreationContext<'s> {
|
||||||
@@ -131,7 +130,7 @@ impl CreationContext<'_> {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Implement this trait to write apps that can be compiled for both web/wasm and desktop/native using [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe).
|
/// Implement this trait to write apps that can be compiled for both web/wasm and desktop/native using [`eframe`](https://github.com/emilk/egui/tree/main/crates/eframe).
|
||||||
pub trait App {
|
pub trait App: std::any::Any {
|
||||||
/// Called once before each call to [`Self::ui`],
|
/// Called once before each call to [`Self::ui`],
|
||||||
/// and additionally also called when the UI is hidden, but [`egui::Context::request_repaint`] was called.
|
/// and additionally also called when the UI is hidden, but [`egui::Context::request_repaint`] was called.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ pub mod icon_data;
|
|||||||
pub fn run_native(
|
pub fn run_native(
|
||||||
app_name: &str,
|
app_name: &str,
|
||||||
mut native_options: NativeOptions,
|
mut native_options: NativeOptions,
|
||||||
app_creator: AppCreator<'_>,
|
app_creator: AppCreator,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
let renderer = init_native(app_name, &mut native_options);
|
let renderer = init_native(app_name, &mut native_options);
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ pub fn run_native(
|
|||||||
pub fn create_native<'a>(
|
pub fn create_native<'a>(
|
||||||
app_name: &str,
|
app_name: &str,
|
||||||
mut native_options: NativeOptions,
|
mut native_options: NativeOptions,
|
||||||
app_creator: AppCreator<'a>,
|
app_creator: AppCreator,
|
||||||
event_loop: &winit::event_loop::EventLoop<UserEvent>,
|
event_loop: &winit::event_loop::EventLoop<UserEvent>,
|
||||||
) -> EframeWinitApplication<'a> {
|
) -> EframeWinitApplication<'a> {
|
||||||
let renderer = init_native(app_name, &mut native_options);
|
let renderer = init_native(app_name, &mut native_options);
|
||||||
|
|||||||
@@ -45,24 +45,24 @@ use super::{
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Types:
|
// Types:
|
||||||
|
|
||||||
pub struct GlowWinitApp<'app> {
|
pub struct GlowWinitApp {
|
||||||
repaint_proxy: Arc<egui::mutex::Mutex<EventLoopProxy<UserEvent>>>,
|
repaint_proxy: Arc<egui::mutex::Mutex<EventLoopProxy<UserEvent>>>,
|
||||||
app_name: String,
|
app_name: String,
|
||||||
native_options: NativeOptions,
|
native_options: NativeOptions,
|
||||||
running: Option<GlowWinitRunning<'app>>,
|
running: Option<GlowWinitRunning>,
|
||||||
|
|
||||||
// Note that since this `AppCreator` is FnOnce we are currently unable to support
|
// Note that since this `AppCreator` is FnOnce we are currently unable to support
|
||||||
// re-initializing the `GlowWinitRunning` state on Android if the application
|
// re-initializing the `GlowWinitRunning` state on Android if the application
|
||||||
// suspends and resumes.
|
// suspends and resumes.
|
||||||
app_creator: Option<AppCreator<'app>>,
|
app_creator: Option<AppCreator>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State that is initialized when the application is first starts running via
|
/// State that is initialized when the application is first starts running via
|
||||||
/// a Resumed event. On Android this ensures that any graphics state is only
|
/// a Resumed event. On Android this ensures that any graphics state is only
|
||||||
/// initialized once the application has an associated `SurfaceView`.
|
/// initialized once the application has an associated `SurfaceView`.
|
||||||
struct GlowWinitRunning<'app> {
|
struct GlowWinitRunning {
|
||||||
integration: EpiIntegration,
|
integration: EpiIntegration,
|
||||||
app: Box<dyn 'app + App>,
|
app: Box<dyn App>,
|
||||||
|
|
||||||
// These needs to be shared with the immediate viewport renderer, hence the Rc/Arc/RefCells:
|
// These needs to be shared with the immediate viewport renderer, hence the Rc/Arc/RefCells:
|
||||||
glutin: Rc<RefCell<GlutinWindowContext>>,
|
glutin: Rc<RefCell<GlutinWindowContext>>,
|
||||||
@@ -123,12 +123,12 @@ struct Viewport {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
impl<'app> GlowWinitApp<'app> {
|
impl GlowWinitApp {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
event_loop: &EventLoop<UserEvent>,
|
event_loop: &EventLoop<UserEvent>,
|
||||||
app_name: &str,
|
app_name: &str,
|
||||||
native_options: NativeOptions,
|
native_options: NativeOptions,
|
||||||
app_creator: AppCreator<'app>,
|
app_creator: AppCreator,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
profiling::function_scope!();
|
profiling::function_scope!();
|
||||||
Self {
|
Self {
|
||||||
@@ -191,10 +191,7 @@ impl<'app> GlowWinitApp<'app> {
|
|||||||
Ok((glutin_window_context, painter))
|
Ok((glutin_window_context, painter))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_run_state(
|
fn init_run_state(&mut self, event_loop: &ActiveEventLoop) -> Result<&mut GlowWinitRunning> {
|
||||||
&mut self,
|
|
||||||
event_loop: &ActiveEventLoop,
|
|
||||||
) -> Result<&mut GlowWinitRunning<'app>> {
|
|
||||||
profiling::function_scope!();
|
profiling::function_scope!();
|
||||||
|
|
||||||
let storage = if let Some(file) = &self.native_options.persistence_path {
|
let storage = if let Some(file) = &self.native_options.persistence_path {
|
||||||
@@ -290,7 +287,7 @@ impl<'app> GlowWinitApp<'app> {
|
|||||||
let app_creator = std::mem::take(&mut self.app_creator)
|
let app_creator = std::mem::take(&mut self.app_creator)
|
||||||
.expect("Single-use AppCreator has unexpectedly already been taken");
|
.expect("Single-use AppCreator has unexpectedly already been taken");
|
||||||
|
|
||||||
let app: Box<dyn 'app + App> = {
|
let app: Box<dyn App> = {
|
||||||
// Use latest raw_window_handle for eframe compatibility
|
// Use latest raw_window_handle for eframe compatibility
|
||||||
use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _};
|
use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _};
|
||||||
|
|
||||||
@@ -344,7 +341,7 @@ impl<'app> GlowWinitApp<'app> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WinitApp for GlowWinitApp<'_> {
|
impl WinitApp for GlowWinitApp {
|
||||||
fn egui_ctx(&self) -> Option<&egui::Context> {
|
fn egui_ctx(&self) -> Option<&egui::Context> {
|
||||||
self.running.as_ref().map(|r| &r.integration.egui_ctx)
|
self.running.as_ref().map(|r| &r.integration.egui_ctx)
|
||||||
}
|
}
|
||||||
@@ -496,7 +493,7 @@ impl WinitApp for GlowWinitApp<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlowWinitRunning<'_> {
|
impl GlowWinitRunning {
|
||||||
fn run_ui_and_paint(
|
fn run_ui_and_paint(
|
||||||
&mut self,
|
&mut self,
|
||||||
event_loop: &ActiveEventLoop,
|
event_loop: &ActiveEventLoop,
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, winit_app: impl WinitApp) -> R
|
|||||||
pub fn run_glow(
|
pub fn run_glow(
|
||||||
app_name: &str,
|
app_name: &str,
|
||||||
mut native_options: epi::NativeOptions,
|
mut native_options: epi::NativeOptions,
|
||||||
app_creator: epi::AppCreator<'_>,
|
app_creator: epi::AppCreator,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
use super::glow_integration::GlowWinitApp;
|
use super::glow_integration::GlowWinitApp;
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ pub fn run_glow(
|
|||||||
pub fn create_glow<'a>(
|
pub fn create_glow<'a>(
|
||||||
app_name: &str,
|
app_name: &str,
|
||||||
native_options: epi::NativeOptions,
|
native_options: epi::NativeOptions,
|
||||||
app_creator: epi::AppCreator<'a>,
|
app_creator: epi::AppCreator,
|
||||||
event_loop: &EventLoop<UserEvent>,
|
event_loop: &EventLoop<UserEvent>,
|
||||||
) -> impl ApplicationHandler<UserEvent> + 'a {
|
) -> impl ApplicationHandler<UserEvent> + 'a {
|
||||||
use super::glow_integration::GlowWinitApp;
|
use super::glow_integration::GlowWinitApp;
|
||||||
@@ -383,7 +383,7 @@ pub fn create_glow<'a>(
|
|||||||
pub fn run_wgpu(
|
pub fn run_wgpu(
|
||||||
app_name: &str,
|
app_name: &str,
|
||||||
mut native_options: epi::NativeOptions,
|
mut native_options: epi::NativeOptions,
|
||||||
app_creator: epi::AppCreator<'_>,
|
app_creator: epi::AppCreator,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
use super::wgpu_integration::WgpuWinitApp;
|
use super::wgpu_integration::WgpuWinitApp;
|
||||||
|
|
||||||
@@ -404,7 +404,7 @@ pub fn run_wgpu(
|
|||||||
pub fn create_wgpu<'a>(
|
pub fn create_wgpu<'a>(
|
||||||
app_name: &str,
|
app_name: &str,
|
||||||
native_options: epi::NativeOptions,
|
native_options: epi::NativeOptions,
|
||||||
app_creator: epi::AppCreator<'a>,
|
app_creator: epi::AppCreator,
|
||||||
event_loop: &EventLoop<UserEvent>,
|
event_loop: &EventLoop<UserEvent>,
|
||||||
) -> impl ApplicationHandler<UserEvent> + 'a {
|
) -> impl ApplicationHandler<UserEvent> + 'a {
|
||||||
use super::wgpu_integration::WgpuWinitApp;
|
use super::wgpu_integration::WgpuWinitApp;
|
||||||
|
|||||||
@@ -35,26 +35,26 @@ use super::{epi_integration, event_loop_context, winit_integration, winit_integr
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Types:
|
// Types:
|
||||||
|
|
||||||
pub struct WgpuWinitApp<'app> {
|
pub struct WgpuWinitApp {
|
||||||
repaint_proxy: Arc<Mutex<EventLoopProxy<UserEvent>>>,
|
repaint_proxy: Arc<Mutex<EventLoopProxy<UserEvent>>>,
|
||||||
app_name: String,
|
app_name: String,
|
||||||
native_options: NativeOptions,
|
native_options: NativeOptions,
|
||||||
|
|
||||||
/// Set at initialization, then taken and set to `None` in `init_run_state`.
|
/// Set at initialization, then taken and set to `None` in `init_run_state`.
|
||||||
app_creator: Option<AppCreator<'app>>,
|
app_creator: Option<AppCreator>,
|
||||||
|
|
||||||
/// Set when we are actually up and running.
|
/// Set when we are actually up and running.
|
||||||
running: Option<WgpuWinitRunning<'app>>,
|
running: Option<WgpuWinitRunning>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State that is initialized when the application is first starts running via
|
/// State that is initialized when the application is first starts running via
|
||||||
/// a Resumed event. On Android this ensures that any graphics state is only
|
/// a Resumed event. On Android this ensures that any graphics state is only
|
||||||
/// initialized once the application has an associated `SurfaceView`.
|
/// initialized once the application has an associated `SurfaceView`.
|
||||||
struct WgpuWinitRunning<'app> {
|
struct WgpuWinitRunning {
|
||||||
integration: EpiIntegration,
|
integration: EpiIntegration,
|
||||||
|
|
||||||
/// The users application.
|
/// The users application.
|
||||||
app: Box<dyn 'app + App>,
|
app: Box<dyn App>,
|
||||||
|
|
||||||
/// Wrapped in an `Rc<RefCell<…>>` so it can be re-entrantly shared via a weak-pointer.
|
/// Wrapped in an `Rc<RefCell<…>>` so it can be re-entrantly shared via a weak-pointer.
|
||||||
shared: Rc<RefCell<SharedState>>,
|
shared: Rc<RefCell<SharedState>>,
|
||||||
@@ -97,12 +97,12 @@ pub struct Viewport {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
impl<'app> WgpuWinitApp<'app> {
|
impl WgpuWinitApp {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
event_loop: &EventLoop<UserEvent>,
|
event_loop: &EventLoop<UserEvent>,
|
||||||
app_name: &str,
|
app_name: &str,
|
||||||
native_options: NativeOptions,
|
native_options: NativeOptions,
|
||||||
app_creator: AppCreator<'app>,
|
app_creator: AppCreator,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
profiling::function_scope!();
|
profiling::function_scope!();
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ impl<'app> WgpuWinitApp<'app> {
|
|||||||
storage: Option<Box<dyn Storage>>,
|
storage: Option<Box<dyn Storage>>,
|
||||||
window: Window,
|
window: Window,
|
||||||
builder: ViewportBuilder,
|
builder: ViewportBuilder,
|
||||||
) -> crate::Result<&mut WgpuWinitRunning<'app>> {
|
) -> crate::Result<&mut WgpuWinitRunning> {
|
||||||
profiling::function_scope!();
|
profiling::function_scope!();
|
||||||
let mut painter = pollster::block_on(egui_wgpu::winit::Painter::new(
|
let mut painter = pollster::block_on(egui_wgpu::winit::Painter::new(
|
||||||
egui_ctx.clone(),
|
egui_ctx.clone(),
|
||||||
@@ -341,7 +341,7 @@ impl<'app> WgpuWinitApp<'app> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WinitApp for WgpuWinitApp<'_> {
|
impl WinitApp for WgpuWinitApp {
|
||||||
fn egui_ctx(&self) -> Option<&egui::Context> {
|
fn egui_ctx(&self) -> Option<&egui::Context> {
|
||||||
self.running.as_ref().map(|r| &r.integration.egui_ctx)
|
self.running.as_ref().map(|r| &r.integration.egui_ctx)
|
||||||
}
|
}
|
||||||
@@ -510,7 +510,7 @@ impl WinitApp for WgpuWinitApp<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuWinitRunning<'_> {
|
impl WgpuWinitRunning {
|
||||||
/// Saves the application state
|
/// Saves the application state
|
||||||
fn save(&mut self) {
|
fn save(&mut self) {
|
||||||
let shared = self.shared.borrow();
|
let shared = self.shared.borrow();
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ impl AppRunner {
|
|||||||
pub async fn new(
|
pub async fn new(
|
||||||
canvas: web_sys::HtmlCanvasElement,
|
canvas: web_sys::HtmlCanvasElement,
|
||||||
web_options: crate::WebOptions,
|
web_options: crate::WebOptions,
|
||||||
app_creator: epi::AppCreator<'static>,
|
app_creator: epi::AppCreator,
|
||||||
text_agent: TextAgent,
|
text_agent: TextAgent,
|
||||||
) -> Result<Self, String> {
|
) -> Result<Self, String> {
|
||||||
let egui_ctx = egui::Context::default();
|
let egui_ctx = egui::Context::default();
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ impl WebRunner {
|
|||||||
&self,
|
&self,
|
||||||
canvas: web_sys::HtmlCanvasElement,
|
canvas: web_sys::HtmlCanvasElement,
|
||||||
web_options: crate::WebOptions,
|
web_options: crate::WebOptions,
|
||||||
app_creator: epi::AppCreator<'static>,
|
app_creator: epi::AppCreator,
|
||||||
) -> Result<(), JsValue> {
|
) -> Result<(), JsValue> {
|
||||||
self.destroy();
|
self.destroy();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user