Apply modifiers changes into data

This commit is contained in:
alonso.torres 2025-04-29 14:18:38 +02:00
parent 7eab6a2f1d
commit 88e5209856
7 changed files with 361 additions and 163 deletions

View file

@ -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]

View file

@ -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

View file

@ -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})))))))

View file

@ -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]