mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Optimize editor performance for node selection, click target bounds, and batched messages (#3162)
* Don't clone messages during batch processing * Improve selected nodes perf and memoize network hash computation * Reuse click target bounding boxes for document bounds * Early terminate computing the connected count * Cleanup
This commit is contained in:
@@ -40,7 +40,7 @@ pub struct ClickTarget {
|
||||
|
||||
impl ClickTarget {
|
||||
pub fn new_with_subpath(subpath: Subpath<PointId>, stroke_width: f64) -> Self {
|
||||
let bounding_box = subpath.loose_bounding_box();
|
||||
let bounding_box = subpath.bounding_box();
|
||||
Self {
|
||||
target_type: ClickTargetType::Subpath(subpath),
|
||||
stroke_width,
|
||||
|
||||
@@ -426,6 +426,11 @@ impl SegmentDomain {
|
||||
self.all_connected(point).count()
|
||||
}
|
||||
|
||||
/// Enumerate the number of segments connected to a point. If a segment starts and ends at a point then it is counted twice.
|
||||
pub(crate) fn any_connected(&self, point: usize) -> bool {
|
||||
self.all_connected(point).next().is_some()
|
||||
}
|
||||
|
||||
/// Iterates over segments in the domain.
|
||||
///
|
||||
/// Tuple is: (id, start point, end point, handles)
|
||||
|
||||
@@ -322,6 +322,11 @@ impl Vector {
|
||||
self.point_domain.resolve_id(point).map_or(0, |point| self.segment_domain.connected_count(point))
|
||||
}
|
||||
|
||||
/// Enumerate the number of segments connected to a point. If a segment starts and ends at a point then it is counted twice.
|
||||
pub fn any_connected(&self, point: PointId) -> bool {
|
||||
self.point_domain.resolve_id(point).is_some_and(|point| self.segment_domain.any_connected(point))
|
||||
}
|
||||
|
||||
pub fn check_point_inside_shape(&self, transform: DAffine2, point: DVec2) -> bool {
|
||||
let number = self
|
||||
.stroke_bezpath_iter()
|
||||
|
||||
@@ -9,7 +9,7 @@ pub use graphene_core::uuid::NodeId;
|
||||
pub use graphene_core::uuid::generate_uuid;
|
||||
use graphene_core::{Context, ContextDependencies, Cow, MemoHash, ProtoNodeIdentifier, Type};
|
||||
use log::Metadata;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustc_hash::{FxBuildHasher, FxHashMap};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
@@ -551,9 +551,8 @@ impl PartialEq for NodeNetwork {
|
||||
/// Graph modification functions
|
||||
impl NodeNetwork {
|
||||
pub fn current_hash(&self) -> u64 {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
self.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
use std::hash::BuildHasher;
|
||||
FxBuildHasher.hash_one(self)
|
||||
}
|
||||
|
||||
pub fn value_network(node: DocumentNode) -> Self {
|
||||
|
||||
@@ -1117,7 +1117,7 @@ impl Render for Table<Vector> {
|
||||
|
||||
// For free-floating anchors, we need to add a click target for each
|
||||
let single_anchors_targets = vector.point_domain.ids().iter().filter_map(|&point_id| {
|
||||
if vector.connected_count(point_id) == 0 {
|
||||
if !vector.any_connected(point_id) {
|
||||
let anchor = vector.point_domain.position_from_id(point_id).unwrap_or_default();
|
||||
let point = FreePoint::new(point_id, anchor);
|
||||
|
||||
@@ -1162,7 +1162,7 @@ impl Render for Table<Vector> {
|
||||
|
||||
// For free-floating anchors, we need to add a click target for each
|
||||
let single_anchors_targets = row.element.point_domain.ids().iter().filter_map(|&point_id| {
|
||||
if row.element.connected_count(point_id) > 0 {
|
||||
if row.element.any_connected(point_id) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user