diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index 0d12396f3c..eb196ac848 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -518,7 +518,7 @@ (check-changes items)) (binding [*touched-changes* (volatile! #{}) - cts/*wasm-sync* true] + cts/*wasm-sync* (not cts/*wasm-sync-override*)] (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/files/changes_builder.cljc b/common/src/app/common/files/changes_builder.cljc index e27940ef1b..2fb3ddfa53 100644 --- a/common/src/app/common/files/changes_builder.cljc +++ b/common/src/app/common/files/changes_builder.cljc @@ -638,6 +638,7 @@ (reduce add-undo-change-shape $ ids))) (apply-changes-local))))) +;; FIXME: PERFORMANCE (defn resize-parents [changes ids] (assert-page-id! changes) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index 0ab6b79581..c95bb6e0e5 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -38,6 +38,10 @@ (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 wasm-enabled? false) (defonce wasm-create-shape (constantly nil)) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 698bafd7b2..f0c4dbcfcb 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -68,7 +68,7 @@ [app.main.repo :as rp] [app.main.router :as rt] [app.render-wasm :as wasm] - [app.render-wasm.api :as api] + [app.render-wasm.api :as wasm.api] [app.util.dom :as dom] [app.util.globals :as ug] [app.util.http :as http] @@ -265,7 +265,7 @@ ptk/EffectEvent (effect [_ state _] (let [objects (dsh/lookup-page-objects state)] - (api/process-object (get objects id)))))) + (wasm.api/process-object (get objects id)))))) (defn initialize-workspace [team-id file-id] diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index 3df0560a32..250ad14ff8 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -78,19 +78,20 @@ (not-empty)) changes - (-> (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))) + (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)))) changes (add-undo-group changes state)] diff --git a/frontend/src/app/render_wasm.cljs b/frontend/src/app/render_wasm.cljs index 89642811bf..7bf9de917f 100644 --- a/frontend/src/app/render_wasm.cljs +++ b/frontend/src/app/render_wasm.cljs @@ -9,15 +9,15 @@ (:require [app.common.types.path] [app.common.types.shape :as shape] - [app.render-wasm.api :as api] + [app.render-wasm.api :as wasm.api] [app.render-wasm.shape :as wasm.shape])) -(def module api/module) +(def module wasm.api/module) (defn initialize [enabled?] (if enabled? - (set! app.common.types.path/wasm:calc-bool-content api/calculate-bool) + (set! app.common.types.path/wasm:calc-bool-content wasm.api/calculate-bool) (set! app.common.types.path/wasm:calc-bool-content nil)) (set! app.common.types.shape/wasm-enabled? enabled?) (set! app.common.types.shape/wasm-create-shape wasm.shape/create-shape)) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 8396d2bdf3..f01ebd70fa 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -89,17 +89,16 @@ (def debounce-render (fns/debounce render 100)) -(defn cancel-render - [_] - (when wasm/internal-frame-id - (js/cancelAnimationFrame wasm/internal-frame-id) - (set! wasm/internal-frame-id nil))) +(defonce pending-render (atom false)) (defn request-render - [requester] - (when wasm/internal-frame-id (cancel-render requester)) - (let [frame-id (js/requestAnimationFrame render)] - (set! wasm/internal-frame-id frame-id))) + [_requester] + (when (not @pending-render) + (reset! pending-render true) + (js/requestAnimationFrame + (fn [ts] + (reset! pending-render false) + (render ts))))) (defn use-shape [id] diff --git a/frontend/src/app/render_wasm/helpers.cljc b/frontend/src/app/render_wasm/helpers.cljc index 671c12cc2d..5cb9b5f5ac 100644 --- a/frontend/src/app/render_wasm/helpers.cljc +++ b/frontend/src/app/render_wasm/helpers.cljc @@ -12,4 +12,6 @@ [module name & params] (let [fn-sym (with-meta (gensym "fn-") {:tag 'function})] `(let [~fn-sym (cljs.core/unchecked-get ~module ~name)] + ;; DEBUG + ;; (println "##" ~name) (~fn-sym ~@params)))) diff --git a/frontend/src/app/render_wasm/serializers.cljs b/frontend/src/app/render_wasm/serializers.cljs index 306a768f8e..f929ad5dac 100644 --- a/frontend/src/app/render_wasm/serializers.cljs +++ b/frontend/src/app/render_wasm/serializers.cljs @@ -7,6 +7,7 @@ (ns app.render-wasm.serializers (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.uuid :as uuid] [app.render-wasm.wasm :as wasm] [cuerdas.core :as str])) @@ -76,12 +77,13 @@ (defn serialize-path-attrs [svg-attrs] - (reduce - (fn [acc [key value]] - (str/concat + (reduce-kv + (fn [acc key value] + (dm/str acc (str/kebab key) "\0" - value "\0")) "" svg-attrs)) + value "\0")) "" + svg-attrs)) (defn translate-blend-mode [blend-mode] diff --git a/frontend/src/app/render_wasm/shape.cljs b/frontend/src/app/render_wasm/shape.cljs index 001a16842a..148096795e 100644 --- a/frontend/src/app/render_wasm/shape.cljs +++ b/frontend/src/app/render_wasm/shape.cljs @@ -121,7 +121,7 @@ ;; --- SHAPE IMPL -(defn set-wasm-single-attr! +(defn- set-wasm-single-attr! [shape k] (let [v (get shape k) id (get shape :id)] @@ -252,8 +252,10 @@ (defn set-wasm-attrs! [shape k v] - (let [shape-id (dm/get-prop shape :id)] - (when (shape-in-current-page? shape-id) + (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) diff --git a/render-wasm/src/shapes/modifiers.rs b/render-wasm/src/shapes/modifiers.rs index 59c2431431..6dafb1c202 100644 --- a/render-wasm/src/shapes/modifiers.rs +++ b/render-wasm/src/shapes/modifiers.rs @@ -88,6 +88,7 @@ fn propagate_children( result } +// FIXME: PERFORMANCE fn calculate_group_bounds( shape: &Shape, shapes: &ShapesPool, diff --git a/render-wasm/src/state.rs b/render-wasm/src/state.rs index bab9e60add..45ded3c67e 100644 --- a/render-wasm/src/state.rs +++ b/render-wasm/src/state.rs @@ -148,6 +148,7 @@ impl State { /// When a shape's selection rectangle changes, all its ancestors need to have their /// extended rectangles recalculated because the shape's bounds may have changed. /// This ensures proper rendering of frames and groups containing the modified shape. + // FIXME: PERFORMANCE pub fn set_selrect_for_current_shape(&mut self, left: f32, top: f32, right: f32, bottom: f32) { let shape = { let Some(shape) = self.current_shape_mut() else {