From d8ad776c295884aedc1e7e266833f77f8cd21366 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 25 Mar 2022 19:58:00 +0100 Subject: [PATCH 1/6] Add Frame::storage() to get access to the Storage from App::update --- egui-winit/src/epi.rs | 69 +++++++++++-------- egui_demo_lib/src/apps/color_test.rs | 2 +- egui_demo_lib/src/apps/demo/app.rs | 2 +- egui_demo_lib/src/apps/fractal_clock.rs | 2 +- egui_demo_lib/src/apps/http_app.rs | 4 +- egui_demo_lib/src/backend_panel.rs | 6 +- .../src/easy_mark/easy_mark_editor.rs | 2 +- egui_demo_lib/src/wrap_app.rs | 4 +- egui_glow/src/epi_backend.rs | 18 +++-- egui_web/src/backend.rs | 15 ++-- egui_web/src/lib.rs | 6 +- epi/src/lib.rs | 69 +++++++++---------- 12 files changed, 104 insertions(+), 95 deletions(-) diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index 1a82de178d4..80f361aba85 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -125,7 +125,6 @@ pub fn handle_app_output( /// For loading/saving app state and/or egui memory to disk. pub struct Persistence { - storage: Option>, last_auto_save: instant::Instant, } @@ -136,7 +135,7 @@ impl Persistence { #[cfg(feature = "persistence")] const WINDOW_KEY: &'static str = "window"; - pub fn from_app_name(app_name: &str) -> Self { + pub fn from_app_name(app_name: &str) -> (Option>, Self) { fn create_storage(_app_name: &str) -> Option> { #[cfg(feature = "persistence")] if let Some(storage) = epi::file_storage::FileStorage::from_app_name(_app_name) { @@ -145,72 +144,75 @@ impl Persistence { None } - Self { - storage: create_storage(app_name), - last_auto_save: instant::Instant::now(), - } - } - - pub fn storage(&self) -> Option<&dyn epi::Storage> { - self.storage.as_deref() + let storage = create_storage(app_name); + ( + storage, + Self { + last_auto_save: instant::Instant::now(), + }, + ) } #[cfg(feature = "persistence")] - pub fn load_window_settings(&self) -> Option { - epi::get_value(&**self.storage.as_ref()?, Self::WINDOW_KEY) + pub fn load_window_settings( + &self, + storage: Option<&dyn epi::Storage>, + ) -> Option { + epi::get_value(&**storage.as_ref()?, Self::WINDOW_KEY) } #[cfg(not(feature = "persistence"))] - pub fn load_window_settings(&self) -> Option { + pub fn load_window_settings( + &self, + _storage: Option<&dyn epi::Storage>, + ) -> Option { None } #[cfg(feature = "persistence")] - pub fn load_memory(&self) -> Option { - epi::get_value(&**self.storage.as_ref()?, Self::EGUI_MEMORY_KEY) + pub fn load_memory(&self, storage: Option<&dyn epi::Storage>) -> Option { + epi::get_value(&**storage.as_ref()?, Self::EGUI_MEMORY_KEY) } #[cfg(not(feature = "persistence"))] - pub fn load_memory(&self) -> Option { + pub fn load_memory(&self, _storage: Option<&dyn epi::Storage>) -> Option { None } pub fn save( &mut self, + _storage: Option<&mut dyn epi::Storage>, _app: &mut dyn epi::App, _egui_ctx: &egui::Context, _window: &winit::window::Window, ) { #[cfg(feature = "persistence")] - if let Some(storage) = &mut self.storage { + if let Some(storage) = _storage { if _app.persist_native_window() { epi::set_value( - storage.as_mut(), + storage, Self::WINDOW_KEY, &crate::WindowSettings::from_display(_window), ); } if _app.persist_egui_memory() { - epi::set_value( - storage.as_mut(), - Self::EGUI_MEMORY_KEY, - &*_egui_ctx.memory(), - ); + epi::set_value(storage, Self::EGUI_MEMORY_KEY, &*_egui_ctx.memory()); } - _app.save(storage.as_mut()); + _app.save(storage); storage.flush(); } } pub fn maybe_autosave( &mut self, + storage: Option<&mut dyn epi::Storage>, app: &mut dyn epi::App, egui_ctx: &egui::Context, window: &winit::window::Window, ) { let now = instant::Instant::now(); if now - self.last_auto_save > app.auto_save_interval() { - self.save(app, egui_ctx, window); + self.save(storage, app, egui_ctx, window); self.last_auto_save = now; } } @@ -235,11 +237,14 @@ impl EpiIntegration { integration_name: &'static str, max_texture_side: usize, window: &winit::window::Window, + storage: Option>, persistence: crate::epi::Persistence, ) -> Self { let egui_ctx = egui::Context::default(); - *egui_ctx.memory() = persistence.load_memory().unwrap_or_default(); + *egui_ctx.memory() = persistence + .load_memory(storage.as_deref()) + .unwrap_or_default(); let prefer_dark_mode = prefer_dark_mode(); @@ -252,6 +257,7 @@ impl EpiIntegration { native_pixels_per_point: Some(crate::native_pixels_per_point(window)), }, output: Default::default(), + storage, }); if prefer_dark_mode == Some(true) { @@ -311,7 +317,7 @@ impl EpiIntegration { let raw_input = self.egui_winit.take_egui_input(window); let full_output = self.egui_ctx.run(raw_input, |egui_ctx| { - app.update(egui_ctx, &self.frame); + app.update(egui_ctx, &mut self.frame); }); self.pending_full_output.append(full_output); let full_output = std::mem::take(&mut self.pending_full_output); @@ -327,7 +333,7 @@ impl EpiIntegration { } let frame_time = (instant::Instant::now() - frame_start).as_secs_f64() as f32; - self.frame.lock().info.cpu_usage = Some(frame_time); + self.frame.0.info.cpu_usage = Some(frame_time); full_output } @@ -342,8 +348,11 @@ impl EpiIntegration { } pub fn maybe_autosave(&mut self, app: &mut dyn epi::App, window: &winit::window::Window) { - self.persistence - .maybe_autosave(&mut *app, &self.egui_ctx, window); + let storage = self.frame.0.storage.as_deref_mut(); + if let Some(storage) = storage { + self.persistence + .maybe_autosave(Some(storage), &mut *app, &self.egui_ctx, window); + } } } diff --git a/egui_demo_lib/src/apps/color_test.rs b/egui_demo_lib/src/apps/color_test.rs index 4126026d27c..1fb2188d315 100644 --- a/egui_demo_lib/src/apps/color_test.rs +++ b/egui_demo_lib/src/apps/color_test.rs @@ -30,7 +30,7 @@ impl Default for ColorTest { } impl epi::App for ColorTest { - fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) { + fn update(&mut self, ctx: &egui::Context, frame: &mut epi::Frame) { egui::CentralPanel::default().show(ctx, |ui| { if frame.is_web() { ui.label( diff --git a/egui_demo_lib/src/apps/demo/app.rs b/egui_demo_lib/src/apps/demo/app.rs index c01aa8b9cfb..5a74e1ab44f 100644 --- a/egui_demo_lib/src/apps/demo/app.rs +++ b/egui_demo_lib/src/apps/demo/app.rs @@ -6,7 +6,7 @@ pub struct DemoApp { } impl epi::App for DemoApp { - fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut epi::Frame) { self.demo_windows.ui(ctx); } } diff --git a/egui_demo_lib/src/apps/fractal_clock.rs b/egui_demo_lib/src/apps/fractal_clock.rs index 51a03f4c938..854df99d473 100644 --- a/egui_demo_lib/src/apps/fractal_clock.rs +++ b/egui_demo_lib/src/apps/fractal_clock.rs @@ -33,7 +33,7 @@ impl Default for FractalClock { } impl epi::App for FractalClock { - fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut epi::Frame) { egui::CentralPanel::default() .frame(Frame::dark_canvas(&ctx.style())) .show(ctx, |ui| self.ui(ui, crate::seconds_since_midnight())); diff --git a/egui_demo_lib/src/apps/http_app.rs b/egui_demo_lib/src/apps/http_app.rs index a2c9097c777..db81a5172e7 100644 --- a/egui_demo_lib/src/apps/http_app.rs +++ b/egui_demo_lib/src/apps/http_app.rs @@ -54,7 +54,7 @@ impl Default for HttpApp { } impl epi::App for HttpApp { - fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) { + fn update(&mut self, ctx: &egui::Context, frame: &mut epi::Frame) { egui::TopBottomPanel::bottom("http_bottom").show(ctx, |ui| { let layout = egui::Layout::top_down(egui::Align::Center).with_main_justify(true); ui.allocate_ui_with_layout(ui.available_size(), layout, |ui| { @@ -108,7 +108,7 @@ impl epi::App for HttpApp { } } -fn ui_url(ui: &mut egui::Ui, frame: &epi::Frame, url: &mut String) -> bool { +fn ui_url(ui: &mut egui::Ui, frame: &mut epi::Frame, url: &mut String) -> bool { let mut trigger_fetch = false; ui.horizontal(|ui| { diff --git a/egui_demo_lib/src/backend_panel.rs b/egui_demo_lib/src/backend_panel.rs index 0daa3a45a75..1b5bc1bd225 100644 --- a/egui_demo_lib/src/backend_panel.rs +++ b/egui_demo_lib/src/backend_panel.rs @@ -73,7 +73,7 @@ impl Default for BackendPanel { } impl BackendPanel { - pub fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) { + pub fn update(&mut self, ctx: &egui::Context, frame: &mut epi::Frame) { self.frame_history .on_new_frame(ctx.input().time, frame.info().cpu_usage); @@ -87,7 +87,7 @@ impl BackendPanel { self.egui_windows.windows(ctx); } - pub fn ui(&mut self, ui: &mut egui::Ui, frame: &epi::Frame) { + pub fn ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame) { egui::trace!(ui); ui.vertical_centered(|ui| { ui.heading("💻 Backend"); @@ -142,7 +142,7 @@ impl BackendPanel { } } - fn integration_ui(&mut self, ui: &mut egui::Ui, frame: &epi::Frame) { + fn integration_ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame) { if frame.is_web() { ui.label("egui is an immediate mode GUI written in Rust, compiled to WebAssembly, rendered with WebGL."); ui.label( diff --git a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs index 30350e8428a..c9374cfece5 100644 --- a/egui_demo_lib/src/easy_mark/easy_mark_editor.rs +++ b/egui_demo_lib/src/easy_mark/easy_mark_editor.rs @@ -30,7 +30,7 @@ impl Default for EasyMarkEditor { } impl epi::App for EasyMarkEditor { - fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut epi::Frame) { egui::TopBottomPanel::bottom("easy_mark_bottom").show(ctx, |ui| { let layout = egui::Layout::top_down(egui::Align::Center).with_main_justify(true); ui.allocate_ui_with_layout(ui.available_size(), layout, |ui| { diff --git a/egui_demo_lib/src/wrap_app.rs b/egui_demo_lib/src/wrap_app.rs index e80240e4749..5b8ef4d1c38 100644 --- a/egui_demo_lib/src/wrap_app.rs +++ b/egui_demo_lib/src/wrap_app.rs @@ -69,7 +69,7 @@ impl epi::App for WrapApp { egui::Rgba::TRANSPARENT // we set a `CentralPanel` fill color in `demo_windows.rs` } - fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) { + fn update(&mut self, ctx: &egui::Context, frame: &mut epi::Frame) { if let Some(web_info) = frame.info().web_info.as_ref() { if let Some(anchor) = web_info.location.hash.strip_prefix('#') { self.selected_anchor = anchor.to_owned(); @@ -130,7 +130,7 @@ impl epi::App for WrapApp { } impl WrapApp { - fn bar_contents(&mut self, ui: &mut egui::Ui, frame: &epi::Frame) { + fn bar_contents(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame) { // A menu-bar is a horizontal layout with some special styles applied. // egui::menu::bar(ui, |ui| { ui.horizontal_wrapped(|ui| { diff --git a/egui_glow/src/epi_backend.rs b/egui_glow/src/epi_backend.rs index e9b1cf7411d..a1cdf06da9c 100644 --- a/egui_glow/src/epi_backend.rs +++ b/egui_glow/src/epi_backend.rs @@ -37,8 +37,8 @@ pub use epi::NativeOptions; /// Run an egui app #[allow(unsafe_code)] pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi::AppCreator) -> ! { - let persistence = egui_winit::epi::Persistence::from_app_name(app_name); - let window_settings = persistence.load_window_settings(); + let (storage, persistence) = egui_winit::epi::Persistence::from_app_name(app_name); + let window_settings = persistence.load_window_settings(storage.as_deref()); let window_builder = egui_winit::epi::window_builder(native_options, &window_settings).with_title(app_name); let event_loop = winit::event_loop::EventLoop::with_user_event(); @@ -52,6 +52,7 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi "egui_glow", painter.max_texture_side(), gl_window.window(), + storage, persistence, ); @@ -65,7 +66,7 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi let mut app = app_creator(&epi::CreationContext { egui_ctx: integration.egui_ctx.clone(), integration_info: integration.frame.info(), - storage: integration.persistence.storage(), + storage: integration.frame.storage(), gl: gl.clone(), }); @@ -154,9 +155,14 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi gl_window.window().request_redraw(); // TODO: ask egui if the events warrants a repaint instead } winit::event::Event::LoopDestroyed => { - integration - .persistence - .save(&mut *app, &integration.egui_ctx, gl_window.window()); + if let Some(storage) = integration.frame.storage_mut() { + integration.persistence.save( + Some(storage), + &mut *app, + &integration.egui_ctx, + gl_window.window(), + ); + } app.on_exit(&gl); painter.destroy(); } diff --git a/egui_web/src/backend.rs b/egui_web/src/backend.rs index 0ea9c8c0805..56298fb53be 100644 --- a/egui_web/src/backend.rs +++ b/egui_web/src/backend.rs @@ -130,7 +130,6 @@ pub struct AppRunner { pub(crate) input: WebInput, app: Box, pub(crate) needs_repaint: std::sync::Arc, - storage: LocalStorage, last_save_time: f64, screen_reader: crate::screen_reader::ScreenReader, pub(crate) text_cursor_pos: Option, @@ -155,6 +154,7 @@ impl AppRunner { native_pixels_per_point: Some(native_pixels_per_point()), }, output: Default::default(), + storage: Some(Box::new(LocalStorage::default())), }); let needs_repaint: std::sync::Arc = Default::default(); @@ -175,12 +175,10 @@ impl AppRunner { egui_ctx.set_visuals(egui::Visuals::light()); } - let storage = LocalStorage::default(); - let app = app_creator(&epi::CreationContext { egui_ctx: egui_ctx.clone(), integration_info: frame.info(), - storage: Some(&storage), + storage: frame.storage(), gl: painter.painter.gl().clone(), }); @@ -191,7 +189,6 @@ impl AppRunner { input: Default::default(), app, needs_repaint, - storage, last_save_time: now_sec(), screen_reader: Default::default(), text_cursor_pos: None, @@ -216,7 +213,9 @@ impl AppRunner { if self.app.persist_egui_memory() { save_memory(&self.egui_ctx); } - self.app.save(&mut self.storage); + if let Some(storage) = self.frame.storage_mut() { + self.app.save(storage); + } self.last_save_time = now; } } @@ -247,7 +246,7 @@ impl AppRunner { let raw_input = self.input.new_frame(canvas_size); let full_output = self.egui_ctx.run(raw_input, |egui_ctx| { - self.app.update(egui_ctx, &self.frame); + self.app.update(egui_ctx, &mut self.frame); }); let egui::FullOutput { platform_output, @@ -271,7 +270,7 @@ impl AppRunner { } = app_output; } - self.frame.lock().info.cpu_usage = Some((now_sec() - frame_start) as f32); + self.frame.0.info.cpu_usage = Some((now_sec() - frame_start) as f32); Ok((needs_repaint, clipped_primitives)) } diff --git a/egui_web/src/lib.rs b/egui_web/src/lib.rs index c0bc1905d52..e2a968482d6 100644 --- a/egui_web/src/lib.rs +++ b/egui_web/src/lib.rs @@ -509,11 +509,9 @@ fn install_document_events(runner_container: &AppRunnerContainer) -> Result<(), runner_container.add_event_listener( &document, "hashchange", - |_: web_sys::Event, runner_lock| { - let mut frame_lock = runner_lock.frame.lock(); - + |_: web_sys::Event, mut runner_lock| { // `epi::Frame::info(&self)` clones `epi::IntegrationInfo`, but we need to modify the original here - if let Some(web_info) = &mut frame_lock.info.web_info { + if let Some(web_info) = &mut runner_lock.frame.0.info.web_info { web_info.location.hash = location_hash(); } }, diff --git a/epi/src/lib.rs b/epi/src/lib.rs index dac19301796..002f878d404 100644 --- a/epi/src/lib.rs +++ b/epi/src/lib.rs @@ -15,8 +15,6 @@ pub mod file_storage; pub use egui; // Re-export for user convenience pub use glow; // Re-export for user convenience -use std::sync::{Arc, Mutex}; - /// The is is how your app is created. /// /// You can use the [`CreationContext`] to setup egui, restore state, setup OpenGL things, etc. @@ -50,10 +48,10 @@ pub trait App { /// /// Put your widgets into a [`egui::SidePanel`], [`egui::TopBottomPanel`], [`egui::CentralPanel`], [`egui::Window`] or [`egui::Area`]. /// - /// The [`egui::Context`] and [`Frame`] can be cloned and saved if you like. + /// The [`egui::Context`] can be cloned and saved if you like. /// /// 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: &Frame); + fn update(&mut self, ctx: &egui::Context, frame: &mut Frame); /// Called on shutdown, and perhaps at regular intervals. Allows you to save state. /// @@ -252,76 +250,72 @@ pub struct IconData { /// allocate textures, and change settings (e.g. window size). /// /// [`Frame`] is cheap to clone and is safe to pass to other threads. -#[derive(Clone)] -pub struct Frame(pub Arc>); +pub struct Frame(pub backend::FrameData); impl Frame { /// Create a `Frame` - called by the integration. #[doc(hidden)] pub fn new(frame_data: backend::FrameData) -> Self { - Self(Arc::new(Mutex::new(frame_data))) - } - - /// Access the underlying [`backend::FrameData`]. - #[doc(hidden)] - #[inline] - pub fn lock(&self) -> std::sync::MutexGuard<'_, backend::FrameData> { - self.0.lock().unwrap() + Self(frame_data) } /// True if you are in a web environment. pub fn is_web(&self) -> bool { - self.lock().info.web_info.is_some() + self.0.info.web_info.is_some() } /// Information about the integration. pub fn info(&self) -> IntegrationInfo { - self.lock().info.clone() + self.0.info.clone() + } + + /// A place where you can store custom data in a way that persists when you restart the app. + pub fn storage(&self) -> Option<&dyn Storage> { + self.0.storage.as_deref() + } + + /// A place where you can store custom data in a way that persists when you restart the app. + pub fn storage_mut(&mut self) -> Option<&mut (dyn Storage + 'static)> { + self.0.storage.as_deref_mut() } /// Signal the app to stop/exit/quit the app (only works for native apps, not web apps). /// The framework will not quit immediately, but at the end of the this frame. - pub fn quit(&self) { - self.lock().output.quit = true; + pub fn quit(&mut self) { + self.0.output.quit = true; } /// Set the desired inner size of the window (in egui points). - pub fn set_window_size(&self, size: egui::Vec2) { - self.lock().output.window_size = Some(size); + pub fn set_window_size(&mut self, size: egui::Vec2) { + self.0.output.window_size = Some(size); } /// Set the desired title of the window. - pub fn set_window_title(&self, title: &str) { - self.lock().output.window_title = Some(title.to_owned()); + pub fn set_window_title(&mut self, title: &str) { + self.0.output.window_title = Some(title.to_owned()); } /// Set whether to show window decorations (i.e. a frame around you app). /// If false it will be difficult to move and resize the app. - pub fn set_decorations(&self, decorated: bool) { - self.lock().output.decorated = Some(decorated); + pub fn set_decorations(&mut self, decorated: bool) { + self.0.output.decorated = Some(decorated); } /// When called, the native window will follow the /// movement of the cursor while the primary mouse button is down. /// /// Does not work on the web. - pub fn drag_window(&self) { - self.lock().output.drag_window = true; + pub fn drag_window(&mut self) { + self.0.output.drag_window = true; } /// for integrations only: call once per frame - pub fn take_app_output(&self) -> crate::backend::AppOutput { - std::mem::take(&mut self.lock().output) + #[doc(hidden)] + pub fn take_app_output(&mut self) -> crate::backend::AppOutput { + std::mem::take(&mut self.0.output) } } -#[cfg(test)] -#[test] -fn frame_impl_send_sync() { - fn assert_send_sync() {} - assert_send_sync::(); -} - /// Information about the web environment (if applicable). #[derive(Clone, Debug)] pub struct WebInfo { @@ -474,10 +468,13 @@ pub mod backend { /// Where the app can issue commands back to the integration. pub output: AppOutput, + + /// A place where you can store custom data in a way that persists when you restart the app. + pub storage: Option>, } /// Action that can be taken by the user app. - #[derive(Default)] + #[derive(Clone, Debug, Default)] #[must_use] pub struct AppOutput { /// Set to `true` to stop the app. From f145efa324c2894afa0b6a7e7fce029635715e00 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 25 Mar 2022 20:00:02 +0100 Subject: [PATCH 2/6] Remove FrameData --- egui-winit/src/epi.rs | 8 +++---- egui_web/src/backend.rs | 6 ++--- egui_web/src/lib.rs | 2 +- epi/src/lib.rs | 51 +++++++++++++++++++---------------------- 4 files changed, 31 insertions(+), 36 deletions(-) diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index 80f361aba85..020f0d20b12 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -248,7 +248,7 @@ impl EpiIntegration { let prefer_dark_mode = prefer_dark_mode(); - let frame = epi::Frame::new(epi::backend::FrameData { + let frame = epi::Frame { info: epi::IntegrationInfo { name: integration_name, web_info: None, @@ -258,7 +258,7 @@ impl EpiIntegration { }, output: Default::default(), storage, - }); + }; if prefer_dark_mode == Some(true) { egui_ctx.set_visuals(egui::Visuals::dark()); @@ -333,7 +333,7 @@ impl EpiIntegration { } let frame_time = (instant::Instant::now() - frame_start).as_secs_f64() as f32; - self.frame.0.info.cpu_usage = Some(frame_time); + self.frame.info.cpu_usage = Some(frame_time); full_output } @@ -348,7 +348,7 @@ impl EpiIntegration { } pub fn maybe_autosave(&mut self, app: &mut dyn epi::App, window: &winit::window::Window) { - let storage = self.frame.0.storage.as_deref_mut(); + let storage = self.frame.storage.as_deref_mut(); if let Some(storage) = storage { self.persistence .maybe_autosave(Some(storage), &mut *app, &self.egui_ctx, window); diff --git a/egui_web/src/backend.rs b/egui_web/src/backend.rs index 56298fb53be..29915523092 100644 --- a/egui_web/src/backend.rs +++ b/egui_web/src/backend.rs @@ -143,7 +143,7 @@ impl AppRunner { let prefer_dark_mode = crate::prefer_dark_mode(); - let frame = epi::Frame::new(epi::backend::FrameData { + let frame = epi::Frame { info: epi::IntegrationInfo { name: "egui_web", web_info: Some(epi::WebInfo { @@ -155,7 +155,7 @@ impl AppRunner { }, output: Default::default(), storage: Some(Box::new(LocalStorage::default())), - }); + }; let needs_repaint: std::sync::Arc = Default::default(); @@ -270,7 +270,7 @@ impl AppRunner { } = app_output; } - self.frame.0.info.cpu_usage = Some((now_sec() - frame_start) as f32); + self.frame.info.cpu_usage = Some((now_sec() - frame_start) as f32); Ok((needs_repaint, clipped_primitives)) } diff --git a/egui_web/src/lib.rs b/egui_web/src/lib.rs index e2a968482d6..1143bbbab0e 100644 --- a/egui_web/src/lib.rs +++ b/egui_web/src/lib.rs @@ -511,7 +511,7 @@ fn install_document_events(runner_container: &AppRunnerContainer) -> Result<(), "hashchange", |_: web_sys::Event, mut runner_lock| { // `epi::Frame::info(&self)` clones `epi::IntegrationInfo`, but we need to modify the original here - if let Some(web_info) = &mut runner_lock.frame.0.info.web_info { + if let Some(web_info) = &mut runner_lock.frame.info.web_info { web_info.location.hash = location_hash(); } }, diff --git a/epi/src/lib.rs b/epi/src/lib.rs index 002f878d404..4a8ea63666f 100644 --- a/epi/src/lib.rs +++ b/epi/src/lib.rs @@ -250,55 +250,61 @@ pub struct IconData { /// allocate textures, and change settings (e.g. window size). /// /// [`Frame`] is cheap to clone and is safe to pass to other threads. -pub struct Frame(pub backend::FrameData); +pub struct Frame { + /// Information about the integration. + #[doc(hidden)] + pub info: IntegrationInfo, -impl Frame { - /// Create a `Frame` - called by the integration. + /// Where the app can issue commands back to the integration. #[doc(hidden)] - pub fn new(frame_data: backend::FrameData) -> Self { - Self(frame_data) - } + pub output: backend::AppOutput, + /// A place where you can store custom data in a way that persists when you restart the app. + #[doc(hidden)] + pub storage: Option>, +} + +impl Frame { /// True if you are in a web environment. pub fn is_web(&self) -> bool { - self.0.info.web_info.is_some() + self.info.web_info.is_some() } /// Information about the integration. pub fn info(&self) -> IntegrationInfo { - self.0.info.clone() + self.info.clone() } /// A place where you can store custom data in a way that persists when you restart the app. pub fn storage(&self) -> Option<&dyn Storage> { - self.0.storage.as_deref() + self.storage.as_deref() } /// A place where you can store custom data in a way that persists when you restart the app. pub fn storage_mut(&mut self) -> Option<&mut (dyn Storage + 'static)> { - self.0.storage.as_deref_mut() + self.storage.as_deref_mut() } /// Signal the app to stop/exit/quit the app (only works for native apps, not web apps). /// The framework will not quit immediately, but at the end of the this frame. pub fn quit(&mut self) { - self.0.output.quit = true; + self.output.quit = true; } /// Set the desired inner size of the window (in egui points). pub fn set_window_size(&mut self, size: egui::Vec2) { - self.0.output.window_size = Some(size); + self.output.window_size = Some(size); } /// Set the desired title of the window. pub fn set_window_title(&mut self, title: &str) { - self.0.output.window_title = Some(title.to_owned()); + self.output.window_title = Some(title.to_owned()); } /// Set whether to show window decorations (i.e. a frame around you app). /// If false it will be difficult to move and resize the app. pub fn set_decorations(&mut self, decorated: bool) { - self.0.output.decorated = Some(decorated); + self.output.decorated = Some(decorated); } /// When called, the native window will follow the @@ -306,13 +312,13 @@ impl Frame { /// /// Does not work on the web. pub fn drag_window(&mut self) { - self.0.output.drag_window = true; + self.output.drag_window = true; } /// for integrations only: call once per frame #[doc(hidden)] pub fn take_app_output(&mut self) -> crate::backend::AppOutput { - std::mem::take(&mut self.0.output) + std::mem::take(&mut self.output) } } @@ -458,21 +464,10 @@ pub const APP_KEY: &str = "app"; // ---------------------------------------------------------------------------- /// You only need to look here if you are writing a backend for `epi`. +#[doc(hidden)] pub mod backend { use super::*; - /// The data required by [`Frame`] each frame. - pub struct FrameData { - /// Information about the integration. - pub info: IntegrationInfo, - - /// Where the app can issue commands back to the integration. - pub output: AppOutput, - - /// A place where you can store custom data in a way that persists when you restart the app. - pub storage: Option>, - } - /// Action that can be taken by the user app. #[derive(Clone, Debug, Default)] #[must_use] From 3fa4356134259f56537302be0acf3af20a191ebd Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 25 Mar 2022 20:09:16 +0100 Subject: [PATCH 3/6] Refactor: remove struct Pesistence --- egui-winit/src/epi.rs | 155 +++++++++++++---------------------- egui_glow/src/epi_backend.rs | 14 +--- 2 files changed, 58 insertions(+), 111 deletions(-) diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index 020f0d20b12..d295faea11a 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -124,98 +124,12 @@ pub fn handle_app_output( // ---------------------------------------------------------------------------- /// For loading/saving app state and/or egui memory to disk. -pub struct Persistence { - last_auto_save: instant::Instant, -} - -#[allow(clippy::unused_self)] -impl Persistence { +pub fn create_storage(_app_name: &str) -> Option> { #[cfg(feature = "persistence")] - const EGUI_MEMORY_KEY: &'static str = "egui"; - #[cfg(feature = "persistence")] - const WINDOW_KEY: &'static str = "window"; - - pub fn from_app_name(app_name: &str) -> (Option>, Self) { - fn create_storage(_app_name: &str) -> Option> { - #[cfg(feature = "persistence")] - if let Some(storage) = epi::file_storage::FileStorage::from_app_name(_app_name) { - return Some(Box::new(storage)); - } - None - } - - let storage = create_storage(app_name); - ( - storage, - Self { - last_auto_save: instant::Instant::now(), - }, - ) - } - - #[cfg(feature = "persistence")] - pub fn load_window_settings( - &self, - storage: Option<&dyn epi::Storage>, - ) -> Option { - epi::get_value(&**storage.as_ref()?, Self::WINDOW_KEY) - } - - #[cfg(not(feature = "persistence"))] - pub fn load_window_settings( - &self, - _storage: Option<&dyn epi::Storage>, - ) -> Option { - None - } - - #[cfg(feature = "persistence")] - pub fn load_memory(&self, storage: Option<&dyn epi::Storage>) -> Option { - epi::get_value(&**storage.as_ref()?, Self::EGUI_MEMORY_KEY) - } - - #[cfg(not(feature = "persistence"))] - pub fn load_memory(&self, _storage: Option<&dyn epi::Storage>) -> Option { - None - } - - pub fn save( - &mut self, - _storage: Option<&mut dyn epi::Storage>, - _app: &mut dyn epi::App, - _egui_ctx: &egui::Context, - _window: &winit::window::Window, - ) { - #[cfg(feature = "persistence")] - if let Some(storage) = _storage { - if _app.persist_native_window() { - epi::set_value( - storage, - Self::WINDOW_KEY, - &crate::WindowSettings::from_display(_window), - ); - } - if _app.persist_egui_memory() { - epi::set_value(storage, Self::EGUI_MEMORY_KEY, &*_egui_ctx.memory()); - } - _app.save(storage); - storage.flush(); - } - } - - pub fn maybe_autosave( - &mut self, - storage: Option<&mut dyn epi::Storage>, - app: &mut dyn epi::App, - egui_ctx: &egui::Context, - window: &winit::window::Window, - ) { - let now = instant::Instant::now(); - if now - self.last_auto_save > app.auto_save_interval() { - self.save(storage, app, egui_ctx, window); - self.last_auto_save = now; - } + if let Some(storage) = epi::file_storage::FileStorage::from_app_name(_app_name) { + return Some(Box::new(storage)); } + None } // ---------------------------------------------------------------------------- @@ -223,7 +137,7 @@ impl Persistence { /// Everything needed to make a winit-based integration for [`epi`]. pub struct EpiIntegration { pub frame: epi::Frame, - pub persistence: crate::epi::Persistence, + last_auto_save: instant::Instant, pub egui_ctx: egui::Context, pending_full_output: egui::FullOutput, egui_winit: crate::State, @@ -238,13 +152,10 @@ impl EpiIntegration { max_texture_side: usize, window: &winit::window::Window, storage: Option>, - persistence: crate::epi::Persistence, ) -> Self { let egui_ctx = egui::Context::default(); - *egui_ctx.memory() = persistence - .load_memory(storage.as_deref()) - .unwrap_or_default(); + *egui_ctx.memory() = load_memory(storage.as_deref()).unwrap_or_default(); let prefer_dark_mode = prefer_dark_mode(); @@ -268,7 +179,7 @@ impl EpiIntegration { Self { frame, - persistence, + last_auto_save: instant::Instant::now(), egui_ctx, egui_winit: crate::State::new(max_texture_side, window), pending_full_output: Default::default(), @@ -347,15 +258,59 @@ impl EpiIntegration { .handle_platform_output(window, &self.egui_ctx, platform_output); } + // ------------------------------------------------------------------------ + // Persistance stuff: + pub fn maybe_autosave(&mut self, app: &mut dyn epi::App, window: &winit::window::Window) { - let storage = self.frame.storage.as_deref_mut(); - if let Some(storage) = storage { - self.persistence - .maybe_autosave(Some(storage), &mut *app, &self.egui_ctx, window); + let now = instant::Instant::now(); + if now - self.last_auto_save > app.auto_save_interval() { + self.save(app, window); + self.last_auto_save = now; + } + } + + pub fn save(&mut self, _app: &mut dyn epi::App, _window: &winit::window::Window) { + #[cfg(feature = "persistence")] + if let Some(storage) = self.frame.storage_mut() { + if _app.persist_native_window() { + epi::set_value( + storage, + STORAGE_WINDOW_KEY, + &crate::WindowSettings::from_display(_window), + ); + } + if _app.persist_egui_memory() { + epi::set_value(storage, STORAGE_EGUI_MEMORY_KEY, &*self.egui_ctx.memory()); + } + _app.save(storage); + storage.flush(); } } } +#[cfg(feature = "persistence")] +const STORAGE_EGUI_MEMORY_KEY: &'static str = "egui"; +#[cfg(feature = "persistence")] +const STORAGE_WINDOW_KEY: &'static str = "window"; + +pub fn load_window_settings(_storage: Option<&dyn epi::Storage>) -> Option { + #[cfg(feature = "persistence")] + { + epi::get_value(_storage?, STORAGE_WINDOW_KEY) + } + #[cfg(not(feature = "persistence"))] + None +} + +pub fn load_memory(_storage: Option<&dyn epi::Storage>) -> Option { + #[cfg(feature = "persistence")] + { + epi::get_value(_storage?, STORAGE_EGUI_MEMORY_KEY) + } + #[cfg(not(feature = "persistence"))] + None +} + #[cfg(feature = "dark-light")] fn prefer_dark_mode() -> Option { match dark_light::detect() { diff --git a/egui_glow/src/epi_backend.rs b/egui_glow/src/epi_backend.rs index a1cdf06da9c..8b919ea9897 100644 --- a/egui_glow/src/epi_backend.rs +++ b/egui_glow/src/epi_backend.rs @@ -37,8 +37,8 @@ pub use epi::NativeOptions; /// Run an egui app #[allow(unsafe_code)] pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi::AppCreator) -> ! { - let (storage, persistence) = egui_winit::epi::Persistence::from_app_name(app_name); - let window_settings = persistence.load_window_settings(storage.as_deref()); + let storage = egui_winit::epi::create_storage(app_name); + let window_settings = egui_winit::epi::load_window_settings(storage.as_deref()); let window_builder = egui_winit::epi::window_builder(native_options, &window_settings).with_title(app_name); let event_loop = winit::event_loop::EventLoop::with_user_event(); @@ -53,7 +53,6 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi painter.max_texture_side(), gl_window.window(), storage, - persistence, ); { @@ -155,14 +154,7 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi gl_window.window().request_redraw(); // TODO: ask egui if the events warrants a repaint instead } winit::event::Event::LoopDestroyed => { - if let Some(storage) = integration.frame.storage_mut() { - integration.persistence.save( - Some(storage), - &mut *app, - &integration.egui_ctx, - gl_window.window(), - ); - } + integration.save(&mut *app, gl_window.window()); app.on_exit(&gl); painter.destroy(); } From 8f7837d85f2b33abc3767baa1eaaae8edbb65200 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 25 Mar 2022 20:10:46 +0100 Subject: [PATCH 4/6] Update examples --- eframe/examples/confirm_exit.rs | 2 +- eframe/examples/custom_3d_glow.rs | 2 +- eframe/examples/custom_3d_three-d.rs | 2 +- eframe/examples/custom_font.rs | 2 +- eframe/examples/custom_window_frame.rs | 4 ++-- eframe/examples/download_image.rs | 2 +- eframe/examples/file_dialog.rs | 2 +- eframe/examples/hello_world.rs | 2 +- eframe/examples/image.rs | 2 +- eframe/examples/svg.rs | 2 +- eframe/src/lib.rs | 4 ++-- egui-winit/src/epi.rs | 4 ++-- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eframe/examples/confirm_exit.rs b/eframe/examples/confirm_exit.rs index 8bc9bea3b41..70f317d3cea 100644 --- a/eframe/examples/confirm_exit.rs +++ b/eframe/examples/confirm_exit.rs @@ -23,7 +23,7 @@ impl eframe::App for MyApp { self.can_exit } - fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.heading("Try to close the window"); }); diff --git a/eframe/examples/custom_3d_glow.rs b/eframe/examples/custom_3d_glow.rs index 20b3d3cd824..22ace3261c3 100644 --- a/eframe/examples/custom_3d_glow.rs +++ b/eframe/examples/custom_3d_glow.rs @@ -46,7 +46,7 @@ impl MyApp { } impl eframe::App for MyApp { - fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.horizontal(|ui| { ui.spacing_mut().item_spacing.x = 0.0; diff --git a/eframe/examples/custom_3d_three-d.rs b/eframe/examples/custom_3d_three-d.rs index 5be84631cdd..e91a5652851 100644 --- a/eframe/examples/custom_3d_three-d.rs +++ b/eframe/examples/custom_3d_three-d.rs @@ -37,7 +37,7 @@ impl MyApp { } impl eframe::App for MyApp { - fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { egui::widgets::global_dark_light_mode_buttons(ui); diff --git a/eframe/examples/custom_font.rs b/eframe/examples/custom_font.rs index b1408b008fd..d705fc99bf7 100644 --- a/eframe/examples/custom_font.rs +++ b/eframe/examples/custom_font.rs @@ -54,7 +54,7 @@ impl MyApp { } impl eframe::App for MyApp { - fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.heading("egui using custom fonts"); ui.text_edit_multiline(&mut self.text); diff --git a/eframe/examples/custom_window_frame.rs b/eframe/examples/custom_window_frame.rs index 9f5dd2229c7..ef466fa0e24 100644 --- a/eframe/examples/custom_window_frame.rs +++ b/eframe/examples/custom_window_frame.rs @@ -28,7 +28,7 @@ impl eframe::App for MyApp { egui::Rgba::TRANSPARENT // Make sure we don't paint anything behind the rounded corners } - fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { custon_window_frame(ctx, frame, "egui with custom frame", |ui| { ui.label("This is just the contents of the window"); ui.horizontal(|ui| { @@ -41,7 +41,7 @@ impl eframe::App for MyApp { fn custon_window_frame( ctx: &egui::Context, - frame: &eframe::Frame, + frame: &mut eframe::Frame, title: &str, add_contents: impl FnOnce(&mut egui::Ui), ) { diff --git a/eframe/examples/download_image.rs b/eframe/examples/download_image.rs index 71ac412a34a..903c0dc0d0c 100644 --- a/eframe/examples/download_image.rs +++ b/eframe/examples/download_image.rs @@ -20,7 +20,7 @@ struct MyApp { } impl eframe::App for MyApp { - fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { let promise = self.promise.get_or_insert_with(|| { // Begin download. // We download the image using `ehttp`, a library that works both in WASM and on native. diff --git a/eframe/examples/file_dialog.rs b/eframe/examples/file_dialog.rs index 1cec45a4eae..2d9eff43310 100644 --- a/eframe/examples/file_dialog.rs +++ b/eframe/examples/file_dialog.rs @@ -21,7 +21,7 @@ struct MyApp { } impl eframe::App for MyApp { - fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.label("Drag-and-drop files onto the window!"); diff --git a/eframe/examples/hello_world.rs b/eframe/examples/hello_world.rs index 93156c7359d..626af5ba391 100644 --- a/eframe/examples/hello_world.rs +++ b/eframe/examples/hello_world.rs @@ -26,7 +26,7 @@ impl Default for MyApp { } impl eframe::App for MyApp { - fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.heading("My egui Application"); ui.horizontal(|ui| { diff --git a/eframe/examples/image.rs b/eframe/examples/image.rs index 0edcf6050fb..f5f0004908e 100644 --- a/eframe/examples/image.rs +++ b/eframe/examples/image.rs @@ -32,7 +32,7 @@ impl Default for MyApp { } impl eframe::App for MyApp { - fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.heading("This is an image:"); self.image.show(ui); diff --git a/eframe/examples/svg.rs b/eframe/examples/svg.rs index fd3f32f7e61..d272d67d3b5 100644 --- a/eframe/examples/svg.rs +++ b/eframe/examples/svg.rs @@ -35,7 +35,7 @@ impl Default for MyApp { } impl eframe::App for MyApp { - fn update(&mut self, ctx: &egui::Context, _frame: &eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.heading("SVG example"); ui.label("The SVG is rasterized and displayed as a texture."); diff --git a/eframe/src/lib.rs b/eframe/src/lib.rs index 68b060b0029..6e7a318f738 100644 --- a/eframe/src/lib.rs +++ b/eframe/src/lib.rs @@ -37,7 +37,7 @@ //! } //! //! impl eframe::App for MyEguiApp { -//! fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) { +//! fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { //! egui::CentralPanel::default().show(ctx, |ui| { //! ui.heading("Hello World!"); //! }); @@ -126,7 +126,7 @@ pub fn start_web(canvas_id: &str, app_creator: AppCreator) -> Result<(), wasm_bi /// } /// /// impl eframe::App for MyEguiApp { -/// fn update(&mut self, ctx: &egui::Context, frame: &eframe::Frame) { +/// fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { /// egui::CentralPanel::default().show(ctx, |ui| { /// ui.heading("Hello World!"); /// }); diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index d295faea11a..a8c04f0b239 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -155,7 +155,7 @@ impl EpiIntegration { ) -> Self { let egui_ctx = egui::Context::default(); - *egui_ctx.memory() = load_memory(storage.as_deref()).unwrap_or_default(); + *egui_ctx.memory() = load_egui_memory(storage.as_deref()).unwrap_or_default(); let prefer_dark_mode = prefer_dark_mode(); @@ -302,7 +302,7 @@ pub fn load_window_settings(_storage: Option<&dyn epi::Storage>) -> Option) -> Option { +pub fn load_egui_memory(_storage: Option<&dyn epi::Storage>) -> Option { #[cfg(feature = "persistence")] { epi::get_value(_storage?, STORAGE_EGUI_MEMORY_KEY) From 7f385d8975a168d4594106c4c5794c89d2b3cb6b Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 25 Mar 2022 20:15:33 +0100 Subject: [PATCH 5/6] Clippy fixes --- egui-winit/src/epi.rs | 4 ++-- epaint/src/image.rs | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index a8c04f0b239..e3533e829ce 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -289,9 +289,9 @@ impl EpiIntegration { } #[cfg(feature = "persistence")] -const STORAGE_EGUI_MEMORY_KEY: &'static str = "egui"; +const STORAGE_EGUI_MEMORY_KEY: &str = "egui"; #[cfg(feature = "persistence")] -const STORAGE_WINDOW_KEY: &'static str = "window"; +const STORAGE_WINDOW_KEY: &str = "window"; pub fn load_window_settings(_storage: Option<&dyn epi::Storage>) -> Option { #[cfg(feature = "persistence")] diff --git a/epaint/src/image.rs b/epaint/src/image.rs index 2cfa586a449..43745e0d0c0 100644 --- a/epaint/src/image.rs +++ b/epaint/src/image.rs @@ -34,8 +34,7 @@ impl ImageData { pub fn bytes_per_pixel(&self) -> usize { match self { - Self::Color(_) => 4, - Self::Font(_) => 4, + Self::Color(_) | Self::Font(_) => 4, } } } From 32067a6a78f168fc214db7e7ef34b2f8491c7e7c Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 25 Mar 2022 20:43:43 +0100 Subject: [PATCH 6/6] Update changelog --- eframe/CHANGELOG.md | 12 ++++++++++-- egui_web/CHANGELOG.md | 2 +- epaint/CHANGELOG.md | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/eframe/CHANGELOG.md b/eframe/CHANGELOG.md index 580fc090a01..ae83aa92259 100644 --- a/eframe/CHANGELOG.md +++ b/eframe/CHANGELOG.md @@ -8,8 +8,16 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG * Change default for `NativeOptions::drag_and_drop_support` to `true` ([#1329](https://github.com/emilk/egui/pull/1329)). * Remove the `egui_glium` feature. `eframe` will now always use `egui_glow` as the native backend ([#1357](https://github.com/emilk/egui/pull/1357)). * Removed `Frame::request_repaint` - just call `egui::Context::request_repaint` for the same effect ([#1366](https://github.com/emilk/egui/pull/1366)). -* Use full browser width by default ([#1378](https://github.com/emilk/egui/pull/1378)). -* Add new `NativeOptions`: `vsync`, `multisampling`, `depth_buffer`, `stencil_buffer`. +* Use full browser width by default ([#1378](https://github.com/emilk/egui/pull/1378)). +* Added new `NativeOptions`: `vsync`, `multisampling`, `depth_buffer`, `stencil_buffer`. +* Changed app creation/setup ([#1363](https://github.com/emilk/egui/pull/1363)): + * Removed `App::setup` and `App::name`. + * Provide `CreationContext` when creating app with egui context, storage, integration info and glow context. + * Change interface of `run_native` and `start_web`. +* Added `Frame::storage()` and `Frame::storage_mut()` ([#1418](https://github.com/emilk/egui/pull/1418)). + * You can now load/save state in `App::update` + * Changed `App::update` to take `&mut Frame` instead of `&Frame`. + * `Frame` is no longer `Clone` or `Sync`. ## 0.17.0 - 2022-02-22 diff --git a/egui_web/CHANGELOG.md b/egui_web/CHANGELOG.md index ecffcb7f926..c3abab06795 100644 --- a/egui_web/CHANGELOG.md +++ b/egui_web/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to the `egui_web` integration will be noted in this file. ## Unreleased * egui code will no longer be called after panic ([#1306](https://github.com/emilk/egui/pull/1306)). * Remove the "webgl" feature. `egui_web` now always use `glow` (which in turn wraps WebGL) ([#1356](https://github.com/emilk/egui/pull/1356)). -* Use full browser width by default ([#1378](https://github.com/emilk/egui/pull/1378)). +* Use full browser width by default ([#1378](https://github.com/emilk/egui/pull/1378)). ## 0.17.0 - 2022-02-22 diff --git a/epaint/CHANGELOG.md b/epaint/CHANGELOG.md index 25bce292c5e..09ab4c28226 100644 --- a/epaint/CHANGELOG.md +++ b/epaint/CHANGELOG.md @@ -24,7 +24,7 @@ All notable changes to the epaint crate will be documented in this file. ## 0.16.0 - 2021-12-29 -* Anti-alias path ends ([#893](https://github.com/emilk/egui/pull/893)). +* Anti-alias path ends ([#893](https://github.com/emilk/egui/pull/893)). * `Rgba` now implements `Hash` ([#886](https://github.com/emilk/egui/pull/886)). * Renamed `Texture` to `FontImage`.