Improve performance of shape-to-frame relationship calc.

This commit is contained in:
Andrey Antukh 2020-05-05 10:41:22 +02:00 committed by Alonso Torres
parent 6b9ed0c5a3
commit f5e277269c
2 changed files with 49 additions and 36 deletions

View file

@ -413,9 +413,11 @@
unames (retrieve-used-names objects) unames (retrieve-used-names objects)
name (generate-unique-name unames (:name shape)) name (generate-unique-name unames (:name shape))
frames (dwc/retrieve-frames objects)
frame-id (if (= :frame (:type shape)) frame-id (if (= :frame (:type shape))
uuid/zero uuid/zero
(dwc/calculate-frame-overlap objects shape)) (dwc/calculate-frame-overlap frames shape))
shape (merge shape (merge
(if (= :frame (:type shape)) (if (= :frame (:type shape))

View file

@ -162,7 +162,6 @@
;; --- Common Helpers & Events ;; --- Common Helpers & Events
;; TODO: move
(defn retrieve-toplevel-shapes (defn retrieve-toplevel-shapes
[objects] [objects]
(let [lookup #(get objects %) (let [lookup #(get objects %)
@ -178,46 +177,55 @@
(recur (first ids) (recur (first ids)
(rest ids) (rest ids)
(if (= :frame typ) (if (= :frame typ)
(into res (:shapes obj)) (into res (map lookup) (:shapes obj))
(conj res id)))))))) (conj res obj))))))))
(defn retrieve-frames
[objects]
(let [root (get objects uuid/zero)
loopfn (fn loopfn [ids]
(let [obj (get objects (first ids))]
(cond
(nil? obj)
nil
(= :frame (:type obj))
(lazy-seq (cons obj (loopfn (rest ids))))
:else
(lazy-seq (loopfn (rest ids))))))]
(loopfn (:shapes root))))
(defn- calculate-frame-overlap (defn- calculate-frame-overlap
[objects shape] [frames shape]
(let [rshp (geom/shape->rect-shape shape) (let [shape (geom/shape->rect-shape shape)
xf (comp
xfmt (comp (filter #(geom/overlaps? % shape))
(filter #(= :frame (:type %))) (take 1))
(filter #(not= (:id shape) (:id %))) frame (first (into [] xf frames))]
(filter #(not= uuid/zero (:id %)))
(filter #(geom/overlaps? % rshp)))
frame (->> (vals objects)
(sequence xfmt)
(first))]
(or (:id frame) uuid/zero))) (or (:id frame) uuid/zero)))
(defn- calculate-shape-to-frame-relationship-changes (defn- calculate-shape-to-frame-relationship-changes
[objects ids] [frames shapes]
(loop [id (first ids) (loop [shape (first shapes)
ids (rest ids) shapes (rest shapes)
rch [] rch []
uch []] uch []]
(if (nil? id) (if (nil? shape)
[rch uch] [rch uch]
(let [obj (get objects id) (let [fid (calculate-frame-overlap frames shape)]
fid (calculate-frame-overlap objects obj)] (if (not= fid (:frame-id shape))
(if (not= fid (:frame-id obj)) (recur (first shapes)
(recur (first ids) (rest shapes)
(rest ids)
(conj rch {:type :mov-objects (conj rch {:type :mov-objects
:parent-id fid :parent-id fid
:shapes [id]}) :shapes [(:id shape)]})
(conj uch {:type :mov-objects (conj uch {:type :mov-objects
:parent-id (:frame-id obj) :parent-id (:frame-id shape)
:shapes [id]})) :shapes [(:id shape)]}))
(recur (first ids) (recur (first shapes)
(rest ids) (rest shapes)
rch rch
uch)))))) uch))))))
@ -226,10 +234,13 @@
(ptk/reify ::rehash-shape-frame-relationship (ptk/reify ::rehash-shape-frame-relationship
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(let [page-id (:current-page-id state) (let [page-id (get-in state [:workspace-page :id])
objects (get-in state [:workspace-data page-id :objects]) objects (get-in state [:workspace-data page-id :objects])
ids (retrieve-toplevel-shapes objects)
[rch uch] (calculate-shape-to-frame-relationship-changes objects ids)] shapes (retrieve-toplevel-shapes objects)
frames (retrieve-frames objects)
[rch uch] (calculate-shape-to-frame-relationship-changes frames shapes)]
(when-not (empty? rch) (when-not (empty? rch)
(rx/of (commit-changes rch uch {:commit-local? true}))))))) (rx/of (commit-changes rch uch {:commit-local? true})))))))