perf: stop scanning every entity for associative centers on each edit

The spans put it exactly: 63.5 ms of a 63.8 ms pointer-up is
`bump_entities`, and inside it two drawing-wide scans.

`refresh_associative_centerlines` and `refresh_associative_center_marks`
each walk all 1 166 357 entities, filter to Lines and parse every one's
extended data looking for an association that references a changed
handle. About 30 ms each, run on every edit -- to find, on this drawing,
none at all.

Track whether the document holds any such association. The question is
settled once, with a single pass, and after that each edit only examines
the handles it actually changed: an entity that carries an association
flips the answer to yes, and nothing else can. Deleting the last one
leaves the answer at yes, which costs a scan that finds nothing rather
than skipping one it should have run. A coarse `bump_geometry` re-opens
the question, since it can carry a new document.

Where an association really exists the scans run exactly as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
PanosandClaude Opus 5 committed 2026-09-05 09:10:49 +03:00
1 parent 13afc1479f
commit 69bd3c40a9
3 files changed
+75 -7

No files matched your search

+12
View File
@@ -473,3 +473,15 @@ impl Scene {
candidates.len()
}
}
/// Whether `entity` carries a center mark association.
///
/// Used to keep the drawing-wide scan off the edit path: only an entity that
/// actually carries one can make the scan necessary.
pub(crate) fn entity_has_center_association(entity: &EntityType) -> bool {
let EntityType::Line(line) = entity else {
return false;
};
CenterMarkAssociation::read(&line.common.extended_data)
.is_some_and(|association| association.associated)
}