From d1ad3b51c49711a3f9bfa5a913df832dbbcd33cd Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Mon, 31 Jan 2022 19:41:22 +0300 Subject: [PATCH 1/8] refactor!: allow `RepaintSignal: ?Sync` --- egui-winit/src/epi.rs | 9 ++++++--- egui_glium/src/epi_backend.rs | 11 ++++------- egui_glow/src/epi_backend.rs | 9 ++++----- egui_web/src/backend.rs | 9 +++++---- epi/src/lib.rs | 17 +++++++++++------ 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index f9eeaece098..3888d6fa559 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -197,14 +197,17 @@ pub struct EpiIntegration { } impl EpiIntegration { - pub fn new( + pub fn new( integration_name: &'static str, max_texture_side: usize, window: &winit::window::Window, - repaint_signal: std::sync::Arc, + repaint_signal: S, persistence: crate::epi::Persistence, app: Box, - ) -> Self { + ) -> Self + where + S: epi::backend::RepaintSignal + 'static, + { let egui_ctx = egui::Context::default(); *egui_ctx.memory() = persistence.load_memory().unwrap_or_default(); diff --git a/egui_glium/src/epi_backend.rs b/egui_glium/src/epi_backend.rs index b22a507592e..9546522d974 100644 --- a/egui_glium/src/epi_backend.rs +++ b/egui_glium/src/epi_backend.rs @@ -4,13 +4,12 @@ use crate::*; struct RequestRepaintEvent; -struct GliumRepaintSignal( - std::sync::Mutex>, -); +#[derive(Clone)] +struct GliumRepaintSignal(glutin::event_loop::EventLoopProxy); impl epi::backend::RepaintSignal for GliumRepaintSignal { fn request_repaint(&self) { - self.0.lock().unwrap().send_event(RequestRepaintEvent).ok(); + self.0.send_event(RequestRepaintEvent).ok(); } } @@ -40,9 +39,7 @@ pub fn run(app: Box, native_options: &epi::NativeOptions) -> ! { let event_loop = glutin::event_loop::EventLoop::with_user_event(); let display = create_display(window_builder, &event_loop); - let repaint_signal = std::sync::Arc::new(GliumRepaintSignal(std::sync::Mutex::new( - event_loop.create_proxy(), - ))); + let repaint_signal = GliumRepaintSignal(event_loop.create_proxy()); let mut painter = crate::Painter::new(&display); let mut integration = egui_winit::epi::EpiIntegration::new( diff --git a/egui_glow/src/epi_backend.rs b/egui_glow/src/epi_backend.rs index 0a9f381a671..1f5a2daf1bb 100644 --- a/egui_glow/src/epi_backend.rs +++ b/egui_glow/src/epi_backend.rs @@ -3,11 +3,12 @@ use egui_winit::winit; struct RequestRepaintEvent; -struct GlowRepaintSignal(std::sync::Mutex>); +#[derive(Clone)] +struct GlowRepaintSignal(winit::event_loop::EventLoopProxy); impl epi::backend::RepaintSignal for GlowRepaintSignal { fn request_repaint(&self) { - self.0.lock().unwrap().send_event(RequestRepaintEvent).ok(); + self.0.send_event(RequestRepaintEvent).ok(); } } @@ -55,9 +56,7 @@ pub fn run(app: Box, native_options: &epi::NativeOptions) -> ! { let event_loop = winit::event_loop::EventLoop::with_user_event(); let (gl_window, gl) = create_display(window_builder, &event_loop); - let repaint_signal = std::sync::Arc::new(GlowRepaintSignal(std::sync::Mutex::new( - event_loop.create_proxy(), - ))); + let repaint_signal = GlowRepaintSignal(event_loop.create_proxy()); let mut painter = crate::Painter::new(&gl, None, "") .map_err(|error| eprintln!("some OpenGL error occurred {}\n", error)) diff --git a/egui_web/src/backend.rs b/egui_web/src/backend.rs index 9d893e3a65a..6683f40670d 100644 --- a/egui_web/src/backend.rs +++ b/egui_web/src/backend.rs @@ -55,11 +55,12 @@ impl WebInput { use std::sync::atomic::Ordering::SeqCst; -pub struct NeedRepaint(std::sync::atomic::AtomicBool); +#[derive(Clone)] +pub struct NeedRepaint(std::sync::Arc); impl Default for NeedRepaint { fn default() -> Self { - Self(true.into()) + Self(std::sync::Arc::new(true.into())) } } @@ -87,7 +88,7 @@ pub struct AppRunner { painter: Box, pub(crate) input: WebInput, app: Box, - pub(crate) needs_repaint: std::sync::Arc, + pub(crate) needs_repaint: NeedRepaint, storage: LocalStorage, last_save_time: f64, screen_reader: crate::screen_reader::ScreenReader, @@ -102,7 +103,7 @@ impl AppRunner { let prefer_dark_mode = crate::prefer_dark_mode(); - let needs_repaint: std::sync::Arc = Default::default(); + let needs_repaint: NeedRepaint = Default::default(); let frame = epi::Frame::new(epi::backend::FrameData { info: epi::IntegrationInfo { diff --git a/epi/src/lib.rs b/epi/src/lib.rs index bc1b5ea1e09..8f6e0ce5700 100644 --- a/epi/src/lib.rs +++ b/epi/src/lib.rs @@ -277,19 +277,24 @@ pub struct IconData { /// /// [`Frame`] is cheap to clone and is safe to pass to other threads. #[derive(Clone)] -pub struct Frame(pub Arc>); +pub struct Frame(pub Arc>>); impl Frame { /// Create a `Frame` - called by the integration. #[doc(hidden)] - pub fn new(frame_data: backend::FrameData) -> Self { + pub fn new(frame_data: backend::FrameData) -> Self + where + S: backend::RepaintSignal, + { Self(Arc::new(Mutex::new(frame_data))) } /// Access the underlying [`backend::FrameData`]. #[doc(hidden)] #[inline] - pub fn lock(&self) -> std::sync::MutexGuard<'_, backend::FrameData> { + pub fn lock( + &self, + ) -> std::sync::MutexGuard<'_, backend::FrameData> { self.0.lock().unwrap() } @@ -440,7 +445,7 @@ pub mod backend { use super::*; /// How to signal the [`egui`] integration that a repaint is required. - pub trait RepaintSignal: Send + Sync { + pub trait RepaintSignal: Send { /// This signals the [`egui`] integration that a repaint is required. /// /// Call this e.g. when a background process finishes in an async context and/or background thread. @@ -448,7 +453,7 @@ pub mod backend { } /// The data required by [`Frame`] each frame. - pub struct FrameData { + pub struct FrameData { /// Information about the integration. pub info: IntegrationInfo, @@ -456,7 +461,7 @@ pub mod backend { pub output: AppOutput, /// If you need to request a repaint from another thread, clone this and send it to that other thread. - pub repaint_signal: std::sync::Arc, + pub repaint_signal: S, } /// Action that can be taken by the user app. From 0ecba88b5f17b9d72c5ef81768ec09154857e07c Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Mon, 31 Jan 2022 19:55:54 +0300 Subject: [PATCH 2/8] `RepaintSignal: Any` --- epi/src/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/epi/src/lib.rs b/epi/src/lib.rs index 8f6e0ce5700..61f0fbf1139 100644 --- a/epi/src/lib.rs +++ b/epi/src/lib.rs @@ -277,12 +277,12 @@ pub struct IconData { /// /// [`Frame`] is cheap to clone and is safe to pass to other threads. #[derive(Clone)] -pub struct Frame(pub Arc>>); +pub struct Frame(pub Arc>>); impl Frame { /// Create a `Frame` - called by the integration. #[doc(hidden)] - pub fn new(frame_data: backend::FrameData) -> Self + pub fn new(frame_data: backend::FrameData) -> Self where S: backend::RepaintSignal, { @@ -442,10 +442,12 @@ pub const APP_KEY: &str = "app"; /// You only need to look here if you are writing a backend for `epi`. pub mod backend { + use std::any::Any; + use super::*; /// How to signal the [`egui`] integration that a repaint is required. - pub trait RepaintSignal: Send { + pub trait RepaintSignal: Send + Any { /// This signals the [`egui`] integration that a repaint is required. /// /// Call this e.g. when a background process finishes in an async context and/or background thread. From fb720f5e30a8d9b073f9e9a19c4b7858383208c4 Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Mon, 31 Jan 2022 22:55:58 +0300 Subject: [PATCH 3/8] feat!: add `dyn_clone` method to `epi::backend::RepaintSignal` --- egui_glium/src/epi_backend.rs | 4 ++++ egui_glow/src/epi_backend.rs | 4 ++++ egui_web/src/backend.rs | 4 ++++ epi/src/lib.rs | 18 +++++++++--------- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/egui_glium/src/epi_backend.rs b/egui_glium/src/epi_backend.rs index 9546522d974..c7d7952f9d9 100644 --- a/egui_glium/src/epi_backend.rs +++ b/egui_glium/src/epi_backend.rs @@ -11,6 +11,10 @@ impl epi::backend::RepaintSignal for GliumRepaintSignal { fn request_repaint(&self) { self.0.send_event(RequestRepaintEvent).ok(); } + + fn dyn_clone(&self) -> Box { + Box::new(self.clone()) + } } fn create_display( diff --git a/egui_glow/src/epi_backend.rs b/egui_glow/src/epi_backend.rs index 1f5a2daf1bb..519d28b0ed8 100644 --- a/egui_glow/src/epi_backend.rs +++ b/egui_glow/src/epi_backend.rs @@ -10,6 +10,10 @@ impl epi::backend::RepaintSignal for GlowRepaintSignal { fn request_repaint(&self) { self.0.send_event(RequestRepaintEvent).ok(); } + + fn dyn_clone(&self) -> Box { + Box::new(self.clone()) + } } #[allow(unsafe_code)] diff --git a/egui_web/src/backend.rs b/egui_web/src/backend.rs index 6683f40670d..7fc1b1e1d5e 100644 --- a/egui_web/src/backend.rs +++ b/egui_web/src/backend.rs @@ -78,6 +78,10 @@ impl epi::backend::RepaintSignal for NeedRepaint { fn request_repaint(&self) { self.0.store(true, SeqCst); } + + fn dyn_clone(&self) -> Box { + Box::new(self.clone()) + } } // ---------------------------------------------------------------------------- diff --git a/epi/src/lib.rs b/epi/src/lib.rs index 61f0fbf1139..5f5ed647df9 100644 --- a/epi/src/lib.rs +++ b/epi/src/lib.rs @@ -277,7 +277,7 @@ pub struct IconData { /// /// [`Frame`] is cheap to clone and is safe to pass to other threads. #[derive(Clone)] -pub struct Frame(pub Arc>>); +pub struct Frame(pub Arc>); impl Frame { /// Create a `Frame` - called by the integration. @@ -292,9 +292,7 @@ impl Frame { /// Access the underlying [`backend::FrameData`]. #[doc(hidden)] #[inline] - pub fn lock( - &self, - ) -> std::sync::MutexGuard<'_, backend::FrameData> { + pub fn lock(&self) -> std::sync::MutexGuard<'_, backend::FrameData> { self.0.lock().unwrap() } @@ -442,27 +440,29 @@ pub const APP_KEY: &str = "app"; /// You only need to look here if you are writing a backend for `epi`. pub mod backend { - use std::any::Any; - use super::*; /// How to signal the [`egui`] integration that a repaint is required. - pub trait RepaintSignal: Send + Any { + pub trait RepaintSignal: Send + std::any::Any { /// This signals the [`egui`] integration that a repaint is required. /// /// Call this e.g. when a background process finishes in an async context and/or background thread. fn request_repaint(&self); + + /// Method to dynamically clone self. Calling [`RepaintSignal::request_repaint`] on a clone should + /// be equivalent to a call on the original value. You may use [`Box::downcast`] to get a concrete type. + fn dyn_clone(&self) -> Box; } /// The data required by [`Frame`] each frame. - pub struct FrameData { + pub struct FrameData { /// Information about the integration. pub info: IntegrationInfo, /// Where the app can issue commands back to the integration. pub output: AppOutput, - /// If you need to request a repaint from another thread, clone this and send it to that other thread. + /// If you need to request a repaint from another thread, [`RepaintSignal::dyn_clone`] this and send it to that other thread. pub repaint_signal: S, } From f197740d1298279ea67764c433049c73afc59f5a Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Tue, 1 Feb 2022 00:32:20 +0300 Subject: [PATCH 4/8] chore: added entries to the changelog --- eframe/CHANGELOG.md | 1 + egui_web/CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/eframe/CHANGELOG.md b/eframe/CHANGELOG.md index 45ed02fe4d3..ee341abb1da 100644 --- a/eframe/CHANGELOG.md +++ b/eframe/CHANGELOG.md @@ -11,6 +11,7 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG * Fix horizontal scrolling direction on Linux. * Added `App::on_exit_event` ([#1038](https://github.com/emilk/egui/pull/1038)) * Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)). +* `backend::RepaintSignal` no longer requires `Sync`, but now requires new method `dyn_clone` ([#1187](https://github.com/emilk/egui/pull/1187)). ## 0.16.0 - 2021-12-29 diff --git a/egui_web/CHANGELOG.md b/egui_web/CHANGELOG.md index 3964e70ee28..890526e1fd7 100644 --- a/egui_web/CHANGELOG.md +++ b/egui_web/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to the `egui_web` integration will be noted in this file. * Fixed glow failure on Chromium ([#1092](https://github.com/emilk/egui/pull/1092)). * Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)). * Updated `epi::IntegrationInfo::web_location_hash` on `hashchange` event ([#1140](https://github.com/emilk/egui/pull/1140)). +* Updated `NeedRepaint` implementation ([#1187](https://github.com/emilk/egui/pull/1187)). ## 0.16.0 - 2021-12-29 From 02f593c6c689ab0540a409efabddd7758603863a Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Tue, 1 Feb 2022 00:38:38 +0300 Subject: [PATCH 5/8] nano refactoring --- egui_web/src/backend.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/egui_web/src/backend.rs b/egui_web/src/backend.rs index 7fc1b1e1d5e..b8872e50d6c 100644 --- a/egui_web/src/backend.rs +++ b/egui_web/src/backend.rs @@ -107,7 +107,7 @@ impl AppRunner { let prefer_dark_mode = crate::prefer_dark_mode(); - let needs_repaint: NeedRepaint = Default::default(); + let needs_repaint = NeedRepaint::default(); let frame = epi::Frame::new(epi::backend::FrameData { info: epi::IntegrationInfo { From 956fbf5627c301c953f744cb8a7540064ac40dab Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Tue, 1 Feb 2022 00:49:40 +0300 Subject: [PATCH 6/8] nano refactor 2 --- egui-winit/src/epi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index 3888d6fa559..d384090e999 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -206,7 +206,7 @@ impl EpiIntegration { app: Box, ) -> Self where - S: epi::backend::RepaintSignal + 'static, + S: epi::backend::RepaintSignal, { let egui_ctx = egui::Context::default(); From 6e16ddd0f52bfc237e53de3e4c37f7329df1614a Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Tue, 1 Feb 2022 00:59:46 +0300 Subject: [PATCH 7/8] update `egui-winit`s changelog --- egui-winit/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/egui-winit/CHANGELOG.md b/egui-winit/CHANGELOG.md index 426fbc6a206..bbacc0158d1 100644 --- a/egui-winit/CHANGELOG.md +++ b/egui-winit/CHANGELOG.md @@ -9,7 +9,7 @@ All notable changes to the `egui-winit` integration will be noted in this file. * Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)). * Require knowledge about max texture side (e.g. `GL_MAX_TEXTURE_SIZE`)) ([#1154](https://github.com/emilk/egui/pull/1154)). * Fixed `enable_drag` for Windows. Now called only once just after left click ([#1108](https://github.com/emilk/egui/pull/1108)). - +* Updated `EpiIntegration::new` signature ([#1187](https://github.com/emilk/egui/pull/1187)). ## 0.16.0 - 2021-12-29 * Added helper `EpiIntegration` ([#871](https://github.com/emilk/egui/pull/871)). From 9be55e092aab1e5f77cc836a3f09198247e75057 Mon Sep 17 00:00:00 2001 From: ZetaNumbers Date: Tue, 1 Feb 2022 01:06:25 +0300 Subject: [PATCH 8/8] Readd a line break --- egui-winit/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/egui-winit/CHANGELOG.md b/egui-winit/CHANGELOG.md index bbacc0158d1..109506a957d 100644 --- a/egui-winit/CHANGELOG.md +++ b/egui-winit/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to the `egui-winit` integration will be noted in this file. * Fixed `enable_drag` for Windows. Now called only once just after left click ([#1108](https://github.com/emilk/egui/pull/1108)). * Updated `EpiIntegration::new` signature ([#1187](https://github.com/emilk/egui/pull/1187)). + ## 0.16.0 - 2021-12-29 * Added helper `EpiIntegration` ([#871](https://github.com/emilk/egui/pull/871)). * Fixed shift key getting stuck enabled with the X11 option `shift:both_capslock` enabled ([#849](https://github.com/emilk/egui/pull/849)).