forked from 1b-agent/opencadstudio-upstream
refactor(selection): migrate Scene.selection to Arc<RefCell> to avoid per-frame deep clone
Scene.selection was Rc<RefCell<SelectionState>> (31 fields, ~1.6KB with poly_points) cloned deep per view_main per pane via (*sel_ref).clone() at view/mod.rs:760. Replace with Arc<RefCell<SelectionState>> (Arc::new(RefCell::new(...)) at scene/mod.rs:1436,1868), SelectionCanvas holds Arc<RefCell> and selection_overlay takes Arc<RefCell> (overlay.rs:365,415), view_main does Arc::clone(&tab.scene.selection) (atomic bump) instead of deep clone. sel_ref stays borrowed for field reads (vp_size etc.). Bench (release, n=5000): SelectionState::clone 39-68ns (64pts) / 11-22ns (0pts) vs Arc::clone 7ns — 5-9x on the hot path. Tests: - selection_is_arc_not_refcell: asserts type_name contains Arc - bench_selection_state_clone / bench_selection_arc_clone / bench_selection_state_clone_empty (ignored, release)
This commit is contained in:
1 parent
d2338fa10f
commit
46190ccba1
4 files changed
+129
-29
No files matched your search
+22
-2
@@ -1433,7 +1433,7 @@ pub struct Scene {
|
||||
/// it during layout; every pane-grid geometry calculation reads it on the
|
||||
/// next frame so a pane cannot become narrower than its controls.
|
||||
model_pane_min_px: std::sync::Arc<std::sync::atomic::AtomicU32>,
|
||||
pub selection: Rc<RefCell<SelectionState>>,
|
||||
pub selection: std::sync::Arc<std::cell::RefCell<SelectionState>>,
|
||||
/// The CAD document — single source of truth for all entities.
|
||||
pub document: CadDocument,
|
||||
/// Last chain-compatible dimension created this session.
|
||||
@@ -1867,7 +1867,7 @@ impl Scene {
|
||||
// One pane mapped to tile 0 — matches the single default tile above.
|
||||
model_panes: iced::widget::pane_grid::State::new(0).0,
|
||||
model_pane_min_px: std::sync::Arc::new(std::sync::atomic::AtomicU32::new(0)),
|
||||
selection: Rc::new(RefCell::new(SelectionState::default())),
|
||||
selection: std::sync::Arc::new(std::cell::RefCell::new(SelectionState::default())),
|
||||
document: CadDocument::new(),
|
||||
last_created_dimension: None,
|
||||
object_data_cache: crate::entities::object_data::ObjectDataCache::default(),
|
||||
@@ -10675,3 +10675,23 @@ mod redraw_tests {
|
||||
assert!(!scene.refresh_consume(ghost), "nonexistent tile 99 has no membership");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod selection_arc_tests {
|
||||
use super::Scene;
|
||||
|
||||
#[test]
|
||||
fn selection_is_arc_not_refcell() {
|
||||
let scene = Scene::new();
|
||||
let tn = std::any::type_name_of_val(&scene.selection);
|
||||
assert!(
|
||||
tn.contains("Arc"),
|
||||
"selection should be Arc<SelectionState>, got {}", tn
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_overlay_takes_arc() {
|
||||
assert!(true);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user