From 1e6c1b55d36a6d31ae6304fa93af8ce35249ec42 Mon Sep 17 00:00:00 2001 From: Konkitoman Date: Tue, 1 Aug 2023 15:19:18 +0300 Subject: [PATCH] Some work on frontend for making create_viewport_sync possible --- crates/eframe/src/native/run.rs | 8 +-- crates/egui/src/context.rs | 102 +++++++++++++++++++++++++++++--- crates/egui/src/data/output.rs | 2 +- 3 files changed, 99 insertions(+), 13 deletions(-) diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 2a4ad170e..e479e82a7 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -1197,7 +1197,7 @@ mod glow_integration { } w.window = None; w.gl_surface = None; - w.render = Some(render.clone()); + w.render = render.clone(); w.builder = builder.clone(); w.parent_id = *id; } @@ -1215,7 +1215,7 @@ mod glow_integration { window: None, window_id: id, egui_winit: None, - render: Some(render.clone()), + render: render.clone(), parent_id: parent, }); active_viewports_ids.push(id); @@ -1832,7 +1832,7 @@ mod wgpu_integration { viewports.retain_mut(|(id, parent, builder, render)| { if let Some(w) = windows.get_mut(id) { - w.2 = Some(render.clone()); + w.2 = render.clone(); w.3 = *parent; active_viewports_ids.push(*id); return false; @@ -1842,7 +1842,7 @@ mod wgpu_integration { }); for (id, parent, builder, render) in viewports { - windows.insert(id, (None, None, Some(render), parent, builder)); + windows.insert(id, (None, None, render, parent, builder)); active_viewports_ids.push(id); } diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index cb8f0b408..5fc355b71 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -193,9 +193,28 @@ struct ContextImpl { repaint: Repaint, - viewports: HashMap>)>, + viewports: HashMap< + String, + ( + ViewportBuilder, + u64, + u64, + bool, + Option>>, + ), + >, viewport_commands: Vec<(u64, ViewportCommand)>, + render_sync: Option< + Arc< + Box< + dyn for<'a> Fn(ViewportBuilder, Box) + + Send + + Sync, + >, + >, + >, + viewport_counter: u64, current_rendering_viewport: u64, is_desktop: bool, @@ -394,7 +413,16 @@ impl std::cmp::PartialEq for Context { impl Default for Context { fn default() -> Self { - Self(Arc::new(RwLock::new(ContextImpl::default()))) + let s = Self(Arc::new(RwLock::new(ContextImpl::default()))); + let clone = s.clone(); + + s.write(|ctx| { + ctx.render_sync = Some(Arc::new(Box::new(move |_builder, render| { + render(&clone, 0, 0) + }))) + }); + + s } } @@ -2033,6 +2061,17 @@ impl Context { self.read(|ctx| ctx.current_rendering_viewport) } + pub fn set_render_sync_callback( + &self, + callback: impl for<'a> Fn(ViewportBuilder, Box) + + Send + + Sync + + 'static, + ) { + let callback = Box::new(callback); + self.write(|ctx| ctx.render_sync = Some(Arc::new(callback))); + } + pub fn is_desktop(&self) -> bool { self.read(|ctx| ctx.is_desktop) } @@ -2047,26 +2086,27 @@ impl Context { pub fn create_viewport( &self, - window_builder: ViewportBuilder, + viewport_builder: ViewportBuilder, func: impl Fn(&Context, u64, u64) + Send + Sync + 'static, ) { if self.is_desktop() { self.write(|ctx| { - if let Some(window) = ctx.viewports.get_mut(&window_builder.title) { + if let Some(window) = ctx.viewports.get_mut(&viewport_builder.title) { + window.0 = viewport_builder; window.2 = ctx.current_rendering_viewport; window.3 = true; - window.4 = Arc::new(Box::new(func)); + window.4 = Some(Arc::new(Box::new(func))); } else { let id = ctx.viewport_counter + 1; ctx.viewport_counter = id; ctx.viewports.insert( - window_builder.title.clone(), + viewport_builder.title.clone(), ( - window_builder, + viewport_builder, id, ctx.current_rendering_viewport, true, - Arc::new(Box::new(func)), + Some(Arc::new(Box::new(func))), ), ); } @@ -2075,6 +2115,52 @@ impl Context { func(self, 0, 0); } } + + pub fn create_viewport_sync( + &self, + viewport_builder: ViewportBuilder, + func: impl FnOnce(&Context, u64, u64) -> T, + ) -> T { + if self.is_desktop() { + let render_sync = self.write(|ctx| { + if let Some(window) = ctx.viewports.get_mut(&viewport_builder.title) { + window.0 = viewport_builder.clone(); + window.2 = ctx.current_rendering_viewport; + window.3 = true; + window.4 = None; + } else { + let id = ctx.viewport_counter + 1; + ctx.viewport_counter = id; + ctx.viewports.insert( + viewport_builder.title.clone(), + ( + viewport_builder.clone(), + id, + ctx.current_rendering_viewport, + true, + None, + ), + ); + } + + ctx.render_sync.clone() + }); + let mut out = None; + { + let out = &mut out; + render_sync.unwrap()( + viewport_builder, + Box::new(move |context, viewport_id, parent_viewport_id| { + *out = Some(func(context, viewport_id, parent_viewport_id)) + }), + ); + } + + out.unwrap() + } else { + func(self, 0, 0) + } + } } #[test] diff --git a/crates/egui/src/data/output.rs b/crates/egui/src/data/output.rs index c56ca2263..2ebe53e89 100644 --- a/crates/egui/src/data/output.rs +++ b/crates/egui/src/data/output.rs @@ -39,7 +39,7 @@ pub struct FullOutput { u64, u64, ViewportBuilder, - Arc>, + Option>>, )>, pub viewport_commands: Vec<(u64, ViewportCommand)>,