From a16f40cb732f51b23c6b11a0acabe7f8eecbd83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Torr=C3=B3?= Date: Tue, 29 Jul 2025 13:00:40 +0200 Subject: [PATCH] :sparkles: Set page objects once on wasm render(#6994) --- .../app/main/ui/workspace/viewport_wasm.cljs | 6 +- frontend/src/app/render_wasm/api.cljs | 6 -- frontend/src/app/render_wasm/shape.cljs | 68 ++++++++++--------- 3 files changed, 41 insertions(+), 39 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs index a7c201d375..17b65398a5 100644 --- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs @@ -51,6 +51,7 @@ [app.main.ui.workspace.viewport.viewport-ref :refer [create-viewport-ref]] [app.main.ui.workspace.viewport.widgets :as widgets] [app.render-wasm.api :as wasm.api] + [app.render-wasm.shape :as wasm.shape] [app.util.debug :as dbg] [app.util.text-editor :as ted] [beicon.v2.core :as rx] @@ -280,7 +281,6 @@ (:x first-shape) (:x selected-frame)) - offset-y (if selecting-first-level-frame? (:y first-shape) (:y selected-frame)) @@ -292,7 +292,6 @@ ;; canvas, even though we are not using `page-id` inside the hook. ;; We think moving this out to a handler will make the render code ;; harder to follow through. - (mf/with-effect [page-id] (when-let [canvas (mf/ref-val canvas-ref)] (->> wasm.api/module @@ -349,6 +348,9 @@ (wasm.api/show-grid @hover-top-frame-id) (wasm.api/clear-grid)))) + (mf/with-effect [objects] + (wasm.shape/set-current-page-objects! objects)) + (hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool path-drawing?) (hooks/setup-viewport-size vport viewport-ref) (hooks/setup-cursor cursor alt? mod? space? panning drawing-tool path-drawing? path-editing? z? read-only?) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 6ce6d5f017..2f9fc38f0b 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -1068,9 +1068,3 @@ (js/console.error cause) (p/resolved false))))) (p/resolved false)))) - -(defn shape-in-current-page? - "Check if a shape is in the current page by looking up the current page objects" - [shape-id] - (let [objects (deref refs/workspace-page-objects)] - (contains? objects shape-id))) diff --git a/frontend/src/app/render_wasm/shape.cljs b/frontend/src/app/render_wasm/shape.cljs index 933695e540..466d8afefa 100644 --- a/frontend/src/app/render_wasm/shape.cljs +++ b/frontend/src/app/render_wasm/shape.cljs @@ -19,6 +19,15 @@ (declare ^:private impl-assoc) (declare ^:private impl-conj) (declare ^:private impl-dissoc) +(defonce ^:private current-page-objects {}) + +(defn set-current-page-objects! + [objects] + (set! current-page-objects objects)) + +(defn shape-in-current-page? + [shape-id] + (contains? current-page-objects shape-id)) (defn map-entry [k v] @@ -211,35 +220,13 @@ (defn set-wasm-multi-attrs! [shape properties] - ;; Only call WASM API if the shape is in the current page - (when (api/shape-in-current-page? (:id shape)) - (api/use-shape (:id shape)) - (let [result - (->> properties - (mapcat #(set-wasm-single-attr! shape %))) - pending (-> (d/index-by :key :callback result) vals)] - (if (and pending (seq pending)) - (->> (rx/from pending) - (rx/mapcat (fn [callback] (callback))) - (rx/reduce conj []) - (rx/subs! - (fn [_] - (api/update-shape-tiles) - (api/clear-drawing-cache) - (api/request-render "set-wasm-attrs-pending")))) - (do - (api/update-shape-tiles) - (api/request-render "set-wasm-attrs")))))) - -(defn set-wasm-attrs! - [shape k v] - (let [shape (assoc shape k v)] - ;; Only call WASM API if the shape is in the current page - (when (api/shape-in-current-page? (:id shape)) - (api/use-shape (:id shape)) - (let [result (set-wasm-single-attr! shape k) + (let [shape-id (dm/get-prop shape :id)] + (when (shape-in-current-page? shape-id) + (api/use-shape shape-id) + (let [result + (->> properties + (mapcat #(set-wasm-single-attr! shape %))) pending (-> (d/index-by :key :callback result) vals)] - ;; TODO: set-wasm-attrs is called twice with every set (if (and pending (seq pending)) (->> (rx/from pending) (rx/mapcat (fn [callback] (callback))) @@ -253,6 +240,27 @@ (api/update-shape-tiles) (api/request-render "set-wasm-attrs"))))))) +(defn set-wasm-attrs! + [shape k v] + (let [shape-id (dm/get-prop shape :id)] + (when (shape-in-current-page? shape-id) + (let [shape (assoc shape k v)] + (api/use-shape shape-id) + (let [result (set-wasm-single-attr! shape k) + pending (-> (d/index-by :key :callback result) vals)] + (if (and pending (seq pending)) + (->> (rx/from pending) + (rx/mapcat (fn [callback] (callback))) + (rx/reduce conj []) + (rx/subs! + (fn [_] + (api/update-shape-tiles) + (api/clear-drawing-cache) + (api/request-render "set-wasm-attrs-pending")))) + (do + (api/update-shape-tiles) + (api/request-render "set-wasm-attrs")))))))) + (defn- impl-assoc [self k v] (when ^boolean shape/*wasm-sync* @@ -281,10 +289,8 @@ [self k] (when ^boolean shape/*wasm-sync* (binding [shape/*wasm-sync* false] - ;; Only call WASM API if the shape is in the current page - (when (api/shape-in-current-page? (.-id ^ShapeProxy self)) + (when (shape-in-current-page? (.-id ^ShapeProxy self)) (set-wasm-attrs! self k nil)))) - (case k :id (ShapeProxy. nil