mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Add egui_inspection::Request::Settle (#8344)
This allows inspection clients to know if the app is in a settled state and/or run the app until it settles (similar to egui_kittests `run`/`run_ok`).
This commit is contained in:
@@ -56,6 +56,9 @@ enum Phase {
|
|||||||
/// A screenshot was dispatched with this `user_data` id; reply when the matching
|
/// A screenshot was dispatched with this `user_data` id; reply when the matching
|
||||||
/// [`egui::Event::Screenshot`] arrives.
|
/// [`egui::Event::Screenshot`] arrives.
|
||||||
AwaitScreenshot { id: u64 },
|
AwaitScreenshot { id: u64 },
|
||||||
|
|
||||||
|
/// Watching for the app to go idle.
|
||||||
|
Settle { steps_taken: u64, max_steps: u64 },
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InFlight {
|
struct InFlight {
|
||||||
@@ -116,7 +119,12 @@ impl InspectionPlugin {
|
|||||||
/// While requests are still in flight, keep the UI loop spinning — reactive apps would
|
/// While requests are still in flight, keep the UI loop spinning — reactive apps would
|
||||||
/// otherwise go idle between hooks before a screenshot round-trips.
|
/// otherwise go idle between hooks before a screenshot round-trips.
|
||||||
fn maybe_repaint(&self, ctx: &Context) {
|
fn maybe_repaint(&self, ctx: &Context) {
|
||||||
if !self.in_flight.is_empty() {
|
// Don't repaint if there's only a `Request::Settle`.
|
||||||
|
if self
|
||||||
|
.in_flight
|
||||||
|
.iter()
|
||||||
|
.any(|item| !matches!(item.req, Request::Settle { .. }))
|
||||||
|
{
|
||||||
ctx.request_repaint();
|
ctx.request_repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,6 +244,13 @@ impl egui::Plugin for InspectionPlugin {
|
|||||||
item.phase = Phase::AwaitScreenshot { id };
|
item.phase = Phase::AwaitScreenshot { id };
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
Request::Settle { max_steps } => {
|
||||||
|
item.phase = Phase::Settle {
|
||||||
|
steps_taken: 0,
|
||||||
|
max_steps: *max_steps,
|
||||||
|
};
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.next_screenshot_id = next_id;
|
self.next_screenshot_id = next_id;
|
||||||
@@ -249,9 +264,14 @@ impl egui::Plugin for InspectionPlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let immediate_repaint = output
|
||||||
|
.viewport_output
|
||||||
|
.values()
|
||||||
|
.any(|viewport| viewport.repaint_delay == Duration::ZERO);
|
||||||
|
|
||||||
let step = self.step;
|
let step = self.step;
|
||||||
self.in_flight
|
self.in_flight
|
||||||
.retain_mut(|item| match (&item.phase, &item.req) {
|
.retain_mut(|item| match (&mut item.phase, &item.req) {
|
||||||
(Phase::AwaitOutput, Request::GetTree) => {
|
(Phase::AwaitOutput, Request::GetTree) => {
|
||||||
if let Some(reply) = item.reply.take() {
|
if let Some(reply) = item.reply.take() {
|
||||||
reply(Response::Tree {
|
reply(Response::Tree {
|
||||||
@@ -268,6 +288,27 @@ impl egui::Plugin for InspectionPlugin {
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
(
|
||||||
|
Phase::Settle {
|
||||||
|
steps_taken,
|
||||||
|
max_steps,
|
||||||
|
},
|
||||||
|
Request::Settle { .. },
|
||||||
|
) => {
|
||||||
|
*steps_taken += 1;
|
||||||
|
let steps_exceeded = *steps_taken >= *max_steps;
|
||||||
|
if !immediate_repaint || steps_exceeded {
|
||||||
|
if let Some(reply) = item.reply.take() {
|
||||||
|
reply(Response::Settled {
|
||||||
|
settled: !immediate_repaint,
|
||||||
|
steps: *steps_taken,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => true,
|
_ => true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ pub enum Request {
|
|||||||
/// (via [`egui::ViewportCommand::InnerSize`]). Reply: [`Response::Done`]. This is the one
|
/// (via [`egui::ViewportCommand::InnerSize`]). Reply: [`Response::Done`]. This is the one
|
||||||
/// action that isn't expressible as an [`egui::Event`].
|
/// action that isn't expressible as an [`egui::Event`].
|
||||||
Resize { width: u32, height: u32 },
|
Resize { width: u32, height: u32 },
|
||||||
|
|
||||||
|
/// Wait until the app goes idle, then reply [`Response::Settled`].
|
||||||
|
///
|
||||||
|
/// Will wait for at most `max_steps`.
|
||||||
|
Settle { max_steps: u64 },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sent peer → inspector, exactly one per [`Request`].
|
/// Sent peer → inspector, exactly one per [`Request`].
|
||||||
@@ -99,6 +104,15 @@ pub enum Response {
|
|||||||
/// (not merely received): the events were processed by a frame, or the resize dispatched.
|
/// (not merely received): the events were processed by a frame, or the resize dispatched.
|
||||||
Done,
|
Done,
|
||||||
|
|
||||||
|
/// Reply to [`Request::Settle`].
|
||||||
|
Settled {
|
||||||
|
/// Did we settle within `max_steps`?
|
||||||
|
settled: bool,
|
||||||
|
|
||||||
|
/// How many frames did we run until we settled?
|
||||||
|
steps: u64,
|
||||||
|
},
|
||||||
|
|
||||||
/// The peer failed to service the request (recoverable; the connection stays open).
|
/// The peer failed to service the request (recoverable; the connection stays open).
|
||||||
Error { message: String },
|
Error { message: String },
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user