1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-30 21:30:03 -04:00

Rename render to viewport_ui_cb to avoid confusion

This commit is contained in:
Emil Ernerfeldt
2023-11-03 12:09:09 +01:00
parent 29e1c4d101
commit 9fd65ad21e
4 changed files with 102 additions and 81 deletions

View File

@@ -4,7 +4,7 @@ use winit::event_loop::EventLoopWindowTarget;
use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _}; use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _};
use egui::{NumExt as _, ViewportBuilder, ViewportId, ViewportIdPair, ViewportRender}; use egui::{NumExt as _, ViewportBuilder, ViewportId, ViewportIdPair, ViewportUiCallback};
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
use egui_winit::accesskit_winit; use egui_winit::accesskit_winit;
use egui_winit::{native_pixels_per_point, EventResponse, WindowSettings}; use egui_winit::{native_pixels_per_point, EventResponse, WindowSettings};
@@ -480,7 +480,7 @@ impl EpiIntegration {
app: &mut dyn epi::App, app: &mut dyn epi::App,
window: &winit::window::Window, window: &winit::window::Window,
egui_winit: &mut egui_winit::State, egui_winit: &mut egui_winit::State,
render: &Option<Arc<Box<ViewportRender>>>, viewport_ui_cb: &Option<Arc<Box<ViewportUiCallback>>>,
pair: ViewportIdPair, pair: ViewportIdPair,
) -> egui::FullOutput { ) -> egui::FullOutput {
let frame_start = std::time::Instant::now(); let frame_start = std::time::Instant::now();
@@ -495,9 +495,11 @@ impl EpiIntegration {
// Run user code: // Run user code:
let full_output = self.egui_ctx.run(raw_input, pair, |egui_ctx| { let full_output = self.egui_ctx.run(raw_input, pair, |egui_ctx| {
crate::profile_scope!("App::update"); crate::profile_scope!("App::update");
if let Some(render) = render { if let Some(viewport_ui_cb) = viewport_ui_cb {
render(egui_ctx); // Child viewport
viewport_ui_cb(egui_ctx);
} else { } else {
// Root viewport
app.update(egui_ctx, &mut self.frame); app.update(egui_ctx, &mut self.frame);
} }
}); });

View File

@@ -459,7 +459,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
mod glow_integration { mod glow_integration {
use egui::{ use egui::{
epaint::ahash::HashMap, NumExt as _, ViewportIdPair, ViewportOutput, ViewportRender, epaint::ahash::HashMap, NumExt as _, ViewportIdPair, ViewportOutput, ViewportUiCallback,
}; };
use egui_winit::{ use egui_winit::{
changes_between_builders, create_winit_window_builder, process_viewport_commands, changes_between_builders, create_winit_window_builder, process_viewport_commands,
@@ -503,7 +503,10 @@ mod glow_integration {
gl_surface: Option<glutin::surface::Surface<glutin::surface::WindowSurface>>, gl_surface: Option<glutin::surface::Surface<glutin::surface::WindowSurface>>,
window: Option<Rc<RefCell<winit::window::Window>>>, window: Option<Rc<RefCell<winit::window::Window>>>,
pair: ViewportIdPair, pair: ViewportIdPair,
render: Option<Arc<Box<ViewportRender>>>,
/// The user-callback that shows the ui.
viewport_ui_cb: Option<Arc<Box<ViewportUiCallback>>>,
egui_winit: Option<egui_winit::State>, egui_winit: Option<egui_winit::State>,
} }
@@ -669,7 +672,7 @@ mod glow_integration {
gl_surface: None, gl_surface: None,
window: window.map(|w| Rc::new(RefCell::new(w))), window: window.map(|w| Rc::new(RefCell::new(w))),
egui_winit: None, egui_winit: None,
render: None, viewport_ui_cb: None,
pair: ViewportIdPair::MAIN, pair: ViewportIdPair::MAIN,
})), })),
); );
@@ -1079,7 +1082,7 @@ mod glow_integration {
let beginning = integration.beginning; let beginning = integration.beginning;
integration.egui_ctx.set_render_sync_callback( integration.egui_ctx.set_render_sync_callback(
move |egui_ctx, viewport_builder, pair, render| { move |egui_ctx, viewport_builder, pair, viewport_ui_cb| {
if let (Some(glutin), Some(gl), Some(painter)) = if let (Some(glutin), Some(gl), Some(painter)) =
(glutin.upgrade(), gl.upgrade(), painter.upgrade()) (glutin.upgrade(), gl.upgrade(), painter.upgrade())
{ {
@@ -1087,7 +1090,7 @@ mod glow_integration {
egui_ctx, egui_ctx,
viewport_builder, viewport_builder,
pair, pair,
render, viewport_ui_cb,
&glutin, &glutin,
&gl, &gl,
&painter, &painter,
@@ -1117,7 +1120,7 @@ mod glow_integration {
egui_ctx: &egui::Context, egui_ctx: &egui::Context,
mut viewport_builder: ViewportBuilder, mut viewport_builder: ViewportBuilder,
pair: ViewportIdPair, pair: ViewportIdPair,
render: Box<dyn FnOnce(&egui::Context) + '_>, viewport_ui_cb: Box<dyn FnOnce(&egui::Context) + '_>,
glutin: &RefCell<GlutinWindowContext>, glutin: &RefCell<GlutinWindowContext>,
gl: &glow::Context, gl: &glow::Context,
painter: &RefCell<egui_glow::Painter>, painter: &RefCell<egui_glow::Painter>,
@@ -1149,7 +1152,7 @@ mod glow_integration {
gl_surface: None, gl_surface: None,
window: None, window: None,
pair, pair,
render: None, viewport_ui_cb: None,
egui_winit: None, egui_winit: None,
}))); })));
glutin.builders.entry(pair.this).or_insert(viewport_builder); glutin.builders.entry(pair.this).or_insert(viewport_builder);
@@ -1180,7 +1183,7 @@ mod glow_integration {
let mut input = winit_state.take_egui_input(&win); let mut input = winit_state.take_egui_input(&win);
input.time = Some(beginning.elapsed().as_secs_f64()); input.time = Some(beginning.elapsed().as_secs_f64());
let output = egui_ctx.run(input, pair, |ctx| { let output = egui_ctx.run(input, pair, |ctx| {
render(ctx); viewport_ui_cb(ctx);
}); });
let screen_size_in_pixels: [u32; 2] = win.inner_size().into(); let screen_size_in_pixels: [u32; 2] = win.inner_size().into();
@@ -1247,7 +1250,7 @@ mod glow_integration {
|ViewportOutput { |ViewportOutput {
builder, builder,
pair: ViewportIdPair { this: id, .. }, pair: ViewportIdPair { this: id, .. },
render, viewport_ui_cb,
}| { }| {
let mut glutin = glutin_ctx.borrow_mut(); let mut glutin = glutin_ctx.borrow_mut();
let last_builder = glutin.builders.entry(*id).or_insert(builder.clone()); let last_builder = glutin.builders.entry(*id).or_insert(builder.clone());
@@ -1258,7 +1261,7 @@ mod glow_integration {
if recreate { if recreate {
window.window = None; window.window = None;
window.gl_surface = None; window.gl_surface = None;
window.render = render.clone(); window.viewport_ui_cb = viewport_ui_cb.clone();
window.pair.parent = *id; window.pair.parent = *id;
} }
if let Some(w) = window.window.clone() { if let Some(w) = window.window.clone() {
@@ -1275,7 +1278,7 @@ mod glow_integration {
for ViewportOutput { for ViewportOutput {
mut builder, mut builder,
pair, pair,
render, viewport_ui_cb,
} in viewports } in viewports
{ {
let default_icon = glutin_ctx let default_icon = glutin_ctx
@@ -1295,7 +1298,7 @@ mod glow_integration {
gl_surface: None, gl_surface: None,
window: None, window: None,
egui_winit: None, egui_winit: None,
render, viewport_ui_cb,
pair, pair,
})), })),
); );
@@ -1426,7 +1429,8 @@ mod glow_integration {
{ {
let glutin = glutin.borrow(); let glutin = glutin.borrow();
let viewport = &glutin.viewports[&viewport_id].clone(); let viewport = &glutin.viewports[&viewport_id].clone();
if viewport.borrow().render.is_none() && viewport_id != ViewportId::MAIN { if viewport.borrow().viewport_ui_cb.is_none() && viewport_id != ViewportId::MAIN
{
if let Some(parent_viewport) = if let Some(parent_viewport) =
glutin.viewports.get(&viewport.borrow().pair.parent) glutin.viewports.get(&viewport.borrow().pair.parent)
{ {
@@ -1475,7 +1479,7 @@ mod glow_integration {
app.borrow_mut().as_mut(), app.borrow_mut().as_mut(),
&window, &window,
egui_winit, egui_winit,
&viewport.render.clone(), &viewport.viewport_ui_cb.clone(),
viewport.pair, viewport.pair,
); );
@@ -1870,7 +1874,7 @@ pub use glow_integration::run_glow;
#[cfg(feature = "wgpu")] #[cfg(feature = "wgpu")]
mod wgpu_integration { mod wgpu_integration {
use egui::{ViewportIdPair, ViewportOutput, ViewportRender}; use egui::{ViewportIdPair, ViewportOutput, ViewportUiCallback};
use egui_winit::create_winit_window_builder; use egui_winit::create_winit_window_builder;
use parking_lot::Mutex; use parking_lot::Mutex;
@@ -1880,7 +1884,7 @@ mod wgpu_integration {
pub struct Viewport { pub struct Viewport {
window: Option<Rc<RefCell<winit::window::Window>>>, window: Option<Rc<RefCell<winit::window::Window>>>,
state: Rc<RefCell<Option<egui_winit::State>>>, state: Rc<RefCell<Option<egui_winit::State>>>,
render: Option<Arc<Box<ViewportRender>>>, viewport_ui_cb: Option<Arc<Box<ViewportUiCallback>>>,
parent_id: ViewportId, parent_id: ViewportId,
} }
@@ -2149,7 +2153,7 @@ mod wgpu_integration {
Viewport { Viewport {
window: Some(Rc::new(RefCell::new(window))), window: Some(Rc::new(RefCell::new(window))),
state: Rc::new(RefCell::new(Some(state))), state: Rc::new(RefCell::new(Some(state))),
render: None, viewport_ui_cb: None,
parent_id: ViewportId::MAIN, parent_id: ViewportId::MAIN,
}, },
); );
@@ -2169,7 +2173,7 @@ mod wgpu_integration {
let beginning = integration.beginning; let beginning = integration.beginning;
integration.egui_ctx.set_render_sync_callback( integration.egui_ctx.set_render_sync_callback(
move |egui_ctx, viewport_builder, pair, render| { move |egui_ctx, viewport_builder, pair, viewport_ui_cb| {
if let ( if let (
Some(viewports), Some(viewports),
Some(builders), Some(builders),
@@ -2185,7 +2189,7 @@ mod wgpu_integration {
egui_ctx, egui_ctx,
viewport_builder, viewport_builder,
pair, pair,
render, viewport_ui_cb,
&viewports, &viewports,
&builders, &builders,
beginning, beginning,
@@ -2217,7 +2221,7 @@ mod wgpu_integration {
egui_ctx: &egui::Context, egui_ctx: &egui::Context,
mut viewport_builder: ViewportBuilder, mut viewport_builder: ViewportBuilder,
pair: ViewportIdPair, pair: ViewportIdPair,
render: Box<dyn FnOnce(&egui::Context) + '_>, viewport_ui_cb: Box<dyn FnOnce(&egui::Context) + '_>,
viewports: &RefCell<Viewports>, viewports: &RefCell<Viewports>,
builders: &RefCell<HashMap<ViewportId, ViewportBuilder>>, builders: &RefCell<HashMap<ViewportId, ViewportBuilder>>,
beginning: Instant, beginning: Instant,
@@ -2243,7 +2247,7 @@ mod wgpu_integration {
viewports.entry(pair.this).or_insert(Viewport { viewports.entry(pair.this).or_insert(Viewport {
window: None, window: None,
state: Rc::new(RefCell::new(None)), state: Rc::new(RefCell::new(None)),
render: None, viewport_ui_cb: None,
parent_id: pair.parent, parent_id: pair.parent,
}); });
builders builders
@@ -2277,7 +2281,7 @@ mod wgpu_integration {
let mut input = winit_state.take_egui_input(&win); let mut input = winit_state.take_egui_input(&win);
input.time = Some(beginning.elapsed().as_secs_f64()); input.time = Some(beginning.elapsed().as_secs_f64());
let output = egui_ctx.run(input, pair, |ctx| { let output = egui_ctx.run(input, pair, |ctx| {
render(ctx); viewport_ui_cb(ctx);
}); });
let mut painter = painter.borrow_mut(); let mut painter = painter.borrow_mut();
@@ -2393,12 +2397,12 @@ mod wgpu_integration {
viewport_commands, viewport_commands,
}; };
{ {
let Some((viewport_id, Viewport{window: Some(window), state, render, parent_id })) = viewport_maps.borrow() let Some((viewport_id, Viewport{window: Some(window), state, viewport_ui_cb, parent_id })) = viewport_maps.borrow()
.get(&window_id) .get(&window_id)
.and_then(|id|(viewports.borrow().get(id).map(|w|(*id, w.clone())))) .and_then(|id|(viewports.borrow().get(id).map(|w|(*id, w.clone()))))
else{ return EventResult::Wait }; else{ return EventResult::Wait };
// This is used to not render a viewport if is sync // This is used to not render a viewport if is sync
if viewport_id != ViewportId::MAIN && render.is_none() { if viewport_id != ViewportId::MAIN && viewport_ui_cb.is_none() {
if let Some(viewport) = running.viewports.borrow().get(&parent_id) { if let Some(viewport) = running.viewports.borrow().get(&parent_id) {
if let Some(window) = viewport.window.as_ref() { if let Some(window) = viewport.window.as_ref() {
return EventResult::RepaintNext(window.borrow().id()); return EventResult::RepaintNext(window.borrow().id());
@@ -2423,8 +2427,11 @@ mod wgpu_integration {
app.as_mut(), app.as_mut(),
&window.borrow(), &window.borrow(),
state.borrow_mut().as_mut().unwrap(), state.borrow_mut().as_mut().unwrap(),
&render.clone(), &viewport_ui_cb.clone(),
ViewportIdPair::new(viewport_id, parent_id), ViewportIdPair {
this: viewport_id,
parent: parent_id,
},
); );
integration.borrow_mut().handle_platform_output( integration.borrow_mut().handle_platform_output(
@@ -2469,11 +2476,11 @@ mod wgpu_integration {
out_viewports.retain_mut( out_viewports.retain_mut(
|ViewportOutput { |ViewportOutput {
pair: ViewportIdPair { this: id, parent }, pair: ViewportIdPair { this: id, parent },
render, viewport_ui_cb,
.. ..
}| { }| {
if let Some(window) = viewports.borrow_mut().get_mut(id) { if let Some(window) = viewports.borrow_mut().get_mut(id) {
window.render = render.clone(); window.viewport_ui_cb = viewport_ui_cb.clone();
window.parent_id = *parent; window.parent_id = *parent;
active_viewports_ids.push(*id); active_viewports_ids.push(*id);
false false
@@ -2490,7 +2497,7 @@ mod wgpu_integration {
this: id, this: id,
parent: parent_id, parent: parent_id,
}, },
render, viewport_ui_cb,
} in out_viewports } in out_viewports
{ {
if builder.icon.is_none() { if builder.icon.is_none() {
@@ -2505,7 +2512,7 @@ mod wgpu_integration {
Viewport { Viewport {
window: None, window: None,
state: Rc::new(RefCell::new(None)), state: Rc::new(RefCell::new(None)),
render, viewport_ui_cb,
parent_id, parent_id,
}, },
); );

View File

@@ -159,8 +159,8 @@ struct ContextImpl {
/// State that is collected during a frame and then cleared /// State that is collected during a frame and then cleared
frame_state: HashMap<ViewportId, FrameState>, frame_state: HashMap<ViewportId, FrameState>,
/// Viewport Id, Parent Viewport Id /// How deeply nested are we?
frame_stack: Vec<ViewportIdPair>, viewport_stack: Vec<ViewportIdPair>,
// The output of a frame: // The output of a frame:
graphics: HashMap<ViewportId, GraphicLayers>, graphics: HashMap<ViewportId, GraphicLayers>,
@@ -173,7 +173,7 @@ struct ContextImpl {
viewports: HashMap<Id, Viewport>, viewports: HashMap<Id, Viewport>,
viewport_commands: Vec<(ViewportId, ViewportCommand)>, viewport_commands: Vec<(ViewportId, ViewportCommand)>,
viewport_counter: u64, viewport_id_generator: u64,
is_desktop: bool, is_desktop: bool,
force_embedding: bool, force_embedding: bool,
@@ -196,7 +196,7 @@ struct ContextImpl {
impl ContextImpl { impl ContextImpl {
fn begin_frame_mut(&mut self, mut new_raw_input: RawInput, pair: ViewportIdPair) { fn begin_frame_mut(&mut self, mut new_raw_input: RawInput, pair: ViewportIdPair) {
// This is used to pause the last frame // This is used to pause the last frame
if !self.frame_stack.is_empty() { if !self.viewport_stack.is_empty() {
let viewport_id = self.viewport_id(); let viewport_id = self.viewport_id();
self.memory.pause_frame(viewport_id); self.memory.pause_frame(viewport_id);
@@ -210,7 +210,7 @@ impl ContextImpl {
); );
} }
self.frame_stack.push(pair); self.viewport_stack.push(pair);
self.output.entry(self.viewport_id()).or_default(); self.output.entry(self.viewport_id()).or_default();
self.repaint.start_frame(self.viewport_id()); self.repaint.start_frame(self.viewport_id());
@@ -349,14 +349,18 @@ impl ContextImpl {
/// ///
/// In the case of this viewport is the main viewport will be `ViewportId::MAIN` /// In the case of this viewport is the main viewport will be `ViewportId::MAIN`
pub(crate) fn viewport_id(&self) -> ViewportId { pub(crate) fn viewport_id(&self) -> ViewportId {
self.frame_stack.last().copied().unwrap_or_default().this self.viewport_stack.last().copied().unwrap_or_default().this
} }
/// Return the `ViewportId` of his parent /// Return the `ViewportId` of his parent
/// ///
/// In the case of this viewport is the main viewport will be `ViewportId::MAIN` /// In the case of this viewport is the main viewport will be `ViewportId::MAIN`
pub(crate) fn parent_viewport_id(&self) -> ViewportId { pub(crate) fn parent_viewport_id(&self) -> ViewportId {
self.frame_stack.last().copied().unwrap_or_default().parent self.viewport_stack
.last()
.copied()
.unwrap_or_default()
.parent
} }
} }
@@ -1580,7 +1584,7 @@ impl Context {
builder, builder,
pair, pair,
used, used,
render, viewport_ui_cb,
}| { }| {
let retain = *used; let retain = *used;
@@ -1591,7 +1595,7 @@ impl Context {
viewports.push(ViewportOutput { viewports.push(ViewportOutput {
builder: builder.clone(), builder: builder.clone(),
pair: *pair, pair: *pair,
render: render.clone(), viewport_ui_cb: viewport_ui_cb.clone(),
}); });
(retain || viewport_id != pair.parent) (retain || viewport_id != pair.parent)
&& available_viewports.contains(&pair.parent) && available_viewports.contains(&pair.parent)
@@ -1601,8 +1605,8 @@ impl Context {
// This is used to resume the last frame! // This is used to resume the last frame!
let is_last = self.write(|ctx| { let is_last = self.write(|ctx| {
ctx.frame_stack.pop(); ctx.viewport_stack.pop();
ctx.frame_stack.is_empty() ctx.viewport_stack.is_empty()
}); });
if !is_last { if !is_last {
@@ -2534,14 +2538,14 @@ impl Context {
self.read(|ctx| ctx.viewports.get(&id.into()).map(|v| v.pair)) self.read(|ctx| ctx.viewports.get(&id.into()).map(|v| v.pair))
} }
/// For integrations: Is used to render a sync viewport! /// For integrations: Is used to render a sync viewport.
/// ///
/// This will only be set for the current thread! /// This will only be set for the current thread.
/// Can be set only one callback per thread! /// Can be set only one callback per thread.
/// ///
/// When a viewport sync is created will be rendered by this function /// When a viewport sync is created will be rendered by this function
/// ///
/// Look in `crates/eframe/native/run.rs` and search for `set_render_sync_callback` to see for what is used! /// Look in `crates/eframe/native/run.rs` and search for `set_render_sync_callback` to see for what is used.
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn set_render_sync_callback( pub fn set_render_sync_callback(
&self, &self,
@@ -2584,19 +2588,19 @@ impl Context {
/// ///
/// You will need to wrap your viewport state in an `Arc<RwLock<T>>` or `Arc<Mutex<T>>`. /// You will need to wrap your viewport state in an `Arc<RwLock<T>>` or `Arc<Mutex<T>>`.
/// When this is called again with the same id in `ViewportBuilder` the render function for that viewport will be updated. /// When this is called again with the same id in `ViewportBuilder` the render function for that viewport will be updated.
/// * `render`: will be called when the viewport receives a event or is requested to be rendered /// * `viewport_ui_cb`: will be called when the viewport receives a event or is requested to be rendered
/// ///
/// If this is no more called that viewport will be destroyed. /// If this is no more called that viewport will be destroyed.
/// ///
/// If you use a [`egui::CentralPanel`] you need to check if the viewport is a new window like: /// If you use a [`egui::CentralPanel`] you need to check if the viewport is a new window like:
/// `ctx.viewport_id() != ctx.parent_viewport_id` if false you should create a `egui::Window` /// `ctx.viewport_id() != ctx.parent_viewport_id` if false you should create a [`egui::Window`].
pub fn create_viewport( pub fn create_viewport(
&self, &self,
viewport_builder: ViewportBuilder, viewport_builder: ViewportBuilder,
render: impl Fn(&Context) + Send + Sync + 'static, viewport_ui_cb: impl Fn(&Context) + Send + Sync + 'static,
) { ) {
if self.force_embedding() { if self.force_embedding() {
render(self); viewport_ui_cb(self);
} else { } else {
self.write(|ctx| { self.write(|ctx| {
let viewport_id = ctx.viewport_id(); let viewport_id = ctx.viewport_id();
@@ -2604,10 +2608,10 @@ impl Context {
window.builder = viewport_builder; window.builder = viewport_builder;
window.pair.parent = viewport_id; window.pair.parent = viewport_id;
window.used = true; window.used = true;
window.render = Some(Arc::new(Box::new(render))); window.viewport_ui_cb = Some(Arc::new(Box::new(viewport_ui_cb)));
} else { } else {
let id = ViewportId(ctx.viewport_counter + 1); let id = ViewportId(ctx.viewport_id_generator + 1);
ctx.viewport_counter += 1; ctx.viewport_id_generator += 1;
ctx.viewports.insert( ctx.viewports.insert(
viewport_builder.id, viewport_builder.id,
Viewport { Viewport {
@@ -2617,7 +2621,7 @@ impl Context {
parent: viewport_id, parent: viewport_id,
}, },
used: true, used: true,
render: Some(Arc::new(Box::new(render))), viewport_ui_cb: Some(Arc::new(Box::new(viewport_ui_cb))),
}, },
); );
} }
@@ -2627,7 +2631,8 @@ impl Context {
/// This creates a new native window, if possible. /// This creates a new native window, if possible.
/// ///
/// This can only be called in the main thread. /// The given ui function will be called immediately.
/// This can only be called from the main thread.
/// ///
/// When this is called the current viewport will be paused /// When this is called the current viewport will be paused
/// This will render in a native window if is possible. /// This will render in a native window if is possible.
@@ -2639,39 +2644,43 @@ impl Context {
/// If this is no more called that viewport will be destroyed. /// If this is no more called that viewport will be destroyed.
/// ///
/// If you use a `egui::CentralPanel` you need to check if the viewport is a new window like: /// If you use a `egui::CentralPanel` you need to check if the viewport is a new window like:
/// `ctx.viewport_id() != ctx.parent_viewport_id` if false you should create a `egui::Window` /// `ctx.viewport_id() != ctx.parent_viewport_id` if false you should create a [`egui::Window`].
pub fn create_viewport_sync<T>( pub fn create_viewport_sync<T>(
&self, &self,
viewport_builder: ViewportBuilder, viewport_builder: ViewportBuilder,
func: impl FnOnce(&Context) -> T, viewport_ui_cb: impl FnOnce(&Context) -> T,
) -> T { ) -> T {
if self.force_embedding() { if self.force_embedding() {
func(self) viewport_ui_cb(self)
} else { } else {
let mut id_pair = ViewportIdPair::MAIN; let id_pair = self.write(|ctx| {
self.write(|ctx| { let parent = ctx.viewport_id();
id_pair.parent = ctx.viewport_id();
if let Some(window) = ctx.viewports.get_mut(&viewport_builder.id) { if let Some(window) = ctx.viewports.get_mut(&viewport_builder.id) {
// Existing
window.builder = viewport_builder.clone(); window.builder = viewport_builder.clone();
window.pair.parent = id_pair.parent; window.pair.parent = parent;
window.used = true; window.used = true;
window.render = None; window.viewport_ui_cb = None;
id_pair = window.pair; window.pair
} else { } else {
let id = ViewportId(ctx.viewport_counter + 1); // New
ctx.viewport_counter += 1; let id = ViewportId(ctx.viewport_id_generator + 1);
id_pair.this = id; ctx.viewport_id_generator += 1;
let id_pair = ViewportIdPair { this: id, parent };
ctx.viewports.insert( ctx.viewports.insert(
viewport_builder.id, viewport_builder.id,
Viewport { Viewport {
builder: viewport_builder.clone(), builder: viewport_builder.clone(),
pair: id_pair, pair: id_pair,
used: true, used: true,
render: None, viewport_ui_cb: None,
}, },
); );
id_pair
} }
}); });
let mut out = None; let mut out = None;
{ {
let out = &mut out; let out = &mut out;
@@ -2682,12 +2691,14 @@ impl Context {
self, self,
viewport_builder, viewport_builder,
id_pair, id_pair,
Box::new(move |context| *out = Some(func(context))), Box::new(move |context| *out = Some(viewport_ui_cb(context))),
); );
}); });
} }
out.expect("egui backend is implemented incorrectly! Context::set_render_sync_callback") out.expect(
"egui backend is implemented incorrectly - the user calback was never called",
)
} }
} }
} }

View File

@@ -34,10 +34,6 @@ impl ViewportIdPair {
this: ViewportId::MAIN, this: ViewportId::MAIN,
parent: ViewportId::MAIN, parent: ViewportId::MAIN,
}; };
pub fn new(this: ViewportId, parent: ViewportId) -> Self {
Self { this, parent }
}
} }
impl std::ops::Deref for ViewportIdPair { impl std::ops::Deref for ViewportIdPair {
@@ -48,9 +44,10 @@ impl std::ops::Deref for ViewportIdPair {
} }
} }
/// This is used to render an async viewport /// The user-code that shows the ui in the viewport.
pub type ViewportRender = dyn Fn(&Context) + Sync + Send; pub type ViewportUiCallback = dyn Fn(&Context) + Sync + Send;
/// Render the given viewport, calling the given ui callback.
pub type ViewportRenderSyncCallback = pub type ViewportRenderSyncCallback =
dyn for<'a> Fn(&Context, ViewportBuilder, ViewportIdPair, Box<dyn FnOnce(&Context) + 'a>); dyn for<'a> Fn(&Context, ViewportBuilder, ViewportIdPair, Box<dyn FnOnce(&Context) + 'a>);
@@ -429,12 +426,16 @@ pub(crate) struct Viewport {
pub(crate) builder: ViewportBuilder, pub(crate) builder: ViewportBuilder,
pub(crate) pair: ViewportIdPair, pub(crate) pair: ViewportIdPair,
pub(crate) used: bool, pub(crate) used: bool,
pub(crate) render: Option<Arc<Box<ViewportRender>>>,
/// The user-code that shows the GUI.
pub(crate) viewport_ui_cb: Option<Arc<Box<ViewportUiCallback>>>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct ViewportOutput { pub struct ViewportOutput {
pub builder: ViewportBuilder, pub builder: ViewportBuilder,
pub pair: ViewportIdPair, pub pair: ViewportIdPair,
pub render: Option<Arc<Box<ViewportRender>>>,
/// The user-code that shows the GUI.
pub viewport_ui_cb: Option<Arc<Box<ViewportUiCallback>>>,
} }