From 2030f987db3264b347d7a6782b2ef1b58dca1d5b Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 13 Feb 2023 17:33:41 +0100 Subject: [PATCH] :zap: Performance improvements --- .../src/app/common/geom/shapes/modifiers.cljc | 79 ++++++++++--------- common/src/app/common/pages/helpers.cljc | 19 ++++- .../src/app/main/ui/workspace/viewport.cljs | 31 +++++--- 3 files changed, 77 insertions(+), 52 deletions(-) diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index df17fefd9..3e69afb2f 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -46,46 +46,51 @@ :expr (or (nil? ids) (set? ids)) :hint (dm/str "tree sequence from not set: " ids)) - (letfn [(get-tree-root ;; Finds the tree root for the current id - [id] + (let [get-tree-root + (fn ;; Finds the tree root for the current id + [id] - (loop [current id - result id] - (let [shape (get objects current) - parent (get objects (:parent-id shape))] - (cond - (or (not shape) (= uuid/zero current)) + (loop [current id + result id] + (let [shape (get objects current) + parent (get objects (:parent-id shape))] + (cond + (or (not shape) (= uuid/zero current)) + result + + ;; Frame found, but not layout we return the last layout found (or the id) + (and (= :frame (:type parent)) + (not (ctl/any-layout? parent))) + result + + ;; Layout found. We continue upward but we mark this layout + (ctl/any-layout? parent) + (recur (:id parent) (:id parent)) + + ;; If group or boolean or other type of group we continue with the last result + :else + (recur (:id parent) result))))) + + is-child? #(cph/is-child? objects %1 %2) + + calculate-common-roots + (fn ;; Given some roots retrieves the minimum number of tree roots + [result id] + (if (= id uuid/zero) + result + (let [root (get-tree-root id) + + ;; Remove the children from the current root result + (if (cph/has-children? objects root) + (into #{} (remove #(is-child? root %)) result) + result) - ;; Frame found, but not layout we return the last layout found (or the id) - (and (= :frame (:type parent)) - (not (ctl/layout? parent))) - result - - ;; Layout found. We continue upward but we mark this layout - (ctl/layout? parent) - (recur (:id parent) (:id parent)) - - ;; If group or boolean or other type of group we continue with the last result - :else - (recur (:id parent) result))))) - - (calculate-common-roots ;; Given some roots retrieves the minimum number of tree roots - [result id] - (if (= id uuid/zero) - result - (let [root (get-tree-root id) - - ;; Remove the children from the current root - result - (into #{} (remove #(cph/is-child? objects root %)) result) - - contains-parent? - (some #(cph/is-child? objects % root) result)] - - (cond-> result - (not contains-parent?) - (conj root)))))] + root-parents (cph/get-parent-ids objects root) + contains-parent? (some #(contains? result %) root-parents)] + (cond-> result + (not contains-parent?) + (conj root)))))] (let [roots (->> ids (reduce calculate-common-roots #{}))] (concat diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 3c4649c5e..eedc9beff 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -76,6 +76,12 @@ (and (not (frame-shape? shape)) (= (:frame-id shape) uuid/zero))) +(defn has-children? + ([objects id] + (has-children? (get objects id))) + ([shape] + (d/not-empty? (:shapes shape)))) + (defn get-children-ids [objects id] (letfn [(get-children-ids-rec @@ -487,8 +493,17 @@ (defn is-child? [objects parent-id candidate-child-id] - (let [parents (get-parent-ids objects candidate-child-id)] - (some? (d/seek #(= % parent-id) parents)))) + (loop [cur-id candidate-child-id] + (let [cur-parent-id (dm/get-in objects [cur-id :parent-id])] + (cond + (= parent-id cur-parent-id) + true + + (or (= cur-parent-id uuid/zero) (nil? cur-parent-id)) + false + + :else + (recur cur-parent-id))))) (defn reduce-objects ([objects reducer-fn init-val] diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index f48c82a0b..20a5abe6f 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -51,17 +51,20 @@ (defn apply-modifiers-to-selected [selected objects text-modifiers modifiers] - (into [] - (comp - (keep (d/getf objects)) - (map (fn [{:keys [id] :as shape}] - (cond-> shape - (and (cph/text-shape? shape) (contains? text-modifiers id)) - (dwm/apply-text-modifier (get text-modifiers id)) + (reduce + (fn [objects id] + (update + objects id + (fn [shape] + (cond-> shape + (and (cph/text-shape? shape) (contains? text-modifiers id)) + (dwm/apply-text-modifier (get text-modifiers id)) - (contains? modifiers id) - (gsh/transform-shape (dm/get-in modifiers [id :modifiers])))))) - selected)) + (contains? modifiers id) + (gsh/transform-shape (dm/get-in modifiers [id :modifiers])))))) + + objects + selected)) (mf/defc viewport [{:keys [wlocal wglobal selected layout file] :as props}] @@ -97,8 +100,11 @@ modifiers (mf/deref refs/workspace-modifiers) text-modifiers (mf/deref refs/workspace-text-modifier) - objects-modified (mf/with-memo [base-objects modifiers] - (gsh/apply-objects-modifiers base-objects modifiers selected)) + objects-modified (mf/with-memo + [base-objects text-modifiers modifiers] + (apply-modifiers-to-selected selected base-objects text-modifiers modifiers)) + + selected-shapes (->> selected (keep (d/getf objects-modified))) background (get options :background clr/canvas) @@ -138,7 +144,6 @@ drawing-tool (:tool drawing) drawing-obj (:object drawing) - selected-shapes (apply-modifiers-to-selected selected base-objects text-modifiers modifiers) selected-frames (into #{} (map :frame-id) selected-shapes)