From f5e277269cf7bdc5a76a12b79b324882e949fc7e Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 5 May 2020 10:41:22 +0200 Subject: [PATCH] :sparkles: Improve performance of shape-to-frame relationship calc. --- frontend/src/uxbox/main/data/workspace.cljs | 4 +- .../src/uxbox/main/data/workspace/common.cljs | 81 +++++++++++-------- 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 02081c30c..2c6bbefed 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -413,9 +413,11 @@ unames (retrieve-used-names objects) name (generate-unique-name unames (:name shape)) + frames (dwc/retrieve-frames objects) + frame-id (if (= :frame (:type shape)) uuid/zero - (dwc/calculate-frame-overlap objects shape)) + (dwc/calculate-frame-overlap frames shape)) shape (merge (if (= :frame (:type shape)) diff --git a/frontend/src/uxbox/main/data/workspace/common.cljs b/frontend/src/uxbox/main/data/workspace/common.cljs index 887eec84e..7434cd02f 100644 --- a/frontend/src/uxbox/main/data/workspace/common.cljs +++ b/frontend/src/uxbox/main/data/workspace/common.cljs @@ -162,7 +162,6 @@ ;; --- Common Helpers & Events -;; TODO: move (defn retrieve-toplevel-shapes [objects] (let [lookup #(get objects %) @@ -178,46 +177,55 @@ (recur (first ids) (rest ids) (if (= :frame typ) - (into res (:shapes obj)) - (conj res id)))))))) + (into res (map lookup) (:shapes obj)) + (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 - [objects shape] - (let [rshp (geom/shape->rect-shape shape) - - xfmt (comp - (filter #(= :frame (:type %))) - (filter #(not= (:id shape) (:id %))) - (filter #(not= uuid/zero (:id %))) - (filter #(geom/overlaps? % rshp))) - - frame (->> (vals objects) - (sequence xfmt) - (first))] - + [frames shape] + (let [shape (geom/shape->rect-shape shape) + xf (comp + (filter #(geom/overlaps? % shape)) + (take 1)) + frame (first (into [] xf frames))] (or (:id frame) uuid/zero))) (defn- calculate-shape-to-frame-relationship-changes - [objects ids] - (loop [id (first ids) - ids (rest ids) - rch [] - uch []] - (if (nil? id) + [frames shapes] + (loop [shape (first shapes) + shapes (rest shapes) + rch [] + uch []] + (if (nil? shape) [rch uch] - (let [obj (get objects id) - fid (calculate-frame-overlap objects obj)] - (if (not= fid (:frame-id obj)) - (recur (first ids) - (rest ids) + (let [fid (calculate-frame-overlap frames shape)] + (if (not= fid (:frame-id shape)) + (recur (first shapes) + (rest shapes) (conj rch {:type :mov-objects :parent-id fid - :shapes [id]}) + :shapes [(:id shape)]}) (conj uch {:type :mov-objects - :parent-id (:frame-id obj) - :shapes [id]})) - (recur (first ids) - (rest ids) + :parent-id (:frame-id shape) + :shapes [(:id shape)]})) + (recur (first shapes) + (rest shapes) rch uch)))))) @@ -226,10 +234,13 @@ (ptk/reify ::rehash-shape-frame-relationship ptk/WatchEvent (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]) - 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) (rx/of (commit-changes rch uch {:commit-local? true})))))))