diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index 50a41e06f..59c52c0cc 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -371,8 +371,14 @@ "Given a new set of points transformed, set up the rectangle so it keeps its properties. We adjust de x,y,width,height and create a custom transform" [shape transform-mtx] - (if ^boolean (gmt/move? transform-mtx) + (cond + (nil? transform-mtx) + shape + + ^boolean (gmt/move? transform-mtx) (apply-transform-move shape transform-mtx) + + :else (apply-transform-generic shape transform-mtx))) (defn- update-group-viewbox diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index d8cc7cf22..22e5373ba 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -10,6 +10,7 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.files.helpers :as cfh] + [app.common.geom.matrix :as gmt] [app.common.geom.modifiers :as gm] [app.common.geom.point :as gpt] [app.common.geom.rect :as grc] @@ -484,9 +485,13 @@ [] (keep (fn [[id data]] - (when (ctm/has-geometry? (:modifiers data)) + (if (ctm/has-geometry? (:modifiers data)) {:id id - :transform (ctm/modifiers->transform (:modifiers data))}))) + :transform (ctm/modifiers->transform (:modifiers data))} + + ;; Unit matrix is used for reflowing + {:id id + :transform (gmt/matrix)}))) modif-tree)) (defn- extract-property-changes @@ -498,43 +503,69 @@ (filter (fn [[_ {:keys [type]}]] (= type :change-property))))) +#_:clj-kondo/ignore (defn set-wasm-modifiers - ([modif-tree] - (set-wasm-modifiers modif-tree false)) + [modif-tree & {:keys [ignore-constraints ignore-snap-pixel] + :or {ignore-constraints false ignore-snap-pixel false} + :as params}] + (ptk/reify ::set-wasm-modifiers + ptk/UpdateEvent + (update [_ state] + (let [property-changes + (extract-property-changes modif-tree)] - ([modif-tree ignore-constraints] - (set-wasm-modifiers modif-tree ignore-constraints false)) + (-> state + (assoc :prev-wasm-props (:wasm-props state)) + (assoc :wasm-props property-changes)))) - ([modif-tree ignore-constraints ignore-snap-pixel] - (set-wasm-modifiers modif-tree ignore-constraints ignore-snap-pixel nil)) + ptk/EffectEvent + (effect [_ state _] + (wasm.api/clean-modifiers) - ([modif-tree _ignore-constraints _ignore-snap-pixel _params] - (ptk/reify ::set-wasm-modifiers - ptk/UpdateEvent - (update [_ state] - (let [property-changes - (extract-property-changes modif-tree)] + (let [prev-wasm-props (:prev-wasm-props state) + wasm-props (:wasm-props state) + objects (dsh/lookup-page-objects state)] - (-> state - (assoc :prev-wasm-props (:wasm-props state)) - (assoc :wasm-props property-changes)))) + (set-wasm-props! objects prev-wasm-props wasm-props) - ptk/EffectEvent - (effect [_ state _] - (wasm.api/clean-modifiers) + (let [structure-entries (parse-structure-modifiers modif-tree)] + (wasm.api/set-structure-modifiers structure-entries) + (let [geometry-entries (parse-geometry-modifiers modif-tree)] + (wasm.api/propagate-apply geometry-entries))))))) - (let [prev-wasm-props (:prev-wasm-props state) - wasm-props (:wasm-props state) - objects (dsh/lookup-page-objects state)] +#_:clj-kondo/ignore +(defn apply-wasm-modifiers + [modif-tree & {:keys [ignore-constraints ignore-snap-pixel snap-ignore-axis undo-group] + :or {ignore-constraints false ignore-snap-pixel false snap-ignore-axis nil undo-group nil} + :as params}] + (ptk/reify ::apply-wasm-modifiesr + ptk/WatchEvent + (watch [_ _ _] + (let [geometry-entries + (parse-geometry-modifiers modif-tree) - (set-wasm-props! objects prev-wasm-props wasm-props) + transforms + (into + {} + (map (fn [{:keys [id transform]}] [id transform])) + (wasm.api/propagate-modifiers geometry-entries)) + + ids + (into (set (keys modif-tree)) (keys transforms)) + + update-shape + (fn [shape] + (let [shape-id (dm/get-prop shape :id) + transform (get transforms shape-id) + modifiers (dm/get-in modif-tree [shape-id :modifiers])] + (-> shape + (gsh/apply-transform transform) + (ctm/apply-structure-modifiers modifiers))))] + + (rx/of + (clear-local-transform) + (dwsh/update-shapes ids update-shape)))))) - (let [structure-entries (parse-structure-modifiers modif-tree)] - (wasm.api/set-structure-modifiers structure-entries) - (let [geometry-entries (parse-geometry-modifiers modif-tree) - modifiers-new - (wasm.api/propagate-modifiers geometry-entries)] - (wasm.api/set-modifiers modifiers-new)))))))) (defn set-selrect-transform [modifiers] diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 6436596b1..d4467630a 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -29,6 +29,7 @@ [app.main.data.workspace.selection :as dwse] [app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.undo :as dwu] + [app.main.features :as features] [beicon.v2.core :as rx] [potok.v2.core :as ptk])) @@ -101,13 +102,17 @@ (ptk/reify ::update-layout-positions ptk/WatchEvent (watch [_ state _] + (prn ">update-layout-positions") (let [objects (dsh/lookup-page-objects state) ids (->> ids (filter #(contains? objects %)))] (if (d/not-empty? ids) (let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))] - (rx/of (dwm/apply-modifiers {:modifiers modif-tree - :stack-undo? true - :undo-group undo-group}))) + (if (features/active-feature? state "render-wasm/v1") + (rx/of (dwm/apply-wasm-modifiers modif-tree :stack-undo? true :undo-group undo-group)) + + (rx/of (dwm/apply-modifiers {:modifiers modif-tree + :stack-undo? true + :undo-group undo-group})))) (rx/empty)))))) (defn initialize-shape-layout diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index ccd166395..1e50a0dc3 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -24,6 +24,7 @@ [app.common.types.container :as ctn] [app.common.types.modifiers :as ctm] [app.common.types.shape-tree :as ctst] + [app.common.types.shape.attrs :refer [editable-attrs]] [app.common.types.shape.layout :as ctl] [app.common.uuid :as uuid] [app.main.data.changes :as dch] @@ -279,28 +280,35 @@ modifiers-stream - (rx/merge - (->> resize-events-stream - (rx/mapcat - (fn [modifiers] - (let [modif-tree (dwm/create-modif-tree ids modifiers)] - (if (features/active-feature? state "render-wasm/v1") + (if (features/active-feature? state "render-wasm/v1") + (rx/merge + (->> resize-events-stream + (rx/mapcat + (fn [modifiers] + (let [modif-tree (dwm/create-modif-tree ids modifiers)] (rx/of (dwm/set-selrect-transform modifiers) - (dwm/set-wasm-modifiers modif-tree (contains? layout :scale-text))) + (dwm/set-wasm-modifiers + modif-tree + :ignore-constraints (contains? layout :scale-text)))))) + (rx/take-until stopper)) - (rx/of (dwm/set-modifiers modif-tree (contains? layout :scale-text))))))) - (rx/take-until stopper)) - - ;; The last event we need to use the old method so the elements are correctly positioned until - ;; all the logic is implemented in wasm - (if (features/active-feature? state "render-wasm/v1") + ;; The last event we need to use the old method so the elements are correctly positioned until + ;; all the logic is implemented in wasm (->> resize-events-stream (rx/take-until stopper) (rx/last) - (rx/map #(dwm/apply-modifiers {:modifiers (dwm/create-modif-tree ids %) - :ignore-constraints (contains? layout :scale-text)}))) - (rx/empty)))] + (rx/map + #(dwm/apply-wasm-modifiers + (dwm/create-modif-tree ids %) + :ignore-constraints (contains? layout :scale-text))))) + + (->> resize-events-stream + (rx/mapcat + (fn [modifiers] + (let [modif-tree (dwm/create-modif-tree ids modifiers)] + (rx/of (dwm/set-modifiers modif-tree (contains? layout :scale-text)))))) + (rx/take-until stopper)))] (rx/concat ;; This initial stream waits for some pixels to be move before making the resize @@ -313,11 +321,13 @@ (rx/take-until stopper) (rx/mapcat (fn [] modifiers-stream))) - (rx/of - (if (features/active-feature? state "render-wasm/v1") - (dwm/clear-local-transform) - (dwm/apply-modifiers)) - (finish-transform)))))))) + (if (features/active-feature? state "render-wasm/v1") + (rx/of + (finish-transform)) + + (rx/of + (dwm/apply-modifiers) + (finish-transform))))))))) (defn trigger-bounding-box-cloaking "Trigger the bounding box cloaking (with default timer of 1sec) @@ -368,7 +378,9 @@ (-> (dwm/build-modif-tree ids objects get-modifier) (gm/set-objects-modifiers objects))] - (rx/of (dwm/apply-modifiers* objects modif-tree nil options))))))) + (if (features/active-feature? state "render-wasm/v1") + (rx/of (dwm/apply-wasm-modifiers modif-tree)) + (rx/of (dwm/apply-modifiers* objects modif-tree nil options)))))))) (defn change-orientation "Change orientation of shapes, from the sidebar options form. @@ -384,23 +396,45 @@ (ptk/reify ::change-orientation ptk/UpdateEvent (update [_ state] - (let [objects (dsh/lookup-page-objects state) + (if (features/active-feature? state "render-wasm/v1") + state + (let [objects (dsh/lookup-page-objects state) - get-modifier - (fn [shape] (ctm/change-orientation-modifiers shape orientation)) + get-modifier + (fn [shape] (ctm/change-orientation-modifiers shape orientation)) - modif-tree - (-> (dwm/build-modif-tree ids objects get-modifier) - (gm/set-objects-modifiers objects))] + modif-tree + (-> (dwm/build-modif-tree ids objects get-modifier) + (gm/set-objects-modifiers objects))] - (assoc state :workspace-modifiers modif-tree))) + (assoc state :workspace-modifiers modif-tree)))) ptk/WatchEvent - (watch [_ _ _] - (rx/of (dwm/apply-modifiers))))) + (watch [_ state _] + (if (features/active-feature? state "render-wasm/v1") + (let [objects (dsh/lookup-page-objects state) + + get-modifier + (fn [shape] (ctm/change-orientation-modifiers shape orientation)) + + modif-tree + (-> (dwm/build-modif-tree ids objects get-modifier) + (gm/set-objects-modifiers objects))] + (rx/of (dwm/apply-wasm-modifiers modif-tree))) + + (rx/of (dwm/apply-modifiers)))))) ;; -- Rotate -------------------------------------------------------- +(defn rotation-modifiers + [angle shapes center] + (into {} + (comp + (remove #(get % :blocked false)) + (filter #(:rotation (get editable-attrs (:type %)))) + (map #(vector (:id %) {:modifiers (ctm/rotation-modifiers % center angle)}))) + shapes)) + (defn start-rotate "Enter mouse rotate mode, until mouse button is released." [shapes] @@ -439,39 +473,59 @@ (fn [[pos mod? shift?]] (calculate-angle pos mod? shift?))) (rx/share))] - (rx/concat - (rx/merge - (->> angle-stream - (rx/map - #(if (features/active-feature? state "render-wasm/v1") - (dwm/set-wasm-rotation-modifiers % shapes group-center) - (dwm/set-rotation-modifiers % shapes group-center))) - (rx/take-until stopper)) - (if (features/active-feature? state "render-wasm/v1") + + (if (features/active-feature? state "render-wasm/v1") + (rx/concat + (rx/merge + (->> angle-stream + (rx/map #(dwm/set-wasm-modifiers (rotation-modifiers % shapes group-center))) + (rx/take-until stopper)) (->> angle-stream (rx/take-until stopper) (rx/last) - (rx/map #(dwm/set-rotation-modifiers % shapes group-center))) - (rx/empty))) - (rx/of (dwm/apply-modifiers) - (finish-transform))))))) + (rx/map #(dwm/apply-wasm-modifiers (rotation-modifiers % shapes group-center))))) + + (rx/of (finish-transform))) + + (rx/concat + (rx/merge + (->> angle-stream + (rx/map + #(dwm/set-rotation-modifiers % shapes group-center)) + (rx/take-until stopper))) + (rx/of (dwm/apply-modifiers) + (finish-transform)))))))) (defn increase-rotation "Rotate shapes a fixed angle, from a keyboard action." ([ids rotation] (increase-rotation ids rotation nil)) - ([ids rotation params & {:as options}] + ([ids rotation {:keys [center delta?] :as params} & {:as options}] (ptk/reify ::increase-rotation ptk/WatchEvent (watch [_ state _] - (let [page-id (or (:page-id options) - (:current-page-id state)) - objects (dsh/lookup-page-objects state page-id) - shapes (->> ids (map #(get objects %))) - options (assoc options :page-id page-id)] - (rx/concat - (rx/of (dwm/set-delta-rotation-modifiers rotation shapes (assoc params :page-id page-id))) - (rx/of (dwm/apply-modifiers options)))))))) + (if (features/active-feature? state "render-wasm/v1") + (let [objects (dsh/lookup-page-objects state) + + get-modifier + (fn [shape] + (let [delta (if delta? rotation (- rotation (:rotation shape))) + center (or center (gsh/shape->center shape))] + (ctm/rotation-modifiers shape center delta))) + + modif-tree + (dwm/build-modif-tree ids objects get-modifier)] + + (rx/of (dwm/apply-wasm-modifiers modif-tree))) + + (let [page-id (or (:page-id options) + (:current-page-id state)) + objects (dsh/lookup-page-objects state page-id) + shapes (->> ids (map #(get objects %))) + options (assoc options :page-id page-id)] + (rx/concat + (rx/of (dwm/set-delta-rotation-modifiers rotation shapes (assoc params :page-id page-id))) + (rx/of (dwm/apply-modifiers options))))))))) ;; -- Move ---------------------------------------------------------- (declare start-move) @@ -648,48 +702,73 @@ snap-ignore-axis]))) (rx/share))] - (rx/merge - ;; Temporary modifiers stream - (->> modifiers-stream - (rx/map - (fn [[modifiers snap-ignore-axis]] - (if (features/active-feature? state "render-wasm/v1") - (dwm/set-wasm-modifiers modifiers false false {:snap-ignore-axis snap-ignore-axis}) - (dwm/set-modifiers modifiers false false {:snap-ignore-axis snap-ignore-axis}))))) + (if (features/active-feature? state "render-wasm/v1") + (rx/merge + (->> modifiers-stream + (rx/map + (fn [[modifiers snap-ignore-axis]] + (dwm/set-wasm-modifiers modifiers :snap-ignore-axis snap-ignore-axis)))) - (if (features/active-feature? state "render-wasm/v1") (->> modifiers-stream (rx/last) + (rx/map + (fn [[modifiers snap-ignore-axis]] + (dwm/apply-wasm-modifiers modifiers :snap-ignore-axis snap-ignore-axis)))) + + (->> move-stream + (rx/with-latest-from ms/mouse-position-alt) + (rx/filter (fn [[_ alt?]] alt?)) + (rx/take 1) + (rx/mapcat + (fn [[_ alt?]] + (if (and (not duplicate-move-started?) alt?) + (rx/of (start-move-duplicate from-position) + (dws/duplicate-selected false true)) + (rx/empty))))) + + ;; Last event will write the modifiers creating the changes + (->> move-stream + (rx/last) + (rx/mapcat + (fn [[_ target-frame drop-index drop-cell]] + (let [undo-id (js/Symbol)] + (rx/of (dwu/start-undo-transaction undo-id) + ;; (dwm/apply-modifiers {:undo-transation? false}) + (move-shapes-to-frame ids target-frame drop-index drop-cell) + (finish-transform) + (dwu/commit-undo-transaction undo-id))))))) + + (rx/merge + (->> modifiers-stream (rx/map (fn [[modifiers snap-ignore-axis]] (dwm/set-modifiers modifiers false false {:snap-ignore-axis snap-ignore-axis})))) - (rx/empty)) - (->> move-stream - (rx/with-latest-from ms/mouse-position-alt) - (rx/filter (fn [[_ alt?]] alt?)) - (rx/take 1) - (rx/mapcat - (fn [[_ alt?]] - (if (and (not duplicate-move-started?) alt?) - (rx/of (start-move-duplicate from-position) - (dws/duplicate-selected false true)) - (rx/empty))))) + (->> move-stream + (rx/with-latest-from ms/mouse-position-alt) + (rx/filter (fn [[_ alt?]] alt?)) + (rx/take 1) + (rx/mapcat + (fn [[_ alt?]] + (if (and (not duplicate-move-started?) alt?) + (rx/of (start-move-duplicate from-position) + (dws/duplicate-selected false true)) + (rx/empty))))) - (->> move-stream - (rx/map (comp set-ghost-displacement first))) + (->> move-stream + (rx/map (comp set-ghost-displacement first))) - ;; Last event will write the modifiers creating the changes - (->> move-stream - (rx/last) - (rx/mapcat - (fn [[_ target-frame drop-index drop-cell]] - (let [undo-id (js/Symbol)] - (rx/of (dwu/start-undo-transaction undo-id) - (dwm/apply-modifiers {:undo-transation? false}) - (move-shapes-to-frame ids target-frame drop-index drop-cell) - (finish-transform) - (dwu/commit-undo-transaction undo-id)))))))))))))) + ;; Last event will write the modifiers creating the changes + (->> move-stream + (rx/last) + (rx/mapcat + (fn [[_ target-frame drop-index drop-cell]] + (let [undo-id (js/Symbol)] + (rx/of (dwu/start-undo-transaction undo-id) + (dwm/apply-modifiers {:undo-transation? false}) + (move-shapes-to-frame ids target-frame drop-index drop-cell) + (finish-transform) + (dwu/commit-undo-transaction undo-id))))))))))))))) (def valid-directions #{:up :down :right :left}) @@ -828,17 +907,34 @@ scale (if shift? (gpt/point (or (:big nudge) 10)) (gpt/point (or (:small nudge) 1))) mov-vec (gpt/multiply (get-displacement direction) scale)] - (rx/concat - (rx/merge - (->> move-events - (rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0)) - (rx/map #(dwm/create-modif-tree selected (ctm/move-modifiers %))) - (rx/map #(dwm/set-modifiers % false true)) - (rx/take-until stopper)) - (rx/of (nudge-selected-shapes direction shift?))) + (if (features/active-feature? state "render-wasm/v1") + (let [modif-stream + (->> move-events + (rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0)) + (rx/map #(dwm/create-modif-tree selected (ctm/move-modifiers %))) + (rx/take-until stopper))] + (rx/concat + (rx/merge + (rx/of (nudge-selected-shapes direction shift?)) + (->> modif-stream + (rx/map #(dwm/set-wasm-modifiers % {:ignore-snap-pixel true}))) - (rx/of (dwm/apply-modifiers) - (finish-transform)))) + (->> modif-stream + (rx/last) + (rx/map #(dwm/apply-wasm-modifiers % {:ignore-snap-pixel true})))) + (rx/of (finish-transform)))) + + (rx/concat + (rx/merge + (->> move-events + (rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0)) + (rx/map #(dwm/create-modif-tree selected (ctm/move-modifiers %))) + (rx/map #(dwm/set-modifiers % false true)) + (rx/take-until stopper)) + (rx/of (nudge-selected-shapes direction shift?))) + + (rx/of (dwm/apply-modifiers) + (finish-transform))))) (rx/empty)))))) (defn move-selected @@ -896,11 +992,18 @@ delta (calculate-delta position bbox frame) modifiers (dwm/create-modif-tree [id] (ctm/move-modifiers delta))] - (rx/of (dwm/apply-modifiers {:modifiers modifiers - :page-id page-id - :ignore-constraints false - :ignore-touched (:ignore-touched options) - :ignore-snap-pixel true}))))))) + + (if (features/active-feature? state "render-wasm/v1") + (rx/of (dwm/apply-wasm-modifiers modifiers + {:ignore-constraints false + :ignore-touched (:ignore-touched options) + :ignore-snap-pixel true})) + + (rx/of (dwm/apply-modifiers {:modifiers modifiers + :page-id page-id + :ignore-constraints false + :ignore-touched (:ignore-touched options) + :ignore-snap-pixel true})))))))) (defn position-shapes [shapes] @@ -920,9 +1023,14 @@ opos (-> oshape :points first gpt/point)] (ctm/move-modifiers (gpt/subtract opos cpos)))))] - (rx/of (dwm/apply-modifiers {:modifiers modif-tree - :ignore-constraints false - :ignore-snap-pixel true})))))) + (if (features/active-feature? state "render-wasm/v1") + (rx/of (dwm/apply-wasm-modifiers modif-tree + {:ignore-constraints false + :ignore-snap-pixel true})) + + (rx/of (dwm/apply-modifiers {:modifiers modif-tree + :ignore-constraints false + :ignore-snap-pixel true}))))))) (defn- cleanup-invalid-moving-shapes [ids objects frame-id] (let [lookup (d/getf objects) @@ -1000,7 +1108,11 @@ selrect (gsh/shapes->rect shapes) center (grc/rect->center selrect) modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point -1.0 1.0) center))] - (rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true}))))))) + + + (if (features/active-feature? state "render-wasm/v1") + (rx/of (dwm/apply-wasm-modifiers modifiers {:ignore-snap-pixel true})) + (rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true})))))))) (defn flip-vertical-selected ([] @@ -1018,7 +1130,9 @@ selrect (gsh/shapes->rect shapes) center (grc/rect->center selrect) modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point 1.0 -1.0) center))] - (rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true}))))))) + (if (features/active-feature? state "render-wasm/v1") + (rx/of (dwm/apply-wasm-modifiers modifiers {:ignore-snap-pixel true})) + (rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true})))))))) (defn fit-layout-modifiers [objects frame] @@ -1051,4 +1165,7 @@ (some? new-modif) (assoc (:id frame) {:modifiers new-modif}))))) {}))] - (rx/of (dwm/apply-modifiers {:modifiers modifiers :undo-group undo-group})))))) + + (if (features/active-feature? state "render-wasm/v1") + (rx/of (dwm/apply-wasm-modifiers modifiers {:undo-group undo-group})) + (rx/of (dwm/apply-modifiers {:modifiers modifiers :undo-group undo-group}))))))) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index caff9874e..dc1c74626 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -767,28 +767,46 @@ (defn propagate-modifiers [entries] - (let [offset (mem/alloc-bytes-32 (modifier-get-entries-size entries)) - heapf32 (mem/get-heap-f32) - heapu32 (mem/get-heap-u32)] - - (loop [entries (seq entries) - current-offset offset] - (when-not (empty? entries) - (let [{:keys [id transform]} (first entries)] - (sr/heapu32-set-uuid id heapu32 current-offset) - (sr/heapf32-set-matrix transform heapf32 (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-TRANSFORM-OFFSET))) - (recur (rest entries) (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-SIZE)))))) - - (let [result-offset (h/call wasm/internal-module "_propagate_modifiers") + (when (d/not-empty? entries) + (let [offset (mem/alloc-bytes-32 (modifier-get-entries-size entries)) heapf32 (mem/get-heap-f32) - heapu32 (mem/get-heap-u32) - len (aget heapu32 (mem/ptr8->ptr32 result-offset)) - result - (->> (range 0 len) - (mapv #(dr/heap32->entry heapu32 heapf32 (mem/ptr8->ptr32 (+ result-offset 4 (* % MODIFIER-ENTRY-SIZE))))))] - (h/call wasm/internal-module "_free_bytes") + heapu32 (mem/get-heap-u32)] - result))) + (loop [entries (seq entries) + current-offset offset] + (when-not (empty? entries) + (let [{:keys [id transform]} (first entries)] + (sr/heapu32-set-uuid id heapu32 current-offset) + (sr/heapf32-set-matrix transform heapf32 (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-TRANSFORM-OFFSET))) + (recur (rest entries) (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-SIZE)))))) + + (let [result-offset (h/call wasm/internal-module "_propagate_modifiers") + heapf32 (mem/get-heap-f32) + heapu32 (mem/get-heap-u32) + len (aget heapu32 (mem/ptr8->ptr32 result-offset)) + result + (->> (range 0 len) + (mapv #(dr/heap32->entry heapu32 heapf32 (mem/ptr8->ptr32 (+ result-offset 4 (* % MODIFIER-ENTRY-SIZE))))))] + (h/call wasm/internal-module "_free_bytes") + + result)))) + +(defn propagate-apply + [entries] + (when (d/not-empty? entries) + (let [offset (mem/alloc-bytes-32 (modifier-get-entries-size entries)) + heapf32 (mem/get-heap-f32) + heapu32 (mem/get-heap-u32)] + + (loop [entries (seq entries) + current-offset offset] + (when-not (empty? entries) + (let [{:keys [id transform]} (first entries)] + (sr/heapu32-set-uuid id heapu32 current-offset) + (sr/heapf32-set-matrix transform heapf32 (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-TRANSFORM-OFFSET))) + (recur (rest entries) (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-SIZE)))))) + (h/call wasm/internal-module "_propagate_apply") + (request-render "set-modifiers")))) (defn set-canvas-background [background] diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs index ed640777d..d2adcbba0 100644 --- a/render-wasm/src/main.rs +++ b/render-wasm/src/main.rs @@ -395,6 +395,27 @@ pub extern "C" fn propagate_modifiers() -> *mut u8 { }) } +#[no_mangle] +pub extern "C" fn propagate_apply() { + let bytes = mem::bytes(); + + let entries: Vec<_> = bytes + .chunks(size_of::<::BytesType>()) + .map(|data| TransformEntry::from_bytes(data.try_into().unwrap())) + .collect(); + + with_state!(state, { + let result = shapes::propagate_modifiers(state, entries); + + for entry in result { + state.modifiers.insert(entry.id, entry.transform); + } + state.rebuild_modifier_tiles(); + }); + + mem::free_bytes(); +} + #[no_mangle] pub extern "C" fn set_structure_modifiers() { let bytes = mem::bytes(); diff --git a/render-wasm/src/shapes/modifiers/grid_layout.rs b/render-wasm/src/shapes/modifiers/grid_layout.rs index bbac9efa2..66933b836 100644 --- a/render-wasm/src/shapes/modifiers/grid_layout.rs +++ b/render-wasm/src/shapes/modifiers/grid_layout.rs @@ -334,9 +334,9 @@ fn set_fr_value( layout_size: f32, ) { let tot_gap: f32 = if column { - layout_data.column_gap * (tracks.len() - 1) as f32 + layout_data.column_gap * (tracks.len() as f32 - 1.0) } else { - layout_data.row_gap * (tracks.len() - 1) as f32 + layout_data.row_gap * (tracks.len() as f32 - 1.0) }; // Total size already used