Bound GPU uploads and complete Greek and performance integration

This commit is contained in:
Hakan Seven committed 2026-09-04 20:26:29 +03:00
1 parent 89624f64fc
commit 9d991d7feb
14 files changed
+678 -380

No files matched your search

+41 -16
View File
@@ -360,22 +360,7 @@ impl Scene {
self.selected.len()
}
/// Returns the sorted set of entity-type names present in the active
/// layout. Used to populate the Quick Select "Object type" dropdown
/// with only the types that actually exist in the drawing.
/// Distinct entity type names in the current layout, for the
/// selection-filter menu.
///
/// The status bar rebuilds on every frame, so this used to run once per
/// mouse move over the canvas: a full clone of the layout's handle list
/// (1.16 M handles, ~9 MB, on the reproducer), then a lookup, a `String`
/// allocation and a `BTreeSet` insert for each one — about 107 ms of a
/// 110 ms frame, to produce roughly twenty names.
///
/// The answer only changes when entities are added or removed, so it is
/// cached against `geometry_epoch` and the layout block. The scan itself
/// now borrows the handle list instead of cloning it and collects
/// `&str`, allocating only for the names it actually returns.
/// Sorted entity types in the current layout, cached until geometry or layout changes.
pub fn entity_type_names_in_layout(&self) -> std::sync::Arc<Vec<String>> {
use crate::entities::traits::entity_type_name;
let block = self.current_layout_block_handle();
@@ -969,6 +954,46 @@ impl Scene {
mod tests {
use super::*;
#[test]
fn layout_type_cache_reuses_and_invalidates_on_edits_undo_and_layout() {
use acadrust::entities::{Circle, EntityType, Line};
use acadrust::types::Vector3;
use std::sync::Arc;
let mut scene = Scene::new();
let empty = scene.entity_type_names_in_layout();
assert!(empty.is_empty());
assert!(Arc::ptr_eq(&empty, &scene.entity_type_names_in_layout()));
scene.add_entity(EntityType::Line(Line::from_points(
Vector3::new(0.0, 0.0, 0.0),
Vector3::new(1.0, 0.0, 0.0),
)));
let lines = scene.entity_type_names_in_layout();
assert_eq!(lines.as_slice(), ["Line"]);
assert!(Arc::ptr_eq(&lines, &scene.entity_type_names_in_layout()));
let circle = scene.add_entity(EntityType::Circle(Circle::new()));
let before = scene.document.get_entity_arc(circle);
assert_eq!(
scene.entity_type_names_in_layout().as_slice(),
["Circle", "Line"]
);
scene.erase_entities(&[circle]);
assert_eq!(scene.entity_type_names_in_layout().as_slice(), ["Line"]);
let changes = scene.apply_entity_delta(&[(circle, before, None)], true);
scene.bump_entities(&changes);
assert_eq!(
scene.entity_type_names_in_layout().as_slice(),
["Circle", "Line"]
);
scene.set_current_layout("Layout1".to_owned());
assert!(scene.entity_type_names_in_layout().is_empty());
scene.set_current_layout("Model".to_owned());
assert_eq!(
scene.entity_type_names_in_layout().as_slice(),
["Circle", "Line"]
);
}
#[test]
fn selection_fingerprint_tracks_final_set_only() {
let mut scene = Scene::default();