1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-02 14:50:03 -04:00

Some work on frontend for making create_viewport_sync possible

This commit is contained in:
Konkitoman
2023-08-01 15:19:18 +03:00
parent e6e1463062
commit 1e6c1b55d3
3 changed files with 99 additions and 13 deletions

View File

@@ -1197,7 +1197,7 @@ mod glow_integration {
} }
w.window = None; w.window = None;
w.gl_surface = None; w.gl_surface = None;
w.render = Some(render.clone()); w.render = render.clone();
w.builder = builder.clone(); w.builder = builder.clone();
w.parent_id = *id; w.parent_id = *id;
} }
@@ -1215,7 +1215,7 @@ mod glow_integration {
window: None, window: None,
window_id: id, window_id: id,
egui_winit: None, egui_winit: None,
render: Some(render.clone()), render: render.clone(),
parent_id: parent, parent_id: parent,
}); });
active_viewports_ids.push(id); active_viewports_ids.push(id);
@@ -1832,7 +1832,7 @@ mod wgpu_integration {
viewports.retain_mut(|(id, parent, builder, render)| { viewports.retain_mut(|(id, parent, builder, render)| {
if let Some(w) = windows.get_mut(id) { if let Some(w) = windows.get_mut(id) {
w.2 = Some(render.clone()); w.2 = render.clone();
w.3 = *parent; w.3 = *parent;
active_viewports_ids.push(*id); active_viewports_ids.push(*id);
return false; return false;
@@ -1842,7 +1842,7 @@ mod wgpu_integration {
}); });
for (id, parent, builder, render) in viewports { 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); active_viewports_ids.push(id);
} }

View File

@@ -193,9 +193,28 @@ struct ContextImpl {
repaint: Repaint, repaint: Repaint,
viewports: HashMap<String, (ViewportBuilder, u64, u64, bool, Arc<Box<ViewportRender>>)>, viewports: HashMap<
String,
(
ViewportBuilder,
u64,
u64,
bool,
Option<Arc<Box<ViewportRender>>>,
),
>,
viewport_commands: Vec<(u64, ViewportCommand)>, viewport_commands: Vec<(u64, ViewportCommand)>,
render_sync: Option<
Arc<
Box<
dyn for<'a> Fn(ViewportBuilder, Box<dyn FnOnce(&Context, u64, u64) + 'a>)
+ Send
+ Sync,
>,
>,
>,
viewport_counter: u64, viewport_counter: u64,
current_rendering_viewport: u64, current_rendering_viewport: u64,
is_desktop: bool, is_desktop: bool,
@@ -394,7 +413,16 @@ impl std::cmp::PartialEq for Context {
impl Default for Context { impl Default for Context {
fn default() -> Self { 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) self.read(|ctx| ctx.current_rendering_viewport)
} }
pub fn set_render_sync_callback(
&self,
callback: impl for<'a> Fn(ViewportBuilder, Box<dyn FnOnce(&Context, u64, u64) + 'a>)
+ Send
+ Sync
+ 'static,
) {
let callback = Box::new(callback);
self.write(|ctx| ctx.render_sync = Some(Arc::new(callback)));
}
pub fn is_desktop(&self) -> bool { pub fn is_desktop(&self) -> bool {
self.read(|ctx| ctx.is_desktop) self.read(|ctx| ctx.is_desktop)
} }
@@ -2047,26 +2086,27 @@ impl Context {
pub fn create_viewport( pub fn create_viewport(
&self, &self,
window_builder: ViewportBuilder, viewport_builder: ViewportBuilder,
func: impl Fn(&Context, u64, u64) + Send + Sync + 'static, func: impl Fn(&Context, u64, u64) + Send + Sync + 'static,
) { ) {
if self.is_desktop() { if self.is_desktop() {
self.write(|ctx| { 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.2 = ctx.current_rendering_viewport;
window.3 = true; window.3 = true;
window.4 = Arc::new(Box::new(func)); window.4 = Some(Arc::new(Box::new(func)));
} else { } else {
let id = ctx.viewport_counter + 1; let id = ctx.viewport_counter + 1;
ctx.viewport_counter = id; ctx.viewport_counter = id;
ctx.viewports.insert( ctx.viewports.insert(
window_builder.title.clone(), viewport_builder.title.clone(),
( (
window_builder, viewport_builder,
id, id,
ctx.current_rendering_viewport, ctx.current_rendering_viewport,
true, true,
Arc::new(Box::new(func)), Some(Arc::new(Box::new(func))),
), ),
); );
} }
@@ -2075,6 +2115,52 @@ impl Context {
func(self, 0, 0); func(self, 0, 0);
} }
} }
pub fn create_viewport_sync<T>(
&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] #[test]

View File

@@ -39,7 +39,7 @@ pub struct FullOutput {
u64, u64,
u64, u64,
ViewportBuilder, ViewportBuilder,
Arc<Box<dyn Fn(&Context, u64, u64) + Sync + Send>>, Option<Arc<Box<dyn Fn(&Context, u64, u64) + Sync + Send>>>,
)>, )>,
pub viewport_commands: Vec<(u64, ViewportCommand)>, pub viewport_commands: Vec<(u64, ViewportCommand)>,