mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 13:50:04 -04:00
Move the viewport commands into the per-viewport output
This commit is contained in:
@@ -564,7 +564,6 @@ mod glow_integration {
|
|||||||
shapes,
|
shapes,
|
||||||
pixels_per_point,
|
pixels_per_point,
|
||||||
viewports: viewports_out,
|
viewports: viewports_out,
|
||||||
viewport_commands,
|
|
||||||
} = full_output;
|
} = full_output;
|
||||||
|
|
||||||
let GlutinWindowContext {
|
let GlutinWindowContext {
|
||||||
@@ -649,19 +648,6 @@ mod glow_integration {
|
|||||||
|
|
||||||
glutin.process_viewport_updates(viewports_out, focused_viewport);
|
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() {
|
if integration.should_close() {
|
||||||
EventResult::Exit
|
EventResult::Exit
|
||||||
} else {
|
} else {
|
||||||
@@ -1169,7 +1155,7 @@ mod glow_integration {
|
|||||||
|
|
||||||
fn process_viewport_updates(
|
fn process_viewport_updates(
|
||||||
&mut self,
|
&mut self,
|
||||||
viewport_output: Vec<ViewportOutput>,
|
viewport_output: ViewportIdMap<ViewportOutput>,
|
||||||
focused_viewport: Option<ViewportId>,
|
focused_viewport: Option<ViewportId>,
|
||||||
) {
|
) {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
@@ -1177,13 +1163,17 @@ mod glow_integration {
|
|||||||
let mut active_viewports_ids = ViewportIdSet::default();
|
let mut active_viewports_ids = ViewportIdSet::default();
|
||||||
active_viewports_ids.insert(ViewportId::ROOT);
|
active_viewports_ids.insert(ViewportId::ROOT);
|
||||||
|
|
||||||
for ViewportOutput {
|
for (
|
||||||
ids,
|
viewport_id,
|
||||||
builder,
|
ViewportOutput {
|
||||||
viewport_ui_cb,
|
ids,
|
||||||
} in viewport_output
|
builder,
|
||||||
|
viewport_ui_cb,
|
||||||
|
commands,
|
||||||
|
},
|
||||||
|
) in viewport_output
|
||||||
{
|
{
|
||||||
active_viewports_ids.insert(ids.this);
|
active_viewports_ids.insert(viewport_id);
|
||||||
|
|
||||||
initialize_or_update_viewport(
|
initialize_or_update_viewport(
|
||||||
&mut self.viewports,
|
&mut self.viewports,
|
||||||
@@ -1192,6 +1182,17 @@ mod glow_integration {
|
|||||||
viewport_ui_cb,
|
viewport_ui_cb,
|
||||||
focused_viewport,
|
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
|
// GC old viewports
|
||||||
@@ -2455,10 +2456,7 @@ mod wgpu_integration {
|
|||||||
|
|
||||||
let raw_input = egui_winit.as_mut().unwrap().take_egui_input(
|
let raw_input = egui_winit.as_mut().unwrap().take_egui_input(
|
||||||
window,
|
window,
|
||||||
ViewportIdPair {
|
ViewportIdPair::from_self_and_parent(viewport_id, ids.parent),
|
||||||
this: viewport_id,
|
|
||||||
parent: ids.parent,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
integration.pre_update(window);
|
integration.pre_update(window);
|
||||||
@@ -2504,7 +2502,6 @@ mod wgpu_integration {
|
|||||||
shapes,
|
shapes,
|
||||||
pixels_per_point,
|
pixels_per_point,
|
||||||
viewports: out_viewports,
|
viewports: out_viewports,
|
||||||
viewport_commands,
|
|
||||||
} = full_output;
|
} = full_output;
|
||||||
|
|
||||||
integration.handle_platform_output(window, viewport_id, platform_output, egui_winit);
|
integration.handle_platform_output(window, viewport_id, platform_output, egui_winit);
|
||||||
@@ -2532,13 +2529,17 @@ mod wgpu_integration {
|
|||||||
active_viewports_ids.insert(ViewportId::ROOT);
|
active_viewports_ids.insert(ViewportId::ROOT);
|
||||||
|
|
||||||
// Add new viewports, and update existing ones:
|
// Add new viewports, and update existing ones:
|
||||||
for ViewportOutput {
|
for (
|
||||||
ids,
|
viewport_id,
|
||||||
builder,
|
ViewportOutput {
|
||||||
viewport_ui_cb,
|
ids,
|
||||||
} in out_viewports
|
builder,
|
||||||
|
viewport_ui_cb,
|
||||||
|
commands,
|
||||||
|
},
|
||||||
|
) in out_viewports
|
||||||
{
|
{
|
||||||
active_viewports_ids.insert(ids.this);
|
active_viewports_ids.insert(viewport_id);
|
||||||
|
|
||||||
initialize_or_update_viewport(
|
initialize_or_update_viewport(
|
||||||
viewports,
|
viewports,
|
||||||
@@ -2547,16 +2548,13 @@ mod wgpu_integration {
|
|||||||
viewport_ui_cb,
|
viewport_ui_cb,
|
||||||
focused_viewport,
|
focused_viewport,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Handle viewport commands:
|
|
||||||
for (viewport_id, command) in viewport_commands {
|
|
||||||
if let Some(window) = viewports
|
if let Some(window) = viewports
|
||||||
.get(&viewport_id)
|
.get(&viewport_id)
|
||||||
.and_then(|vp| vp.window.as_ref())
|
.and_then(|vp| vp.window.as_ref())
|
||||||
{
|
{
|
||||||
let is_viewport_focused = focused_viewport == Some(viewport_id);
|
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:
|
// The output of a frame:
|
||||||
graphics: GraphicLayers,
|
graphics: GraphicLayers,
|
||||||
output: PlatformOutput,
|
output: PlatformOutput,
|
||||||
|
commands: Vec<ViewportCommand>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Per-viewport state related to repaint scheduling.
|
/// Per-viewport state related to repaint scheduling.
|
||||||
@@ -185,7 +186,6 @@ struct ContextImpl {
|
|||||||
|
|
||||||
viewport_parents: ViewportIdMap<ViewportId>,
|
viewport_parents: ViewportIdMap<ViewportId>,
|
||||||
viewports: ViewportIdMap<ViewportState>,
|
viewports: ViewportIdMap<ViewportState>,
|
||||||
viewport_commands: Vec<(ViewportId, ViewportCommand)>,
|
|
||||||
|
|
||||||
embed_viewports: bool,
|
embed_viewports: bool,
|
||||||
|
|
||||||
@@ -1563,24 +1563,36 @@ impl ContextImpl {
|
|||||||
true
|
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!
|
// This is used to resume the last frame!
|
||||||
self.viewport_stack.pop();
|
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 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 {
|
if is_last {
|
||||||
// Remove dead viewports:
|
// Remove dead viewports:
|
||||||
self.viewports.retain(|id, _| all_viewport_ids.contains(id));
|
self.viewports.retain(|id, _| all_viewport_ids.contains(id));
|
||||||
@@ -1597,12 +1609,6 @@ impl ContextImpl {
|
|||||||
shapes,
|
shapes,
|
||||||
pixels_per_point,
|
pixels_per_point,
|
||||||
viewports: out_viewports,
|
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.
|
/// Send a command to a speicfic viewport.
|
||||||
pub fn viewport_command_for(&self, id: ViewportId, command: ViewportCommand) {
|
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.
|
/// This creates a new native window, if possible.
|
||||||
@@ -2615,10 +2621,7 @@ impl Context {
|
|||||||
viewport.used = true;
|
viewport.used = true;
|
||||||
viewport.viewport_ui_cb = None; // it is immediate
|
viewport.viewport_ui_cb = None; // it is immediate
|
||||||
|
|
||||||
ViewportIdPair {
|
ViewportIdPair::from_self_and_parent(new_viewport_id, parent_viewport_id)
|
||||||
this: new_viewport_id,
|
|
||||||
parent: parent_viewport_id,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut out = None;
|
let mut out = None;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! All the data egui returns to the backend at the end of each frame.
|
//! 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`].
|
/// 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`].
|
/// You can pass this to [`crate::Context::tessellate`] together with [`Self::shapes`].
|
||||||
pub pixels_per_point: f32,
|
pub pixels_per_point: f32,
|
||||||
|
|
||||||
/// All the active viewports, excluding the root.
|
/// All the active viewports, including the root.
|
||||||
pub viewports: Vec<ViewportOutput>,
|
pub viewports: ViewportIdMap<ViewportOutput>,
|
||||||
|
|
||||||
/// Commands sent to different viewports.
|
|
||||||
pub viewport_commands: Vec<(ViewportId, ViewportCommand)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FullOutput {
|
impl FullOutput {
|
||||||
@@ -41,16 +38,24 @@ impl FullOutput {
|
|||||||
textures_delta,
|
textures_delta,
|
||||||
shapes,
|
shapes,
|
||||||
pixels_per_point,
|
pixels_per_point,
|
||||||
mut viewports,
|
viewports,
|
||||||
mut viewport_commands,
|
|
||||||
} = newer;
|
} = newer;
|
||||||
|
|
||||||
self.platform_output.append(platform_output);
|
self.platform_output.append(platform_output);
|
||||||
self.textures_delta.append(textures_delta);
|
self.textures_delta.append(textures_delta);
|
||||||
self.shapes = shapes; // Only paint the latest
|
self.shapes = shapes; // Only paint the latest
|
||||||
self.pixels_per_point = pixels_per_point; // Use 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,
|
this: ViewportId::ROOT,
|
||||||
parent: 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.
|
/// 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.
|
/// `None` for immediate viewports and the ROOT viewport.
|
||||||
pub viewport_ui_cb: Option<Arc<ViewportUiCallback>>,
|
pub viewport_ui_cb: Option<Arc<ViewportUiCallback>>,
|
||||||
|
|
||||||
|
/// Commands to change the viewport, e.g. window title and size.
|
||||||
|
pub commands: Vec<ViewportCommand>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ViewportOutput {
|
impl ViewportOutput {
|
||||||
pub fn id(&self) -> ViewportId {
|
pub fn id(&self) -> ViewportId {
|
||||||
self.ids.this
|
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.
|
/// Viewport for immediate rendering.
|
||||||
|
|||||||
Reference in New Issue
Block a user