Improved set-modifiers-recursive and some utils memoization

This commit is contained in:
alonso.torres 2021-11-25 16:01:15 +01:00
parent 9024408ed2
commit 9d66984c62
8 changed files with 70 additions and 63 deletions

View file

@ -252,6 +252,11 @@
#?(:clj (Object.) #?(:clj (Object.)
:cljs (js/Object.))) :cljs (js/Object.)))
(defn getf
"Returns a function to access a map"
[coll]
(partial get coll))
(defn update-in-when (defn update-in-when
[m key-seq f & args] [m key-seq f & args]
(let [found (get-in m key-seq sentinel)] (let [found (get-in m key-seq sentinel)]

View file

@ -220,6 +220,7 @@
"Given a new set of points transformed, set up the rectangle so it keeps "Given a new set of points transformed, set up the rectangle so it keeps
its properties. We adjust de x,y,width,height and create a custom transform" its properties. We adjust de x,y,width,height and create a custom transform"
[shape transform round-coords?] [shape transform round-coords?]
;; FIXME: Improve performance
(let [points (-> shape :points (gco/transform-points transform)) (let [points (-> shape :points (gco/transform-points transform))
center (gco/center-points points) center (gco/center-points points)
@ -491,17 +492,20 @@
([shape {:keys [round-coords?] ([shape {:keys [round-coords?]
:or {round-coords? true}}] :or {round-coords? true}}]
(let [shape (apply-displacement shape)
center (gco/center-shape shape) (if (and (contains? shape :modifiers) (empty? (:modifiers shape)))
modifiers (:modifiers shape)] (dissoc shape :modifiers)
(if (and modifiers center) (let [shape (apply-displacement shape)
(let [transform (modifiers->transform center modifiers)] center (gco/center-shape shape)
(-> shape modifiers (:modifiers shape)]
(set-flip modifiers) (if (and modifiers center)
(apply-transform transform round-coords?) (let [transform (modifiers->transform center modifiers)]
(apply-text-resize modifiers) (-> shape
(dissoc :modifiers))) (set-flip modifiers)
shape)))) (apply-transform transform round-coords?)
(apply-text-resize modifiers)
(dissoc :modifiers)))
shape)))))
(defn calc-transformed-parent-rect (defn calc-transformed-parent-rect
[parent parent-modifiers] [parent parent-modifiers]

View file

@ -69,6 +69,7 @@
(d/export helpers/compact-path) (d/export helpers/compact-path)
(d/export helpers/compact-name) (d/export helpers/compact-name)
(d/export helpers/unframed-shape?) (d/export helpers/unframed-shape?)
(d/export helpers/children-seq)
;; Indices ;; Indices
(d/export indices/calculate-z-index) (d/export indices/calculate-z-index)

View file

@ -99,7 +99,7 @@
(get-in component [:objects (:id component)])) (get-in component [:objects (:id component)]))
;; Implemented with transient for performance ;; Implemented with transient for performance
(defn get-children (defn get-children*
"Retrieve all children ids recursively for a given object. The "Retrieve all children ids recursively for a given object. The
children's order will be breadth first." children's order will be breadth first."
[id objects] [id objects]
@ -128,6 +128,8 @@
(recur result (pop! pending) next)) (recur result (pop! pending) next))
(persistent! result))))) (persistent! result)))))
(def get-children (memoize get-children*))
(defn get-children-objects (defn get-children-objects
"Retrieve all children objects recursively for a given object" "Retrieve all children objects recursively for a given object"
[id objects] [id objects]
@ -172,9 +174,10 @@
shape shape
(get objects (:frame-id shape)))) (get objects (:frame-id shape))))
(defn clean-loops (defn clean-loops*
"Clean a list of ids from circular references." "Clean a list of ids from circular references."
[objects ids] [objects ids]
(let [parent-selected? (let [parent-selected?
(fn [id] (fn [id]
(let [parents (get-parents id objects)] (let [parents (get-parents id objects)]
@ -188,6 +191,8 @@
(reduce add-element (d/ordered-set) ids))) (reduce add-element (d/ordered-set) ids)))
(def clean-loops (memoize clean-loops*))
(defn calculate-invalid-targets (defn calculate-invalid-targets
[shape-id objects] [shape-id objects]
(let [result #{shape-id} (let [result #{shape-id}
@ -494,3 +499,9 @@
(and (not= (:type shape) :frame) (and (not= (:type shape) :frame)
(= (:frame-id shape) uuid/zero))) (= (:frame-id shape) uuid/zero)))
(defn children-seq
"Creates a sequence of shapes through the objects tree"
[shape objects]
(tree-seq #(d/not-empty? (get shape :shapes))
#(->> (get % :shapes) (map (partial get objects)))
shape))

View file

@ -107,7 +107,6 @@
;; geometric attributes of the shapes. ;; geometric attributes of the shapes.
(declare set-modifiers-recursive) (declare set-modifiers-recursive)
(declare check-delta)
(declare set-local-displacement) (declare set-local-displacement)
(declare clear-local-transform) (declare clear-local-transform)
@ -195,39 +194,6 @@
(clear-local-transform) (clear-local-transform)
(dwu/commit-undo-transaction)))))) (dwu/commit-undo-transaction))))))
(defn- set-modifiers-recursive
[modif-tree objects shape modifiers root transformed-root ignore-constraints]
(let [children (->> (get shape :shapes [])
(map #(get objects %)))
transformed-shape (gsh/transform-shape (assoc shape :modifiers modifiers))
[root transformed-root ignore-geometry?]
(check-delta shape root transformed-shape transformed-root objects)
modifiers (assoc modifiers :ignore-geometry? ignore-geometry?)
transformed-rect (gsh/calc-transformed-parent-rect shape modifiers)
set-child
(fn [modif-tree child]
(let [child-modifiers
(gsh/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect)]
(set-modifiers-recursive modif-tree
objects
child
child-modifiers
root
transformed-root
ignore-constraints)))
modif-tree
(-> modif-tree
(assoc-in [(:id shape) :modifiers] modifiers))]
(reduce set-child modif-tree children)))
(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."
@ -262,6 +228,35 @@
[root transformed-root ignore-geometry?])) [root transformed-root ignore-geometry?]))
(defn- set-modifiers-recursive
[modif-tree objects shape modifiers root transformed-root ignore-constraints]
(let [children (map (d/getf objects) (:shapes shape))
transformed-shape (gsh/transform-shape (assoc shape :modifiers modifiers))
[root transformed-root ignore-geometry?]
(check-delta shape root transformed-shape transformed-root objects)
modifiers (assoc modifiers :ignore-geometry? ignore-geometry?)
transformed-rect (gsh/calc-transformed-parent-rect shape modifiers)
set-child
(fn [modif-tree child]
(let [child-modifiers
(gsh/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect)]
(cond-> modif-tree
(not (empty? (d/without-keys child-modifiers [:ignore-geometry?])))
(set-modifiers-new*
objects child child-modifiers root transformed-root ignore-constraints))))
modif-tree
(-> modif-tree
(assoc-in [(:id shape) :modifiers] modifiers))]
(reduce set-child modif-tree children)))
(defn- set-local-displacement [point] (defn- set-local-displacement [point]
(ptk/reify ::start-local-displacement (ptk/reify ::start-local-displacement
ptk/UpdateEvent ptk/UpdateEvent

View file

@ -245,7 +245,7 @@
objects (cond-> objects objects (cond-> objects
with-modifiers? with-modifiers?
(gsh/merge-modifiers modifiers)) (gsh/merge-modifiers modifiers))
xform (comp (map #(get objects %)) xform (comp (map (d/getf objects))
(remove nil?))] (remove nil?))]
(into [] xform ids)))] (into [] xform ids)))]
(l/derived selector st/state =)))) (l/derived selector st/state =))))
@ -300,19 +300,10 @@
(def selected-shapes-with-children (def selected-shapes-with-children
(letfn [(selector [{:keys [selected objects]}] (letfn [(selector [{:keys [selected objects]}]
(let [children (->> selected (let [xform (comp (remove nil?)
(mapcat #(cp/get-children % objects)) (mapcat #(cp/get-children % objects)))
(filterv (comp not nil?)))] shapes (into selected xform selected)]
(into selected children)))] (mapv (d/getf objects) shapes)))]
(l/derived selector selected-data =)))
(def selected-objects-with-children
(letfn [(selector [{:keys [selected objects]}]
(let [children (->> selected
(mapcat #(cp/get-children % objects))
(filterv (comp not nil?)))
shapes (into selected children)]
(mapv #(get objects %) shapes)))]
(l/derived selector selected-data =))) (l/derived selector selected-data =)))
;; ---- Viewer refs ;; ---- Viewer refs

View file

@ -92,7 +92,7 @@
page-id (mf/use-ctx ctx/current-page-id) page-id (mf/use-ctx ctx/current-page-id)
file-id (mf/use-ctx ctx/current-file-id) file-id (mf/use-ctx ctx/current-file-id)
shapes (mf/deref refs/selected-objects) shapes (mf/deref refs/selected-objects)
shapes-with-children (mf/deref refs/selected-objects-with-children)] shapes-with-children (mf/deref refs/selected-shapes-with-children)]
[:& options-content {:shapes shapes [:& options-content {:shapes shapes
:selected selected :selected selected
:shapes-with-children shapes-with-children :shapes-with-children shapes-with-children

View file

@ -18,7 +18,7 @@
(mf/defc booleans-options (mf/defc booleans-options
[] []
(let [selected (mf/deref refs/selected-objects) (let [selected (mf/deref refs/selected-objects)
selected-with-children (mf/deref refs/selected-objects-with-children) selected-with-children (mf/deref refs/selected-shapes-with-children)
has-invalid-shapes? (->> selected-with-children has-invalid-shapes? (->> selected-with-children
(some (comp #{:frame :text} :type))) (some (comp #{:frame :text} :type)))