0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-26 00:19:07 -05:00

Improve performanc for ignore-tree function

This commit is contained in:
alonso.torres 2023-10-30 15:43:12 +01:00 committed by Andrés Moya
parent 218e08c919
commit 5111c3f0d2

View file

@ -15,10 +15,12 @@
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.math :as mth] [app.common.math :as mth]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.types.component :as ctk]
[app.common.types.container :as ctn] [app.common.types.container :as ctn]
[app.common.types.modifiers :as ctm] [app.common.types.modifiers :as ctm]
[app.common.types.shape.attrs :refer [editable-attrs]] [app.common.types.shape.attrs :refer [editable-attrs]]
[app.common.types.shape.layout :as ctl] [app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid]
[app.main.constants :refer [zoom-half-pixel-precision]] [app.main.constants :refer [zoom-half-pixel-precision]]
[app.main.data.workspace.changes :as dch] [app.main.data.workspace.changes :as dch]
[app.main.data.workspace.comments :as-alias dwcm] [app.main.data.workspace.comments :as-alias dwcm]
@ -43,34 +45,11 @@
;; When the interaction is finished (e.g. user releases mouse button), the ;; When the interaction is finished (e.g. user releases mouse button), the
;; apply-modifiers event is done, that consolidates all modifiers into the base ;; apply-modifiers event is done, that consolidates all modifiers into the base
;; geometric attributes of the shapes. ;; geometric attributes of the shapes.
(defn- check-delta (defn- check-delta
"If the shape is a component instance, check its relative position respect the "If the shape is a component instance, check its relative position respect the
root of the component, and see if it changes after applying a transformation." root of the component, and see if it changes after applying a transformation."
[shape root transformed-shape transformed-root objects modif-tree] [shape root transformed-shape transformed-root]
(let [root (let [shape-delta
(cond
(:component-root shape)
shape
(nil? root)
(ctn/get-component-shape objects shape {:allow-main? true})
:else root)
transformed-root
(cond
(:component-root transformed-shape)
transformed-shape
(nil? transformed-root)
(as-> (ctn/get-component-shape objects transformed-shape {:allow-main? true}) $
(gsh/transform-shape (merge $ (get modif-tree (:id $)))))
:else transformed-root)
shape-delta
(when root (when root
(gpt/point (- (gsh/left-bound shape) (gsh/left-bound root)) (gpt/point (- (gsh/left-bound shape) (gsh/left-bound root))
(- (gsh/top-bound shape) (gsh/top-bound root)))) (- (gsh/top-bound shape) (gsh/top-bound root))))
@ -80,12 +59,13 @@
(gpt/point (- (gsh/left-bound transformed-shape) (gsh/left-bound transformed-root)) (gpt/point (- (gsh/left-bound transformed-shape) (gsh/left-bound transformed-root))
(- (gsh/top-bound transformed-shape) (gsh/top-bound transformed-root)))) (- (gsh/top-bound transformed-shape) (gsh/top-bound transformed-root))))
distance (if (and shape-delta transformed-shape-delta) distance
(if (and shape-delta transformed-shape-delta)
(gpt/distance-vector shape-delta transformed-shape-delta) (gpt/distance-vector shape-delta transformed-shape-delta)
(gpt/point 0 0)) (gpt/point 0 0))
selrect (:selrect shape) selrect (:selrect shape)
transformed-selrect (:selrect transformed-shape) transformed-selrect (:selrect transformed-shape)]
;; There are cases in that the coordinates change slightly (e.g. when rounding ;; There are cases in that the coordinates change slightly (e.g. when rounding
;; to pixel, or when recalculating text positions in different zoom levels). ;; to pixel, or when recalculating text positions in different zoom levels).
@ -93,32 +73,59 @@
;; ;;
;; When the change is a resize, also has a transformation that may have the ;; When the change is a resize, also has a transformation that may have the
;; shape position unchanged. But in this case we do not want to ignore it. ;; shape position unchanged. But in this case we do not want to ignore it.
ignore-geometry? (and (and (< (:x distance) 1) (< (:y distance) 1)) (and (and (< (:x distance) 1) (< (:y distance) 1))
(mth/close? (:width selrect) (:width transformed-selrect)) (mth/close? (:width selrect) (:width transformed-selrect))
(mth/close? (:height selrect) (:height transformed-selrect)))] (mth/close? (:height selrect) (:height transformed-selrect)))))
[root transformed-root ignore-geometry?]))
(defn- get-ignore-tree (defn calculate-ignore-tree
"Retrieves a map with the flag `ignore-geometry?` given a tree of modifiers" "Retrieves a map with the flag `ignore-geometry?` given a tree of modifiers"
([modif-tree objects shape] [modif-tree objects]
(get-ignore-tree modif-tree objects shape nil nil {}))
([modif-tree objects shape root transformed-root ignore-tree] (letfn [(get-ignore-tree
(let [children (map (d/getf objects) (:shapes shape)) ([ignore-tree shape]
(let [shape-id (dm/get-prop shape :id)
shape-id (:id shape)
transformed-shape (gsh/transform-shape shape (dm/get-in modif-tree [shape-id :modifiers])) transformed-shape (gsh/transform-shape shape (dm/get-in modif-tree [shape-id :modifiers]))
[root transformed-root ignore-geometry?] root
(check-delta shape root transformed-shape transformed-root objects modif-tree) (if (:component-root shape)
shape
(ctn/get-component-shape objects shape {:allow-main? true}))
ignore-tree (assoc ignore-tree shape-id ignore-geometry?) transformed-root
(if (:component-root shape)
transformed-shape
(gsh/transform-shape root (dm/get-in modif-tree [(:id root) :modifiers])))]
(get-ignore-tree ignore-tree shape transformed-shape root transformed-root)))
([ignore-tree shape root transformed-root]
(let [shape-id (dm/get-prop shape :id)
transformed-shape (gsh/transform-shape shape (dm/get-in modif-tree [shape-id :modifiers]))]
(get-ignore-tree ignore-tree shape transformed-shape root transformed-root)))
([ignore-tree shape transformed-shape root transformed-root]
(let [shape-id (dm/get-prop shape :id)
ignore-tree
(cond-> ignore-tree
(and (some? root) (ctk/in-component-copy? shape))
(assoc
shape-id
(check-delta shape root transformed-shape transformed-root)))
set-child set-child
(fn [ignore-tree child] (fn [ignore-tree child]
(get-ignore-tree modif-tree objects child root transformed-root ignore-tree))] (get-ignore-tree ignore-tree child root transformed-root))]
(reduce set-child ignore-tree children)))) (->> (:shapes shape)
(map (d/getf objects))
(reduce set-child ignore-tree)))))]
;; we check twice because we want only to search parents of components but once the
;; tree is traversed we only want to process the objects in components
(->> (keys modif-tree)
(map #(get objects %))
(reduce get-ignore-tree nil))))
(defn assoc-position-data (defn assoc-position-data
[shape position-data old-shape] [shape position-data old-shape]
@ -131,7 +138,6 @@
(d/not-empty? position-data) (d/not-empty? position-data)
(assoc :position-data position-data)))) (assoc :position-data position-data))))
(defn update-grow-type (defn update-grow-type
[shape old-shape] [shape old-shape]
(let [auto-width? (= :auto-width (:grow-type shape)) (let [auto-width? (= :auto-width (:grow-type shape))
@ -455,16 +461,25 @@
(watch [_ state _] (watch [_ state _]
(let [text-modifiers (get state :workspace-text-modifier) (let [text-modifiers (get state :workspace-text-modifier)
objects (wsh/lookup-page-objects state) objects (wsh/lookup-page-objects state)
object-modifiers (if modifiers
object-modifiers
(if (some? modifiers)
(calculate-modifiers state ignore-constraints ignore-snap-pixel modifiers) (calculate-modifiers state ignore-constraints ignore-snap-pixel modifiers)
(get state :workspace-modifiers)) (get state :workspace-modifiers))
ids (or (keys object-modifiers) []) ids
ids-with-children (into (vec ids) (mapcat #(cph/get-children-ids objects %)) ids) (into []
(remove #(= % uuid/zero))
(keys object-modifiers))
ids-with-children
(into ids
(mapcat (partial cph/get-children-ids objects))
ids)
ignore-tree
(calculate-ignore-tree object-modifiers objects)
shapes (map (d/getf objects) ids)
ignore-tree (->> (map #(get-ignore-tree object-modifiers objects %) shapes)
(reduce merge {}))
undo-id (js/Symbol)] undo-id (js/Symbol)]
(rx/concat (rx/concat