mirror of
https://github.com/emilk/egui.git
synced 2026-06-27 15:13:12 -04:00
Move the viewport commands into the per-viewport output
This commit is contained in:
@@ -564,7 +564,6 @@ mod glow_integration {
|
||||
shapes,
|
||||
pixels_per_point,
|
||||
viewports: viewports_out,
|
||||
viewport_commands,
|
||||
} = full_output;
|
||||
|
||||
let GlutinWindowContext {
|
||||
@@ -649,19 +648,6 @@ mod glow_integration {
|
||||
|
||||
glutin.process_viewport_updates(viewports_out, focused_viewport);
|
||||
|
||||
for (viewport_id, command) in viewport_commands {
|
||||
if let Some(viewport) = glutin.viewports.get(&viewport_id) {
|
||||
if let Some(window) = &viewport.window {
|
||||
let is_viewport_focused = focused_viewport == Some(viewport_id);
|
||||
egui_winit::process_viewport_commands(
|
||||
[command],
|
||||
window,
|
||||
is_viewport_focused,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if integration.should_close() {
|
||||
EventResult::Exit
|
||||
} else {
|
||||
@@ -1169,7 +1155,7 @@ mod glow_integration {
|
||||
|
||||
fn process_viewport_updates(
|
||||
&mut self,
|
||||
viewport_output: Vec<ViewportOutput>,
|
||||
viewport_output: ViewportIdMap<ViewportOutput>,
|
||||
focused_viewport: Option<ViewportId>,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
@@ -1177,13 +1163,17 @@ mod glow_integration {
|
||||
let mut active_viewports_ids = ViewportIdSet::default();
|
||||
active_viewports_ids.insert(ViewportId::ROOT);
|
||||
|
||||
for ViewportOutput {
|
||||
ids,
|
||||
builder,
|
||||
viewport_ui_cb,
|
||||
} in viewport_output
|
||||
for (
|
||||
viewport_id,
|
||||
ViewportOutput {
|
||||
ids,
|
||||
builder,
|
||||
viewport_ui_cb,
|
||||
commands,
|
||||
},
|
||||
) in viewport_output
|
||||
{
|
||||
active_viewports_ids.insert(ids.this);
|
||||
active_viewports_ids.insert(viewport_id);
|
||||
|
||||
initialize_or_update_viewport(
|
||||
&mut self.viewports,
|
||||
@@ -1192,6 +1182,17 @@ mod glow_integration {
|
||||
viewport_ui_cb,
|
||||
focused_viewport,
|
||||
);
|
||||
|
||||
if let Some(viewport) = self.viewports.get(&viewport_id) {
|
||||
if let Some(window) = &viewport.window {
|
||||
let is_viewport_focused = focused_viewport == Some(viewport_id);
|
||||
egui_winit::process_viewport_commands(
|
||||
commands,
|
||||
window,
|
||||
is_viewport_focused,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GC old viewports
|
||||
@@ -2455,10 +2456,7 @@ mod wgpu_integration {
|
||||
|
||||
let raw_input = egui_winit.as_mut().unwrap().take_egui_input(
|
||||
window,
|
||||
ViewportIdPair {
|
||||
this: viewport_id,
|
||||
parent: ids.parent,
|
||||
},
|
||||
ViewportIdPair::from_self_and_parent(viewport_id, ids.parent),
|
||||
);
|
||||
|
||||
integration.pre_update(window);
|
||||
@@ -2504,7 +2502,6 @@ mod wgpu_integration {
|
||||
shapes,
|
||||
pixels_per_point,
|
||||
viewports: out_viewports,
|
||||
viewport_commands,
|
||||
} = full_output;
|
||||
|
||||
integration.handle_platform_output(window, viewport_id, platform_output, egui_winit);
|
||||
@@ -2532,13 +2529,17 @@ mod wgpu_integration {
|
||||
active_viewports_ids.insert(ViewportId::ROOT);
|
||||
|
||||
// Add new viewports, and update existing ones:
|
||||
for ViewportOutput {
|
||||
ids,
|
||||
builder,
|
||||
viewport_ui_cb,
|
||||
} in out_viewports
|
||||
for (
|
||||
viewport_id,
|
||||
ViewportOutput {
|
||||
ids,
|
||||
builder,
|
||||
viewport_ui_cb,
|
||||
commands,
|
||||
},
|
||||
) in out_viewports
|
||||
{
|
||||
active_viewports_ids.insert(ids.this);
|
||||
active_viewports_ids.insert(viewport_id);
|
||||
|
||||
initialize_or_update_viewport(
|
||||
viewports,
|
||||
@@ -2547,16 +2548,13 @@ mod wgpu_integration {
|
||||
viewport_ui_cb,
|
||||
focused_viewport,
|
||||
);
|
||||
}
|
||||
|
||||
// Handle viewport commands:
|
||||
for (viewport_id, command) in viewport_commands {
|
||||
if let Some(window) = viewports
|
||||
.get(&viewport_id)
|
||||
.and_then(|vp| vp.window.as_ref())
|
||||
{
|
||||
let is_viewport_focused = focused_viewport == Some(viewport_id);
|
||||
egui_winit::process_viewport_commands([command], window, is_viewport_focused);
|
||||
egui_winit::process_viewport_commands(commands, window, is_viewport_focused);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ struct ViewportState {
|
||||
// The output of a frame:
|
||||
graphics: GraphicLayers,
|
||||
output: PlatformOutput,
|
||||
commands: Vec<ViewportCommand>,
|
||||
}
|
||||
|
||||
/// Per-viewport state related to repaint scheduling.
|
||||
@@ -185,7 +186,6 @@ struct ContextImpl {
|
||||
|
||||
viewport_parents: ViewportIdMap<ViewportId>,
|
||||
viewports: ViewportIdMap<ViewportState>,
|
||||
viewport_commands: Vec<(ViewportId, ViewportCommand)>,
|
||||
|
||||
embed_viewports: bool,
|
||||
|
||||
@@ -1563,24 +1563,36 @@ impl ContextImpl {
|
||||
true
|
||||
});
|
||||
|
||||
let out_viewports = self
|
||||
.viewports
|
||||
.iter()
|
||||
.map(|(&id, viewport)| {
|
||||
let parent = *self.viewport_parents.entry(id).or_default();
|
||||
ViewportOutput {
|
||||
ids: ViewportIdPair { this: id, parent },
|
||||
builder: viewport.builder.clone(),
|
||||
viewport_ui_cb: viewport.viewport_ui_cb.clone(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// This is used to resume the last frame!
|
||||
self.viewport_stack.pop();
|
||||
|
||||
// The last viewport is not necessarily the root viewport,
|
||||
// just the top _immediate_ viewport.
|
||||
let is_last = self.viewport_stack.is_empty();
|
||||
|
||||
let out_viewports = self
|
||||
.viewports
|
||||
.iter_mut()
|
||||
.map(|(&id, viewport)| {
|
||||
let parent = *self.viewport_parents.entry(id).or_default();
|
||||
let commands = if is_last {
|
||||
std::mem::take(&mut viewport.commands)
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
(
|
||||
id,
|
||||
ViewportOutput {
|
||||
ids: ViewportIdPair::from_self_and_parent(id, parent),
|
||||
builder: viewport.builder.clone(),
|
||||
viewport_ui_cb: viewport.viewport_ui_cb.clone(),
|
||||
commands,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
if is_last {
|
||||
// Remove dead viewports:
|
||||
self.viewports.retain(|id, _| all_viewport_ids.contains(id));
|
||||
@@ -1597,12 +1609,6 @@ impl ContextImpl {
|
||||
shapes,
|
||||
pixels_per_point,
|
||||
viewports: out_viewports,
|
||||
// We should not process viewport commands when we are a sync viewport, because that will cause a deadlock for egui backend
|
||||
viewport_commands: if is_last {
|
||||
std::mem::take(&mut self.viewport_commands)
|
||||
} else {
|
||||
Vec::new()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2518,7 +2524,7 @@ impl Context {
|
||||
|
||||
/// Send a command to a speicfic viewport.
|
||||
pub fn viewport_command_for(&self, id: ViewportId, command: ViewportCommand) {
|
||||
self.write(|ctx| ctx.viewport_commands.push((id, command)));
|
||||
self.write(|ctx| ctx.viewport_for(id).commands.push(command));
|
||||
}
|
||||
|
||||
/// This creates a new native window, if possible.
|
||||
@@ -2615,10 +2621,7 @@ impl Context {
|
||||
viewport.used = true;
|
||||
viewport.viewport_ui_cb = None; // it is immediate
|
||||
|
||||
ViewportIdPair {
|
||||
this: new_viewport_id,
|
||||
parent: parent_viewport_id,
|
||||
}
|
||||
ViewportIdPair::from_self_and_parent(new_viewport_id, parent_viewport_id)
|
||||
});
|
||||
|
||||
let mut out = None;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! All the data egui returns to the backend at the end of each frame.
|
||||
|
||||
use crate::{ViewportCommand, ViewportId, ViewportOutput, WidgetType};
|
||||
use crate::{ViewportIdMap, ViewportOutput, WidgetType};
|
||||
|
||||
/// What egui emits each frame from [`crate::Context::run`].
|
||||
///
|
||||
@@ -26,11 +26,8 @@ pub struct FullOutput {
|
||||
/// You can pass this to [`crate::Context::tessellate`] together with [`Self::shapes`].
|
||||
pub pixels_per_point: f32,
|
||||
|
||||
/// All the active viewports, excluding the root.
|
||||
pub viewports: Vec<ViewportOutput>,
|
||||
|
||||
/// Commands sent to different viewports.
|
||||
pub viewport_commands: Vec<(ViewportId, ViewportCommand)>,
|
||||
/// All the active viewports, including the root.
|
||||
pub viewports: ViewportIdMap<ViewportOutput>,
|
||||
}
|
||||
|
||||
impl FullOutput {
|
||||
@@ -41,16 +38,24 @@ impl FullOutput {
|
||||
textures_delta,
|
||||
shapes,
|
||||
pixels_per_point,
|
||||
mut viewports,
|
||||
mut viewport_commands,
|
||||
viewports,
|
||||
} = newer;
|
||||
|
||||
self.platform_output.append(platform_output);
|
||||
self.textures_delta.append(textures_delta);
|
||||
self.shapes = shapes; // Only paint the latest
|
||||
self.pixels_per_point = pixels_per_point; // Use latest
|
||||
self.viewports.append(&mut viewports);
|
||||
self.viewport_commands.append(&mut viewport_commands);
|
||||
|
||||
for (id, new_viewport) in viewports {
|
||||
match self.viewports.entry(id) {
|
||||
std::collections::hash_map::Entry::Vacant(entry) => {
|
||||
entry.insert(new_viewport);
|
||||
}
|
||||
std::collections::hash_map::Entry::Occupied(mut entry) => {
|
||||
entry.get_mut().append(new_viewport);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,11 @@ impl ViewportIdPair {
|
||||
this: ViewportId::ROOT,
|
||||
parent: ViewportId::ROOT,
|
||||
};
|
||||
|
||||
#[inline]
|
||||
pub fn from_self_and_parent(this: ViewportId, parent: ViewportId) -> Self {
|
||||
Self { this, parent }
|
||||
}
|
||||
}
|
||||
|
||||
/// The user-code that shows the ui in the viewport, used for deferred viewports.
|
||||
@@ -669,12 +674,30 @@ pub struct ViewportOutput {
|
||||
///
|
||||
/// `None` for immediate viewports and the ROOT viewport.
|
||||
pub viewport_ui_cb: Option<Arc<ViewportUiCallback>>,
|
||||
|
||||
/// Commands to change the viewport, e.g. window title and size.
|
||||
pub commands: Vec<ViewportCommand>,
|
||||
}
|
||||
|
||||
impl ViewportOutput {
|
||||
pub fn id(&self) -> ViewportId {
|
||||
self.ids.this
|
||||
}
|
||||
|
||||
/// Add on new output.
|
||||
pub fn append(&mut self, newer: Self) {
|
||||
let Self {
|
||||
ids,
|
||||
builder,
|
||||
viewport_ui_cb,
|
||||
mut commands,
|
||||
} = newer;
|
||||
|
||||
self.ids = ids;
|
||||
self.builder.patch(&builder);
|
||||
self.viewport_ui_cb = viewport_ui_cb;
|
||||
self.commands.append(&mut commands);
|
||||
}
|
||||
}
|
||||
|
||||
/// Viewport for immediate rendering.
|
||||
|
||||
Reference in New Issue
Block a user