mirror of
https://github.com/penpot/penpot.git
synced 2026-09-09 21:49:10 +00:00
🐛 Fix text editor crash when switching from svg to wasm renderer (#9926)
* 🐛 Fix crash when switching renderers with text editor open * ♻️ Use new initialized? helper in wasm api
This commit is contained in:
parent
b5108ca1ad
commit
a5c8bcaf9e
@ -35,6 +35,7 @@
|
|||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.fonts :as fonts]
|
[app.main.fonts :as fonts]
|
||||||
[app.main.router :as rt]
|
[app.main.router :as rt]
|
||||||
|
[app.main.store :as st]
|
||||||
[app.render-wasm.api :as wasm.api]
|
[app.render-wasm.api :as wasm.api]
|
||||||
[app.render-wasm.text-editor :as wasm.text-editor]
|
[app.render-wasm.text-editor :as wasm.text-editor]
|
||||||
[app.util.text-editor :as ted]
|
[app.util.text-editor :as ted]
|
||||||
@ -83,17 +84,23 @@
|
|||||||
[]
|
[]
|
||||||
(ptk/reify ::focus-editor
|
(ptk/reify ::focus-editor
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ state _]
|
(effect [_ _ _]
|
||||||
(let [editor (:workspace-editor state)
|
;; The focus is deferred, so we re-read the current editor at fire
|
||||||
element (when editor (.-element editor))]
|
;; time: the editor present now can be unmounted before the timeout
|
||||||
(cond
|
;; runs (e.g. switching renderer while editing a text), and focusing a
|
||||||
;; V1 (DraftEditor)
|
;; stale instance throws.
|
||||||
(.-focus editor)
|
(ts/schedule
|
||||||
(ts/schedule #(.focus ^js editor))
|
(fn []
|
||||||
|
(let [editor (:workspace-editor @st/state)
|
||||||
|
element (when editor (.-element editor))]
|
||||||
|
(cond
|
||||||
|
;; V1 (DraftEditor)
|
||||||
|
(and (some? editor) (.-focus editor))
|
||||||
|
(.focus ^js editor)
|
||||||
|
|
||||||
;; V2
|
;; V2
|
||||||
(and element (.-focus element))
|
(and element (.-focus element))
|
||||||
(ts/schedule #(.focus ^js element)))))))
|
(.focus ^js element))))))))
|
||||||
|
|
||||||
(defn gen-name
|
(defn gen-name
|
||||||
[editor]
|
[editor]
|
||||||
|
|||||||
@ -33,7 +33,10 @@
|
|||||||
(get-wasm-text-new-size shape (:content shape)))
|
(get-wasm-text-new-size shape (:content shape)))
|
||||||
|
|
||||||
([{:keys [id selrect grow-type] :as shape} content]
|
([{:keys [id selrect grow-type] :as shape} content]
|
||||||
(when id
|
;; Skip when the WASM context is not ready (e.g. switching renderer while a
|
||||||
|
;; text shape is being edited): there is no design state to query, and
|
||||||
|
;; returning nil makes callers skip the WASM resize/modifier path.
|
||||||
|
(when (and id (wasm.api/initialized?))
|
||||||
(wasm.api/use-shape id)
|
(wasm.api/use-shape id)
|
||||||
(wasm.api/set-shape-text-content id content)
|
(wasm.api/set-shape-text-content id content)
|
||||||
(wasm.api/set-shape-text-images id content)
|
(wasm.api/set-shape-text-images id content)
|
||||||
|
|||||||
@ -85,28 +85,34 @@
|
|||||||
parents
|
parents
|
||||||
(mf/deref parents-by-ids-ref)
|
(mf/deref parents-by-ids-ref)
|
||||||
|
|
||||||
|
;; Deref every editor-state ref unconditionally so the hook order
|
||||||
|
;; stays stable when feature flags change at runtime (e.g. switching
|
||||||
|
;; renderer while editing a text). The selection happens afterwards.
|
||||||
|
wasm-editor-styles-map (mf/deref refs/workspace-wasm-editor-styles)
|
||||||
|
v2-editor-state-map (mf/deref refs/workspace-v2-editor-state)
|
||||||
|
v1-editor-state-map (mf/deref refs/workspace-editor-state)
|
||||||
|
editor (mf/deref refs/workspace-editor)
|
||||||
|
|
||||||
|
text-editor-wasm? (features/active-feature? @st/state "text-editor-wasm/v1")
|
||||||
|
text-editor-v2? (features/active-feature? @st/state "text-editor/v2")
|
||||||
|
|
||||||
state-map
|
state-map
|
||||||
(cond
|
(cond
|
||||||
(features/active-feature? @st/state "text-editor-wasm/v1")
|
text-editor-wasm? wasm-editor-styles-map
|
||||||
(mf/deref refs/workspace-wasm-editor-styles)
|
text-editor-v2? v2-editor-state-map
|
||||||
|
:else v1-editor-state-map)
|
||||||
(features/active-feature? @st/state "text-editor/v2")
|
|
||||||
(mf/deref refs/workspace-v2-editor-state)
|
|
||||||
|
|
||||||
:else
|
|
||||||
(mf/deref refs/workspace-editor-state))
|
|
||||||
|
|
||||||
editor-styles
|
editor-styles
|
||||||
(when (features/active-feature? @st/state "text-editor-wasm/v1")
|
(when text-editor-wasm?
|
||||||
(get state-map id))
|
(get state-map id))
|
||||||
|
|
||||||
editor-state
|
editor-state
|
||||||
(when (not (features/active-feature? @st/state "text-editor/v2"))
|
(when (not text-editor-v2?)
|
||||||
(get state-map id))
|
(get state-map id))
|
||||||
|
|
||||||
editor-instance
|
editor-instance
|
||||||
(when (features/active-feature? @st/state "text-editor/v2")
|
(when text-editor-v2?
|
||||||
(mf/deref refs/workspace-editor))
|
editor)
|
||||||
|
|
||||||
fill-values
|
fill-values
|
||||||
(dwt/current-text-values
|
(dwt/current-text-values
|
||||||
|
|||||||
@ -424,9 +424,9 @@
|
|||||||
(js/clearTimeout timeout-id))
|
(js/clearTimeout timeout-id))
|
||||||
(wasm.api/clear-canvas)))))
|
(wasm.api/clear-canvas)))))
|
||||||
|
|
||||||
(mf/with-effect [show-text-editor? workspace-editor-state edition]
|
(mf/with-effect [show-text-editor? workspace-editor-state edition @canvas-init? @initialized?]
|
||||||
(let [active-editor-state (get workspace-editor-state edition)]
|
(let [active-editor-state (get workspace-editor-state edition)]
|
||||||
(when (and show-text-editor? active-editor-state)
|
(when (and show-text-editor? active-editor-state @canvas-init? @initialized?)
|
||||||
(let [content (-> active-editor-state
|
(let [content (-> active-editor-state
|
||||||
(ted/get-editor-current-content)
|
(ted/get-editor-current-content)
|
||||||
(ted/export-content))]
|
(ted/export-content))]
|
||||||
|
|||||||
@ -85,6 +85,15 @@
|
|||||||
|
|
||||||
(def ^:private snapshot-capture-debounce-ms 250)
|
(def ^:private snapshot-capture-debounce-ms 250)
|
||||||
|
|
||||||
|
|
||||||
|
(defn initialized?
|
||||||
|
"True when the WASM render context is ready to receive design-state
|
||||||
|
operations. Use it to skip WASM work during transient states (e.g. while
|
||||||
|
switching renderer with a text shape being edited)."
|
||||||
|
[]
|
||||||
|
(and wasm/context-initialized? (not @wasm/context-lost?)))
|
||||||
|
|
||||||
|
|
||||||
(defn set-transition-image-from-background!
|
(defn set-transition-image-from-background!
|
||||||
"Sets `transition-image-url*` to a data URL representing a solid background color."
|
"Sets `transition-image-url*` to a data URL representing a solid background color."
|
||||||
[background]
|
[background]
|
||||||
@ -161,8 +170,7 @@
|
|||||||
(defonce ^:private schedule-canvas-snapshot-capture!
|
(defonce ^:private schedule-canvas-snapshot-capture!
|
||||||
(fns/debounce
|
(fns/debounce
|
||||||
(fn []
|
(fn []
|
||||||
(when (and wasm/context-initialized?
|
(when (and (initialized?)
|
||||||
(not @wasm/context-lost?)
|
|
||||||
(some? wasm/canvas))
|
(some? wasm/canvas))
|
||||||
(-> (webgl/capture-canvas-snapshot-url)
|
(-> (webgl/capture-canvas-snapshot-url)
|
||||||
(p/catch (fn [_] nil)))))
|
(p/catch (fn [_] nil)))))
|
||||||
@ -323,14 +331,13 @@
|
|||||||
[]
|
[]
|
||||||
;; check if the context has not been lost already or we will get warnings about
|
;; check if the context has not been lost already or we will get warnings about
|
||||||
;; removing objects from a non-current context
|
;; removing objects from a non-current context
|
||||||
(when (and wasm/context-initialized?
|
(when (initialized?)
|
||||||
(not @wasm/context-lost?))
|
|
||||||
(h/call wasm/internal-module "_free_gpu_resources")))
|
(h/call wasm/internal-module "_free_gpu_resources")))
|
||||||
|
|
||||||
;; This should never be called from the outside.
|
;; This should never be called from the outside.
|
||||||
(defn- render
|
(defn- render
|
||||||
[timestamp]
|
[timestamp]
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
(when (initialized?)
|
||||||
(h/call wasm/internal-module "_render" timestamp)
|
(h/call wasm/internal-module "_render" timestamp)
|
||||||
|
|
||||||
;; Update text editor blink (so cursor toggles) using the same timestamp
|
;; Update text editor blink (so cursor toggles) using the same timestamp
|
||||||
@ -361,13 +368,13 @@
|
|||||||
|
|
||||||
(defn render-sync
|
(defn render-sync
|
||||||
[]
|
[]
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
(when (initialized?)
|
||||||
(h/call wasm/internal-module "_render_sync")
|
(h/call wasm/internal-module "_render_sync")
|
||||||
(set! wasm/internal-frame-id nil)))
|
(set! wasm/internal-frame-id nil)))
|
||||||
|
|
||||||
(defn render-sync-shape
|
(defn render-sync-shape
|
||||||
[id]
|
[id]
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
(when (initialized?)
|
||||||
(let [buffer (uuid/get-u32 id)]
|
(let [buffer (uuid/get-u32 id)]
|
||||||
(h/call wasm/internal-module "_render_sync_shape"
|
(h/call wasm/internal-module "_render_sync_shape"
|
||||||
(aget buffer 0)
|
(aget buffer 0)
|
||||||
@ -380,7 +387,7 @@
|
|||||||
"Render a lightweight preview without tile caching.
|
"Render a lightweight preview without tile caching.
|
||||||
Used during progressive loading for fast feedback."
|
Used during progressive loading for fast feedback."
|
||||||
[]
|
[]
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
(when (initialized?)
|
||||||
(h/call wasm/internal-module "_render_preview")))
|
(h/call wasm/internal-module "_render_preview")))
|
||||||
|
|
||||||
|
|
||||||
@ -394,7 +401,7 @@
|
|||||||
|
|
||||||
(defn request-render
|
(defn request-render
|
||||||
[_requester]
|
[_requester]
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?) (not @wasm/disable-request-render?))
|
(when (and (initialized?) (not @wasm/disable-request-render?))
|
||||||
(if @shapes-loading?
|
(if @shapes-loading?
|
||||||
(register-deferred-render!)
|
(register-deferred-render!)
|
||||||
(when-not @pending-render
|
(when-not @pending-render
|
||||||
@ -431,7 +438,7 @@
|
|||||||
|
|
||||||
(defn use-shape
|
(defn use-shape
|
||||||
[id]
|
[id]
|
||||||
(when wasm/context-initialized?
|
(when (initialized?)
|
||||||
(let [buffer (uuid/get-u32 id)]
|
(let [buffer (uuid/get-u32 id)]
|
||||||
(h/call wasm/internal-module "_use_shape"
|
(h/call wasm/internal-module "_use_shape"
|
||||||
(aget buffer 0)
|
(aget buffer 0)
|
||||||
@ -441,7 +448,7 @@
|
|||||||
|
|
||||||
(defn has-shape
|
(defn has-shape
|
||||||
[id]
|
[id]
|
||||||
(when wasm/context-initialized?
|
(when (initialized?)
|
||||||
(let [buffer (uuid/get-u32 id)
|
(let [buffer (uuid/get-u32 id)
|
||||||
|
|
||||||
result
|
result
|
||||||
@ -459,17 +466,20 @@
|
|||||||
;; Cache content for text editor sync
|
;; Cache content for text editor sync
|
||||||
(text-editor/cache-shape-text-content! shape-id content)
|
(text-editor/cache-shape-text-content! shape-id content)
|
||||||
|
|
||||||
(h/call wasm/internal-module "_clear_shape_text")
|
;; The WASM design state may not be ready (e.g. while switching renderer
|
||||||
|
;; with a text shape being edited). Skip the WASM layout calls in that case.
|
||||||
|
(when (initialized?)
|
||||||
|
(h/call wasm/internal-module "_clear_shape_text")
|
||||||
|
|
||||||
(set-shape-vertical-align (get content :vertical-align))
|
(set-shape-vertical-align (get content :vertical-align))
|
||||||
|
|
||||||
(let [fonts (f/get-content-fonts content)
|
(let [fonts (f/get-content-fonts content)
|
||||||
fallback-fonts (fonts-from-text-content content true)
|
fallback-fonts (fonts-from-text-content content true)
|
||||||
all-fonts (concat fonts fallback-fonts)
|
all-fonts (concat fonts fallback-fonts)
|
||||||
result (f/store-fonts all-fonts)]
|
result (f/store-fonts all-fonts)]
|
||||||
(f/load-fallback-fonts-for-editor! fallback-fonts)
|
(f/load-fallback-fonts-for-editor! fallback-fonts)
|
||||||
(h/call wasm/internal-module "_update_shape_text_layout")
|
(h/call wasm/internal-module "_update_shape_text_layout")
|
||||||
result))
|
result)))
|
||||||
|
|
||||||
(defn apply-styles-to-selection
|
(defn apply-styles-to-selection
|
||||||
"Apply style attrs to the currently selected text spans.
|
"Apply style attrs to the currently selected text spans.
|
||||||
@ -1130,21 +1140,23 @@
|
|||||||
(use-shape id)
|
(use-shape id)
|
||||||
(get-text-dimensions))
|
(get-text-dimensions))
|
||||||
([]
|
([]
|
||||||
(let [offset (-> (h/call wasm/internal-module "_get_text_dimensions")
|
(if-not (initialized?)
|
||||||
(mem/->offset-32))
|
{:x 0 :y 0 :width 0 :height 0 :max-width 0}
|
||||||
heapf32 (mem/get-heap-f32)
|
(let [offset (-> (h/call wasm/internal-module "_get_text_dimensions")
|
||||||
width (aget heapf32 (+ offset 0))
|
(mem/->offset-32))
|
||||||
height (aget heapf32 (+ offset 1))
|
heapf32 (mem/get-heap-f32)
|
||||||
max-width (aget heapf32 (+ offset 2))
|
width (aget heapf32 (+ offset 0))
|
||||||
|
height (aget heapf32 (+ offset 1))
|
||||||
|
max-width (aget heapf32 (+ offset 2))
|
||||||
|
|
||||||
x (aget heapf32 (+ offset 3))
|
x (aget heapf32 (+ offset 3))
|
||||||
y (aget heapf32 (+ offset 4))]
|
y (aget heapf32 (+ offset 4))]
|
||||||
(mem/free)
|
(mem/free)
|
||||||
{:x x :y y :width width :height height :max-width max-width})))
|
{:x x :y y :width width :height height :max-width max-width}))))
|
||||||
|
|
||||||
(defn intersect-position-in-shape
|
(defn intersect-position-in-shape
|
||||||
[id position]
|
[id position]
|
||||||
(if (and wasm/context-initialized? (not @wasm/context-lost?))
|
(if (initialized?)
|
||||||
(let [buffer (uuid/get-u32 id)
|
(let [buffer (uuid/get-u32 id)
|
||||||
result
|
result
|
||||||
(h/call wasm/internal-module "_intersect_position_in_shape"
|
(h/call wasm/internal-module "_intersect_position_in_shape"
|
||||||
@ -1175,7 +1187,7 @@
|
|||||||
(letfn [(do-render []
|
(letfn [(do-render []
|
||||||
;; Check if context is still initialized before executing
|
;; Check if context is still initialized before executing
|
||||||
;; to prevent errors when navigating quickly
|
;; to prevent errors when navigating quickly
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
(when (initialized?)
|
||||||
(view-interaction-end!)
|
(view-interaction-end!)
|
||||||
;; Use async _render: visible tiles render synchronously
|
;; Use async _render: visible tiles render synchronously
|
||||||
;; (no yield), interest-area tiles render progressively
|
;; (no yield), interest-area tiles render progressively
|
||||||
@ -1202,8 +1214,7 @@
|
|||||||
(defn sync-workspace-local-viewport!
|
(defn sync-workspace-local-viewport!
|
||||||
"Pushes `[:workspace-local :zoom]` and `:vbox` into WASM."
|
"Pushes `[:workspace-local :zoom]` and `:vbox` into WASM."
|
||||||
[state]
|
[state]
|
||||||
(when (and wasm/context-initialized?
|
(when (initialized?)
|
||||||
(not @wasm/context-lost?))
|
|
||||||
(let [zoom (get-in state [:workspace-local :zoom])
|
(let [zoom (get-in state [:workspace-local :zoom])
|
||||||
vbox (get-in state [:workspace-local :vbox])]
|
vbox (get-in state [:workspace-local :vbox])]
|
||||||
(when (and zoom vbox)
|
(when (and zoom vbox)
|
||||||
@ -1661,7 +1672,8 @@
|
|||||||
|
|
||||||
(defn clean-modifiers
|
(defn clean-modifiers
|
||||||
[]
|
[]
|
||||||
(h/call wasm/internal-module "_clean_modifiers"))
|
(when (initialized?)
|
||||||
|
(h/call wasm/internal-module "_clean_modifiers")))
|
||||||
|
|
||||||
(defn set-modifiers-start
|
(defn set-modifiers-start
|
||||||
"Enter interactive transform mode (drag / resize / rotate). Enables
|
"Enter interactive transform mode (drag / resize / rotate). Enables
|
||||||
@ -1669,7 +1681,7 @@
|
|||||||
backdrop so tiles do not appear sequentially or flicker while the
|
backdrop so tiles do not appear sequentially or flicker while the
|
||||||
gesture is in progress."
|
gesture is in progress."
|
||||||
[]
|
[]
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
(when (initialized?)
|
||||||
(h/call wasm/internal-module "_set_modifiers_start")))
|
(h/call wasm/internal-module "_set_modifiers_start")))
|
||||||
|
|
||||||
(defn set-modifiers-end
|
(defn set-modifiers-end
|
||||||
@ -1677,7 +1689,7 @@
|
|||||||
scheduled under it; the caller is expected to trigger a full-quality
|
scheduled under it; the caller is expected to trigger a full-quality
|
||||||
render (via `request-render`) once the gesture is committed."
|
render (via `request-render`) once the gesture is committed."
|
||||||
[]
|
[]
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
(when (initialized?)
|
||||||
(h/call wasm/internal-module "_set_modifiers_end")))
|
(h/call wasm/internal-module "_set_modifiers_end")))
|
||||||
|
|
||||||
(defn set-modifiers
|
(defn set-modifiers
|
||||||
@ -2164,7 +2176,7 @@
|
|||||||
|
|
||||||
(defn calculate-position-data
|
(defn calculate-position-data
|
||||||
[shape]
|
[shape]
|
||||||
(when wasm/context-initialized?
|
(when (initialized?)
|
||||||
(use-shape (:id shape))
|
(use-shape (:id shape))
|
||||||
(let [heapf32 (mem/get-heap-f32)
|
(let [heapf32 (mem/get-heap-f32)
|
||||||
heapu32 (mem/get-heap-u32)
|
heapu32 (mem/get-heap-u32)
|
||||||
|
|||||||
@ -85,6 +85,31 @@
|
|||||||
(track! :set-shape-grow-type)
|
(track! :set-shape-grow-type)
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
|
(defn- mock-initialized?
|
||||||
|
[]
|
||||||
|
(track! :initialized?)
|
||||||
|
true)
|
||||||
|
|
||||||
|
;; The functions below used to short-circuit in tests because they guarded on
|
||||||
|
;; `wasm/context-initialized?` (always false without a real WASM binary). They
|
||||||
|
;; now guard on `initialized?`, which the mock forces to `true`, so they would
|
||||||
|
;; reach the real WASM heap. Stub them as no-ops to preserve that behavior.
|
||||||
|
|
||||||
|
(defn- mock-use-shape
|
||||||
|
[_id]
|
||||||
|
(track! :use-shape)
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(defn- mock-calculate-position-data
|
||||||
|
[_shape]
|
||||||
|
(track! :calculate-position-data)
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(defn- mock-request-render
|
||||||
|
[_requester]
|
||||||
|
(track! :request-render)
|
||||||
|
nil)
|
||||||
|
|
||||||
(defn- mock-set-shape-text-content
|
(defn- mock-set-shape-text-content
|
||||||
[_shape-id _content]
|
[_shape-id _content]
|
||||||
(track! :set-shape-text-content)
|
(track! :set-shape-text-content)
|
||||||
@ -143,7 +168,11 @@
|
|||||||
(reset-call-counts!)
|
(reset-call-counts!)
|
||||||
;; Save originals
|
;; Save originals
|
||||||
(reset! originals
|
(reset! originals
|
||||||
{:clean-modifiers wasm.api/clean-modifiers
|
{:initialized? wasm.api/initialized?
|
||||||
|
:use-shape wasm.api/use-shape
|
||||||
|
:calculate-position-data wasm.api/calculate-position-data
|
||||||
|
:request-render wasm.api/request-render
|
||||||
|
:clean-modifiers wasm.api/clean-modifiers
|
||||||
:set-structure-modifiers wasm.api/set-structure-modifiers
|
:set-structure-modifiers wasm.api/set-structure-modifiers
|
||||||
:propagate-modifiers wasm.api/propagate-modifiers
|
:propagate-modifiers wasm.api/propagate-modifiers
|
||||||
:set-modifiers wasm.api/set-modifiers
|
:set-modifiers wasm.api/set-modifiers
|
||||||
@ -155,6 +184,10 @@
|
|||||||
:make-font-data wasm.fonts/make-font-data
|
:make-font-data wasm.fonts/make-font-data
|
||||||
:get-content-fonts wasm.fonts/get-content-fonts})
|
:get-content-fonts wasm.fonts/get-content-fonts})
|
||||||
;; Install mocks
|
;; Install mocks
|
||||||
|
(set! wasm.api/initialized? mock-initialized?)
|
||||||
|
(set! wasm.api/use-shape mock-use-shape)
|
||||||
|
(set! wasm.api/calculate-position-data mock-calculate-position-data)
|
||||||
|
(set! wasm.api/request-render mock-request-render)
|
||||||
(set! wasm.api/clean-modifiers mock-clean-modifiers)
|
(set! wasm.api/clean-modifiers mock-clean-modifiers)
|
||||||
(set! wasm.api/set-structure-modifiers mock-set-structure-modifiers)
|
(set! wasm.api/set-structure-modifiers mock-set-structure-modifiers)
|
||||||
(set! wasm.api/propagate-modifiers mock-propagate-modifiers)
|
(set! wasm.api/propagate-modifiers mock-propagate-modifiers)
|
||||||
@ -171,6 +204,10 @@
|
|||||||
"Restore the original WASM functions saved by `setup-wasm-mocks!`."
|
"Restore the original WASM functions saved by `setup-wasm-mocks!`."
|
||||||
[]
|
[]
|
||||||
(let [orig @originals]
|
(let [orig @originals]
|
||||||
|
(set! wasm.api/initialized? (:initialized? orig))
|
||||||
|
(set! wasm.api/use-shape (:use-shape orig))
|
||||||
|
(set! wasm.api/calculate-position-data (:calculate-position-data orig))
|
||||||
|
(set! wasm.api/request-render (:request-render orig))
|
||||||
(set! wasm.api/clean-modifiers (:clean-modifiers orig))
|
(set! wasm.api/clean-modifiers (:clean-modifiers orig))
|
||||||
(set! wasm.api/set-structure-modifiers (:set-structure-modifiers orig))
|
(set! wasm.api/set-structure-modifiers (:set-structure-modifiers orig))
|
||||||
(set! wasm.api/propagate-modifiers (:propagate-modifiers orig))
|
(set! wasm.api/propagate-modifiers (:propagate-modifiers orig))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user