mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 13:08:07 -06:00
Merge pull request #2622 from storytold/fix/2593-render-countdown
Render Queue: elapsed and remaining time tick between frames (#2593)
This commit is contained in:
@@ -451,6 +451,22 @@ fn queue_drop(app: &EffectcraftApp, ui: &egui::Ui, rect: Rect, p: &egui::Painter
|
||||
}
|
||||
}
|
||||
|
||||
/// Elapsed and estimated remaining seconds at UI time `now`. The job reports them as frames
|
||||
/// finish; between reports they count on from the last one, as a clock does, so a slow frame
|
||||
/// doesn't read as a stalled render (#2593).
|
||||
fn live_times(ctx: &egui::Context, pr: &effectcraft_engine::render_queue::JobState, now: f64) -> (f64, Option<f64>) {
|
||||
let report = (pr.current, pr.done, pr.item_elapsed.to_bits());
|
||||
let since = ctx.data_mut(|d| {
|
||||
let seen = d.get_temp_mut_or_insert_with(egui::Id::unique("rq-progress-seen"), || (report, now));
|
||||
if seen.0 != report {
|
||||
*seen = (report, now);
|
||||
}
|
||||
seen.1
|
||||
});
|
||||
let dt = if pr.finished { 0.0 } else { (now - since).max(0.0) };
|
||||
(pr.item_elapsed + dt, pr.remaining.map(|r| (r - dt).max(0.0)))
|
||||
}
|
||||
|
||||
/// The Current Render strip inside `top`: title, elapsed / remaining time, Render, Stop, Notify
|
||||
/// and the progress bar.
|
||||
fn current_render_strip(app: &mut EffectcraftApp, ui: &mut egui::Ui, p: &egui::Painter, top: Rect, rq: &RqView, actions: &mut Vec<Action>) {
|
||||
@@ -461,11 +477,15 @@ fn current_render_strip(app: &mut EffectcraftApp, ui: &mut egui::Ui, p: &egui::P
|
||||
let cur_item = progress.as_ref().and_then(|p| p.current).and_then(|id| queue.iter().find(|i| i.id == id));
|
||||
let cur_name = cur_item.and_then(|i| app.session.project.item(i.comp)).map(|i| i.name.clone());
|
||||
if let Some(pr) = &progress {
|
||||
let rem = pr.remaining.map(hms).unwrap_or_else(|| "–".into());
|
||||
let (elapsed, remaining) = live_times(ui.ctx(), pr, ui.input(|i| i.time));
|
||||
if rendering {
|
||||
ui.ctx().request_repaint_after(std::time::Duration::from_millis(500));
|
||||
}
|
||||
let rem = remaining.map(hms).unwrap_or_else(|| "–".into());
|
||||
p.text(
|
||||
pos2(top.max.x - 12.0, top.min.y + 16.0),
|
||||
Align2::RIGHT_CENTER,
|
||||
format!("Elapsed: {} Est. Remain: {rem}", hms(pr.item_elapsed)),
|
||||
format!("Elapsed: {} Est. Remain: {rem}", hms(elapsed)),
|
||||
Tokens::ui(11.5),
|
||||
t.text_dim,
|
||||
);
|
||||
@@ -903,4 +923,26 @@ mod tests {
|
||||
assert_eq!(super::utc_stamp(u64::MAX), "584554051223-11-09 07:00:15");
|
||||
assert_eq!(super::hms(3725.4), "1:02:05");
|
||||
}
|
||||
|
||||
/// #2593: between progress reports the times count on from the last report, and a new
|
||||
/// report starts the count again.
|
||||
#[test]
|
||||
fn render_times_tick_between_reports() {
|
||||
let ctx = egui::Context::default();
|
||||
let mut pr = effectcraft_engine::render_queue::JobState {
|
||||
current: Some(1),
|
||||
done: 2,
|
||||
total: 10,
|
||||
item_elapsed: 20.0,
|
||||
remaining: Some(80.0),
|
||||
..Default::default()
|
||||
};
|
||||
assert_eq!(super::live_times(&ctx, &pr, 100.0), (20.0, Some(80.0)));
|
||||
assert_eq!(super::live_times(&ctx, &pr, 103.0), (23.0, Some(77.0)));
|
||||
assert_eq!(super::live_times(&ctx, &pr, 300.0).1, Some(0.0), "never below zero");
|
||||
(pr.done, pr.item_elapsed, pr.remaining) = (3, 31.0, Some(72.0));
|
||||
assert_eq!(super::live_times(&ctx, &pr, 301.0), (31.0, Some(72.0)));
|
||||
pr.finished = true;
|
||||
assert_eq!(super::live_times(&ctx, &pr, 400.0), (31.0, Some(72.0)), "a finished job stands still");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user