From 17fefcf0bc1f736eaeb43b22da66195cb787a237 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 20 Oct 2025 15:34:33 +0200 Subject: [PATCH] :sparkles: Changes WASM serialization mechanism --- common/src/app/common/files/changes.cljc | 3 +- common/src/app/common/types/shape.cljc | 7 +-- frontend/src/app/main/data/changes.cljs | 29 ++++++++- .../app/main/data/workspace/modifiers.cljs | 23 ++++--- .../src/app/main/data/workspace/shapes.cljs | 27 ++++---- .../sidebar/options/menus/measures.cljs | 24 +++----- .../app/main/ui/workspace/viewport_wasm.cljs | 3 +- frontend/src/app/render_wasm/shape.cljs | 61 ++++--------------- 8 files changed, 75 insertions(+), 102 deletions(-) diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index eb196ac848..bfbd8db89f 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -517,8 +517,7 @@ (when verify? (check-changes items)) - (binding [*touched-changes* (volatile! #{}) - cts/*wasm-sync* (not cts/*wasm-sync-override*)] + (binding [*touched-changes* (volatile! #{})] (let [result (reduce #(or (process-change %1 %2) %1) data items) result (reduce process-touched-change result @*touched-changes*)] ;; Validate result shapes (only on the backend) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index c95bb6e0e5..36ab8ddce9 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -36,12 +36,7 @@ [app.common.uuid :as uuid] [clojure.set :as set])) -(defonce ^:dynamic *wasm-sync* false) - -;; This is a temporary workaround so the changes-builder doesn't generate updates -;; in the WASM model. -(defonce ^:dynamic *wasm-sync-override* false) - +(defonce ^:dynamic *shape-changes* nil) (defonce wasm-enabled? false) (defonce wasm-create-shape (constantly nil)) diff --git a/frontend/src/app/main/data/changes.cljs b/frontend/src/app/main/data/changes.cljs index 8e914ec00f..309c96c30d 100644 --- a/frontend/src/app/main/data/changes.cljs +++ b/frontend/src/app/main/data/changes.cljs @@ -7,14 +7,19 @@ (ns app.main.data.changes (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.files.changes :as cpc] [app.common.logging :as log] [app.common.time :as ct] + [app.common.types.shape :as cts] [app.common.types.shape-tree :as ctst] [app.common.uuid :as uuid] [app.main.data.event :as ev] [app.main.data.helpers :as dsh] + [app.main.features :as features] [app.main.worker :as mw] + [app.render-wasm.api :as wasm.api] + [app.render-wasm.shape :as wasm.shape] [beicon.v2.core :as rx] [potok.v2.core :as ptk])) @@ -99,7 +104,29 @@ pids (into #{} xf:map-page-id redo-changes)] (reduce #(ctst/update-object-indices %1 %2) fdata pids)))] - (update-in state [:files file-id :data] apply-changes))))) + (if (features/active-feature? state "render-wasm/v1") + ;; Update the wasm model + (let [shape-changes (volatile! {}) + + state + (binding [cts/*shape-changes* shape-changes] + (update-in state [:files file-id :data] apply-changes))] + + (let [objects (dm/get-in state [:files file-id :data :pages-index (:current-page-id state) :objects])] + (run! + (fn [[shape-id props]] + (wasm.api/use-shape shape-id) + (let [shape (get objects shape-id)] + (run! (partial wasm.shape/set-shape-wasm-attr! shape) props))) + @shape-changes)) + + (wasm.api/update-shape-tiles) + (wasm.api/request-render "set-wasm-attrs") + + state) + + ;; wasm renderer deactivated + (update-in state [:files file-id :data] apply-changes)))))) (defn commit "Create a commit event instance" diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index a25e6b27dd..72d4d60e90 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -19,7 +19,6 @@ [app.common.types.component :as ctk] [app.common.types.container :as ctn] [app.common.types.modifiers :as ctm] - [app.common.types.shape :as shape] [app.common.types.shape-tree :as ctst] [app.common.types.shape.attrs :refer [editable-attrs]] [app.common.types.shape.layout :as ctl] @@ -232,16 +231,17 @@ (update-vals #(map second %)))] ;; Props are grouped by id and then assoc to the shape the new value - (doseq [[id properties] wasm-props] - (let [shape - (->> properties - (reduce - (fn [shape {:keys [property value]}] - (assoc shape property value)) - (get objects id)))] + (run! (fn [[id properties]] + (let [shape + (->> properties + (reduce + (fn [shape {:keys [property value]}] + (assoc shape property value)) + (get objects id)))] - ;; With the new values to the shape change multi props - (wasm.shape/set-wasm-multi-attrs! shape (->> properties (map :property))))))) + ;; With the new values to the shape change multi props + (wasm.shape/set-wasm-multi-attrs! shape (->> properties (map :property))))) + wasm-props))) (defn clear-local-transform [] (ptk/reify ::clear-local-transform @@ -649,8 +649,7 @@ (let [objects (dsh/lookup-page-objects state) ignore-tree - (binding [shape/*wasm-sync* false] - (calculate-ignore-tree modif-tree objects)) + (calculate-ignore-tree modif-tree objects) options (-> params diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index 250ad14ff8..3df0560a32 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -78,20 +78,19 @@ (not-empty)) changes - (binding [cts/*wasm-sync-override* true] - (-> (pcb/empty-changes it page-id) - (pcb/set-save-undo? save-undo?) - (pcb/set-stack-undo? stack-undo?) - (cls/generate-update-shapes ids - update-fn - objects - {:attrs attrs - :changed-sub-attr changed-sub-attr - :ignore-tree ignore-tree - :ignore-touched ignore-touched - :with-objects? with-objects?}) - (cond-> undo-group - (pcb/set-undo-group undo-group)))) + (-> (pcb/empty-changes it page-id) + (pcb/set-save-undo? save-undo?) + (pcb/set-stack-undo? stack-undo?) + (cls/generate-update-shapes ids + update-fn + objects + {:attrs attrs + :changed-sub-attr changed-sub-attr + :ignore-tree ignore-tree + :ignore-touched ignore-touched + :with-objects? with-objects?}) + (cond-> undo-group + (pcb/set-undo-group undo-group))) changes (add-undo-group changes state)] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index b1d36ba01d..03ae048983 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -12,7 +12,6 @@ [app.common.geom.rect :as grc] [app.common.geom.shapes :as gsh] [app.common.logic.shapes :as cls] - [app.common.types.shape :as cts] [app.common.types.shape.layout :as ctl] [app.common.types.token :as tk] [app.main.constants :refer [size-presets]] @@ -295,9 +294,8 @@ (mf/use-fn (mf/deps ids) (fn [value attr] - (binding [cts/*wasm-sync* true] - (st/emit! (udw/trigger-bounding-box-cloaking ids) - (udw/update-dimensions ids attr value))))) + (st/emit! (udw/trigger-bounding-box-cloaking ids) + (udw/update-dimensions ids attr value)))) on-size-change (mf/use-fn @@ -306,16 +304,14 @@ (if (or (string? value) (int? value)) (do (st/emit! (udw/trigger-bounding-box-cloaking ids)) - (binding [cts/*wasm-sync* true] - (run! #(do-size-change value attr) shapes))) + (run! #(do-size-change value attr) shapes)) (do (let [resolved-value (:resolved-value (first value))] (st/emit! (udw/trigger-bounding-box-cloaking ids) (dwta/toggle-token {:token (first value) :attrs #{attr} :shape-ids ids})) - (binding [cts/*wasm-sync* true] - (run! #(do-size-change resolved-value attr) shapes))))))) + (run! #(do-size-change resolved-value attr) shapes)))))) on-proportion-lock-change (mf/use-fn @@ -337,16 +333,14 @@ (if (or (string? value) (int? value)) (do (st/emit! (udw/trigger-bounding-box-cloaking ids)) - (binding [cts/*wasm-sync* true] - (run! #(do-position-change %1 value attr) shapes))) + (run! #(do-position-change %1 value attr) shapes)) (do (let [resolved-value (:resolved-value (first value))] (st/emit! (udw/trigger-bounding-box-cloaking ids) (dwta/toggle-token {:token (first value) :attrs #{attr} :shape-ids ids})) - (binding [cts/*wasm-sync* true] - (run! #(do-position-change %1 resolved-value attr) shapes))))))) + (run! #(do-position-change %1 resolved-value attr) shapes)))))) ;; ROTATION do-rotation-change @@ -362,16 +356,14 @@ (if (or (string? value) (int? value)) (do (st/emit! (udw/trigger-bounding-box-cloaking ids)) - (binding [cts/*wasm-sync* true] - (run! #(do-rotation-change value) shapes))) + (run! #(do-rotation-change value) shapes)) (do (let [resolved-value (:resolved-value (first value))] (st/emit! (udw/trigger-bounding-box-cloaking ids) (dwta/toggle-token {:token (first value) :attrs #{:rotation} :shape-ids ids})) - (binding [cts/*wasm-sync* true] - (run! #(do-rotation-change resolved-value) shapes))))))) + (run! #(do-rotation-change resolved-value) shapes)))))) on-width-change (mf/use-fn (mf/deps on-size-change) #(on-size-change % :width)) diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs index d1628c2542..8872ce9304 100644 --- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs @@ -113,8 +113,7 @@ objects-modified (mf/with-memo [base-objects wasm-modifiers] - (binding [cts/*wasm-sync* false] - (apply-modifiers-to-selected selected base-objects wasm-modifiers))) + (apply-modifiers-to-selected selected base-objects wasm-modifiers)) selected-shapes (->> selected (into [] (keep (d/getf objects-modified))) diff --git a/frontend/src/app/render_wasm/shape.cljs b/frontend/src/app/render_wasm/shape.cljs index 148096795e..6cc2791c2f 100644 --- a/frontend/src/app/render_wasm/shape.cljs +++ b/frontend/src/app/render_wasm/shape.cljs @@ -6,14 +6,12 @@ (ns app.render-wasm.shape (:require - [app.common.data :as d] [app.common.data.macros :as dm] [app.common.transit :as t] [app.common.types.shape :as shape] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] [app.render-wasm.api :as api] - [beicon.v2.core :as rx] [cljs.core :as c] [cuerdas.core :as str])) @@ -121,7 +119,7 @@ ;; --- SHAPE IMPL -(defn- set-wasm-single-attr! +(defn set-shape-wasm-attr! [shape k] (let [v (get shape k) id (get shape :id)] @@ -233,51 +231,12 @@ (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)] - (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-id (dm/get-prop shape :id) - old-value (get shape k)] - (when (and (shape-in-current-page? shape-id) - (not (identical? old-value v))) - (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")))))))) + (run! (partial set-shape-wasm-attr! shape) properties)))) (defn- impl-assoc [self k v] - (when ^boolean shape/*wasm-sync* - (binding [shape/*wasm-sync* false] - (set-wasm-attrs! self k v))) + (when shape/*shape-changes* + (vswap! shape/*shape-changes* update (:id self) (fnil conj #{}) k)) (case k :id @@ -299,10 +258,14 @@ (defn- impl-dissoc [self k] - (when ^boolean shape/*wasm-sync* - (binding [shape/*wasm-sync* false] - (when (shape-in-current-page? (.-id ^ShapeProxy self)) - (set-wasm-attrs! self k nil)))) + #_(when ^boolean shape/*wasm-sync* + (binding [shape/*wasm-sync* false] + (when (shape-in-current-page? (.-id ^ShapeProxy self)) + (set-wasm-attrs! self k nil)))) + + (when shape/*shape-changes* + (vswap! shape/*shape-changes* update (:id self) (fnil conj #{}) k)) + (case k :id (ShapeProxy. nil