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
@@ -850,6 +850,8 @@ impl OpenCADStudio {
|
||||
.swap_structure(std::mem::replace(stored, acadrust::CadDocument::new()));
|
||||
*stored = inverse;
|
||||
self.tabs[i].scene.invalidate_dependency_index();
|
||||
self.tabs[i].scene.bump_layout_epoch();
|
||||
self.tabs[i].scene.bump_scale_epoch();
|
||||
}
|
||||
StructureSnapshot::Layers(entries) => {
|
||||
let names: Vec<String> =
|
||||
@@ -911,12 +913,31 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
StructureSnapshot::Objects(entries) => {
|
||||
let mut layout_touched = false;
|
||||
let mut scale_touched = false;
|
||||
for entry in entries {
|
||||
let value = if undo {
|
||||
entry.before.clone()
|
||||
} else {
|
||||
entry.after.clone()
|
||||
};
|
||||
// Either direction can add/remove a layout: undoing
|
||||
// an insert removes it (`before` is `None`), redoing
|
||||
// re-inserts it — so both sides must be inspected.
|
||||
layout_touched |= matches!(
|
||||
entry.before,
|
||||
Some(acadrust::objects::ObjectType::Layout(_))
|
||||
) || matches!(
|
||||
entry.after,
|
||||
Some(acadrust::objects::ObjectType::Layout(_))
|
||||
);
|
||||
scale_touched |= matches!(
|
||||
entry.before,
|
||||
Some(acadrust::objects::ObjectType::Scale(_))
|
||||
) || matches!(
|
||||
entry.after,
|
||||
Some(acadrust::objects::ObjectType::Scale(_))
|
||||
);
|
||||
if let Some(object) = value {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
@@ -927,6 +948,12 @@ impl OpenCADStudio {
|
||||
self.tabs[i].scene.document.objects.remove(&entry.handle);
|
||||
}
|
||||
}
|
||||
if layout_touched {
|
||||
self.tabs[i].scene.bump_layout_epoch();
|
||||
}
|
||||
if scale_touched {
|
||||
self.tabs[i].scene.bump_scale_epoch();
|
||||
}
|
||||
}
|
||||
StructureSnapshot::Styles {
|
||||
before,
|
||||
|
||||
Reference in new issue
Block a user