forked from 1b-agent/opencadstudio-upstream
perf: keep heavy work off UI thread
This commit is contained in:
1 parent
12bf126646
commit
deec48ad99
75 files changed
+11702
-518
No files matched your search
@@ -1,7 +1,7 @@
|
||||
//! Modal overlay shown while a CAD file is being loaded.
|
||||
//!
|
||||
//! Displays the file name, size, current phase, an indeterminate animated
|
||||
//! progress bar, and a Cancel button.
|
||||
//! Displays the file name, size, current phase, measured progress, and a
|
||||
//! Cancel button.
|
||||
|
||||
use iced::time::Instant;
|
||||
use iced::widget::{button, column, container, row, stack, text, Space};
|
||||
@@ -10,20 +10,18 @@ use std::sync::atomic::Ordering;
|
||||
|
||||
use crate::app::{
|
||||
Message, OpenProgress, OPEN_PHASE_CACHING, OPEN_PHASE_FINALIZING, OPEN_PHASE_PARSING,
|
||||
OPEN_PHASE_READING,
|
||||
OPEN_PHASE_READING, OPEN_PHASE_XREF,
|
||||
};
|
||||
|
||||
const CARD_WIDTH: f32 = 420.0;
|
||||
const BAR_TRACK_WIDTH: f32 = 380.0;
|
||||
const BAR_TRACK_HEIGHT: f32 = 6.0;
|
||||
const BAR_WINDOW_WIDTH: f32 = 100.0;
|
||||
/// Period of one back-and-forth bounce, in milliseconds.
|
||||
const BAR_PERIOD_MS: f32 = 1800.0;
|
||||
|
||||
fn phase_label(phase: u8) -> &'static str {
|
||||
match phase {
|
||||
OPEN_PHASE_READING => "Reading file…",
|
||||
OPEN_PHASE_PARSING => "Parsing entities…",
|
||||
OPEN_PHASE_XREF => "Loading references…",
|
||||
OPEN_PHASE_CACHING => "Building scene caches…",
|
||||
OPEN_PHASE_FINALIZING => "Finalizing…",
|
||||
_ => "Working…",
|
||||
@@ -46,29 +44,22 @@ fn format_size(bytes: u64) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute the left-offset of the moving highlight inside the track.
|
||||
/// Bounces left↔right using a triangle wave so the user sees motion even when
|
||||
/// the actual phase atomic stays put for a while.
|
||||
fn bar_offset(elapsed_ms: f32) -> f32 {
|
||||
let travel = (BAR_TRACK_WIDTH - BAR_WINDOW_WIDTH).max(0.0);
|
||||
let cycle = (elapsed_ms / BAR_PERIOD_MS).fract();
|
||||
let tri = if cycle < 0.5 {
|
||||
cycle * 2.0
|
||||
} else {
|
||||
(1.0 - cycle) * 2.0
|
||||
};
|
||||
tri * travel
|
||||
}
|
||||
pub fn view<'a>(progress: &'a OpenProgress, _now: Instant) -> Element<'a, Message> {
|
||||
let phase = progress.state.phase.load(Ordering::Acquire);
|
||||
let basis_points = progress
|
||||
.state
|
||||
.basis_points
|
||||
.load(Ordering::Relaxed)
|
||||
.min(10000);
|
||||
let fraction = basis_points as f32 / 10000.0;
|
||||
let fill_width = BAR_TRACK_WIDTH * fraction;
|
||||
let trailing = (BAR_TRACK_WIDTH - fill_width).max(0.0);
|
||||
|
||||
pub fn view<'a>(progress: &'a OpenProgress, now: Instant) -> Element<'a, Message> {
|
||||
let phase = progress.phase.load(Ordering::Relaxed);
|
||||
let elapsed_ms = now.saturating_duration_since(progress.started).as_millis() as f32;
|
||||
|
||||
// ── Animated indeterminate bar ────────────────────────────────────────
|
||||
let offset = bar_offset(elapsed_ms);
|
||||
let trailing = (BAR_TRACK_WIDTH - BAR_WINDOW_WIDTH - offset).max(0.0);
|
||||
|
||||
let bar_window: Element<'_, Message> = container(Space::new().width(Length::Fixed(BAR_WINDOW_WIDTH)).height(Length::Fixed(BAR_TRACK_HEIGHT)))
|
||||
let bar_fill: Element<'_, Message> = container(
|
||||
Space::new()
|
||||
.width(Length::Fixed(fill_width))
|
||||
.height(Length::Fixed(BAR_TRACK_HEIGHT)),
|
||||
)
|
||||
.style(|_: &Theme| container::Style {
|
||||
background: Some(Background::Color(Color {
|
||||
r: 0.30,
|
||||
@@ -84,11 +75,8 @@ pub fn view<'a>(progress: &'a OpenProgress, now: Instant) -> Element<'a, Message
|
||||
})
|
||||
.into();
|
||||
|
||||
let bar_moving: Element<'_, Message> = row![
|
||||
Space::new()
|
||||
.width(Length::Fixed(offset))
|
||||
.height(Length::Fixed(BAR_TRACK_HEIGHT)),
|
||||
bar_window,
|
||||
let bar_value: Element<'_, Message> = row![
|
||||
bar_fill,
|
||||
Space::new()
|
||||
.width(Length::Fixed(trailing))
|
||||
.height(Length::Fixed(BAR_TRACK_HEIGHT)),
|
||||
@@ -111,7 +99,7 @@ pub fn view<'a>(progress: &'a OpenProgress, now: Instant) -> Element<'a, Message
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
bar_moving,
|
||||
bar_value,
|
||||
]
|
||||
.width(Length::Fixed(BAR_TRACK_WIDTH))
|
||||
.height(Length::Fixed(BAR_TRACK_HEIGHT)),
|
||||
@@ -136,7 +124,11 @@ pub fn view<'a>(progress: &'a OpenProgress, now: Instant) -> Element<'a, Message
|
||||
a: 1.0,
|
||||
});
|
||||
|
||||
let phase_line = text(phase_label(phase))
|
||||
let phase_line = text(format!(
|
||||
"{} {:.1}%",
|
||||
phase_label(phase),
|
||||
basis_points as f32 / 100.0
|
||||
))
|
||||
.size(12)
|
||||
.color(Color {
|
||||
r: 0.70,
|
||||
|
||||
Reference in new issue
Block a user