forked from 1b-agent/opencadstudio-upstream
perf(statusbar): cache layout/scale derived data behind epochs (major)
Status bar rescanned the whole object map twice per frame (layout_names + scale_picker_list), deep-cloned an already-cached Arc, and built two undo/redo label vecs consumed ~never. Cache layout names (epoch key) and scale picker (epoch + unit-factor + imperial-family + current-scale key) as Arc behind choke-point invalidation (layout/scale impl methods, undo/redo swaps, file-open, doc-reset); borrow across the widget boundary (owned-Arc params; E0515 forbids &'a slices over call-site temporaries); build undo/redo labels only when their dropdown is open. Tests: - cached_layout_names_returns_same_arc_until_bump: hit-path Arc identity - cached_layout_names_invalidated_by_add_layout: bump yields new Arc + names - cached_scale_picker_returns_same_arc_until_bump: hit-path Arc identity - cached_scale_picker_invalidated_by_add_scale: bump yields new Arc + scale - cached_scale_picker_invalidated_by_current_scale_change: key completeness Bench (cargo bench ui_statusbar_derived_data, 3k entities): cached hit below timer granularity vs ~1us uncached scans, PASS (50us threshold).
This commit is contained in:
1 parent
baba5bccd3
commit
dcc05f310d
16 files changed
+327
-43
No files matched your search
@@ -17,11 +17,12 @@ pub fn menu_entries(
|
||||
is_model: bool,
|
||||
current_scale_name: &str,
|
||||
viewport_scale: Option<f64>,
|
||||
file_scales: Vec<(String, f32, f64)>,
|
||||
file_scales: &[(String, f32, f64)],
|
||||
) -> Vec<Entry<'static>> {
|
||||
let mut entries: Vec<Entry<'static>> = file_scales
|
||||
.into_iter()
|
||||
.iter()
|
||||
.map(|(label, _anno_scale, vp_scale)| {
|
||||
let vp_scale = *vp_scale;
|
||||
let active = if is_model {
|
||||
label.eq_ignore_ascii_case(current_scale_name)
|
||||
} else {
|
||||
@@ -38,7 +39,7 @@ pub fn menu_entries(
|
||||
} else {
|
||||
Message::SetViewportScale(label.clone())
|
||||
};
|
||||
Entry::close(scale_row(label, active, msg))
|
||||
Entry::close(scale_row(label.clone(), active, msg))
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::ui::statusbar::status_menu::Entry;
|
||||
/// - `types`: entity-type names present in the current layout.
|
||||
/// - `excluded`: types currently filtered out (unchecked).
|
||||
pub fn menu_entries(
|
||||
types: Vec<String>,
|
||||
types: &[String],
|
||||
excluded: &HashSet<String>,
|
||||
) -> Vec<Entry<'static>> {
|
||||
// "Select All / Clear All" header, mirroring the OSNAP popup: Select All
|
||||
@@ -51,10 +51,10 @@ pub fn menu_entries(
|
||||
vec![Entry::stay(empty_row())]
|
||||
} else {
|
||||
types
|
||||
.into_iter()
|
||||
.iter()
|
||||
.map(|name| {
|
||||
let included = !excluded.contains(&name);
|
||||
Entry::stay(type_row(name, included))
|
||||
let included = !excluded.contains(name);
|
||||
Entry::stay(type_row(name.clone(), included))
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user