Improve wasm api call method usability

This commit is contained in:
Andrey Antukh 2024-11-19 13:28:30 +01:00
parent db2eb2c420
commit 884414d5cf
2 changed files with 87 additions and 67 deletions

View file

@ -7,11 +7,11 @@
(ns app.render-wasm (ns app.render-wasm
"A WASM based render API" "A WASM based render API"
(:require (:require
[app.common.colors :as cc]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.types.shape.impl :as ctsi] [app.common.types.shape.impl :as ctsi]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cf] [app.config :as cf]
[app.render-wasm.helpers :as h]
[promesa.core :as p])) [promesa.core :as p]))
(defn initialize (defn initialize
@ -20,95 +20,100 @@
(defonce internal-module #js {}) (defonce internal-module #js {})
;; TODO: remove the `take` once we have the dynamic data structure in Rust
(def xform
(comp
(take 2048)))
(defn create-shape (defn create-shape
[id] [id]
(let [buffer (uuid/get-u32 id) (let [buffer (uuid/get-u32 id)]
create-shape (unchecked-get internal-module "_create_shape")] (h/call internal-module "_create_shape"
(^function create-shape (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3)))) (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))))
(defn use-shape (defn use-shape
[id] [id]
(let [buffer (uuid/get-u32 id) (let [buffer (uuid/get-u32 id)]
use-shape (unchecked-get internal-module "_use_shape")] (h/call internal-module "_use_shape"
(^function use-shape (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3)))) (aget buffer 0)
(aget buffer 1)
(aget buffer 2)
(aget buffer 3))))
(defn set-shape-selrect (defn set-shape-selrect
[selrect] [selrect]
(let [x1 (dm/get-prop selrect :x1) (h/call internal-module "_set_shape_selrect"
y1 (dm/get-prop selrect :y1) (dm/get-prop selrect :x1)
x2 (dm/get-prop selrect :x2) (dm/get-prop selrect :y1)
y2 (dm/get-prop selrect :y2) (dm/get-prop selrect :x2)
set-shape-selrect (unchecked-get internal-module "_set_shape_selrect")] (dm/get-prop selrect :y2)))
(^function set-shape-selrect x1 y1 x2 y2)))
(defn set-shape-transform (defn set-shape-transform
[transform] [transform]
(let [a (dm/get-prop transform :a) (h/call internal-module "_set_shape_transform"
b (dm/get-prop transform :b) (dm/get-prop transform :a)
c (dm/get-prop transform :c) (dm/get-prop transform :b)
d (dm/get-prop transform :d) (dm/get-prop transform :c)
e (dm/get-prop transform :e) (dm/get-prop transform :d)
f (dm/get-prop transform :f) (dm/get-prop transform :e)
set-shape-transform (unchecked-get internal-module "_set_shape_transform")] (dm/get-prop transform :f)))
(^function set-shape-transform a b c d e f)))
(defn set-shape-rotation (defn set-shape-rotation
[rotation] [rotation]
(let [set-shape-rotation (unchecked-get internal-module "_set_shape_rotation")] (h/call internal-module "_set_shape_rotation" rotation))
(^function set-shape-rotation rotation)))
(defn set-shape-children (defn set-shape-children
[shape_ids] [shape-ids]
(let [clear-shape-children (unchecked-get internal-module "_clear_shape_children") (h/call internal-module "_clear_shape_children")
add-shape-child (unchecked-get internal-module "_add_shape_child")] (run! (fn [id]
(^function clear-shape-children) (let [buffer (uuid/get-u32 id)]
(doseq [id shape_ids] (h/call internal-module "_add_shape_child"
(let [buffer (uuid/get-u32 id)] (aget buffer 0)
(^function add-shape-child (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3)))))) (aget buffer 1)
(aget buffer 2)
(aget buffer 3))))
shape-ids))
(defn set-shape-fills (defn set-shape-fills
[fills] [fills]
(let [clear-shape-fills (unchecked-get internal-module "_clear_shape_fills") (h/call internal-module "_clear_shape_fills")
add-shape-fill (unchecked-get internal-module "_add_shape_solid_fill")] (run! (fn [fill]
(^function clear-shape-fills) (let [opacity (:fill-opacity fill)
(doseq [fill (filter #(contains? % :fill-color) fills)] color (:fill-color fill)]
(let [a (:fill-opacity fill) (when ^boolean color
[r g b] (cc/hex->rgb (:fill-color fill))] (let [rgb (js/parseInt (subs color 1) 16)
(^function add-shape-fill r g b a))))) r (bit-shift-right rgb 16)
g (bit-and (bit-shift-right rgb 8) 255)
b (bit-and rgb 255)]
(h/call internal-module "_add_shape_solid_fill" r g b opacity)))))
fills))
(defn- translate-blend-mode
[blend-mode]
(case blend-mode
:normal 3
:darken 16
:multiply 24
:color-burn 19
:lighten 17
:screen 14
:color-dodge 18
:overlay 15
:soft-light 21
:hard-light 20
:difference 22
:exclusion 23
:hue 25
:saturation 26
:color 27
:luminosity 28
3))
(defn set-shape-blend-mode (defn set-shape-blend-mode
[blend-mode] [blend-mode]
;; These values correspond to skia::BlendMode representation ;; These values correspond to skia::BlendMode representation
;; https://rust-skia.github.io/doc/skia_safe/enum.BlendMode.html ;; https://rust-skia.github.io/doc/skia_safe/enum.BlendMode.html
(let [encoded-blend (case blend-mode (h/call internal-module "_set_shape_blend_mode" (translate-blend-mode blend-mode)))
:normal 3
:darken 16
:multiply 24
:color-burn 19
:lighten 17
:screen 14
:color-dodge 18
:overlay 15
:soft-light 21
:hard-light 20
:difference 22
:exclusion 23
:hue 25
:saturation 26
:color 27
:luminosity 28
3)
set-shape-blend-mode (unchecked-get internal-module "_set_shape_blend_mode")]
(^function set-shape-blend-mode encoded-blend)))
(defn set-objects (defn set-objects
[objects] [objects]
(let [shapes (into [] xform (vals objects)) (let [shapes (into [] (vals objects))
total-shapes (count shapes)] total-shapes (count shapes)]
(loop [index 0] (loop [index 0]
(when (< index total-shapes) (when (< index total-shapes)
@ -133,10 +138,9 @@
[zoom vbox] [zoom vbox]
(js/requestAnimationFrame (js/requestAnimationFrame
(fn [] (fn []
(let [pan-x (- (dm/get-prop vbox :x)) (let [pan-x (- (dm/get-prop vbox :x))
pan-y (- (dm/get-prop vbox :y)) pan-y (- (dm/get-prop vbox :y))]
draw-all-shapes (unchecked-get internal-module "_draw_all_shapes")] (h/call internal-module "_draw_all_shapes" zoom pan-x pan-y)))))
(^function draw-all-shapes zoom pan-x pan-y)))))
(defn cancel-draw (defn cancel-draw
[frame-id] [frame-id]

View file

@ -0,0 +1,16 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.render-wasm.helpers
#?(:cljs (:require-macros [app.render-wasm.helpers])))
(defmacro call
"A helper for easy call wasm defined function in a module."
[module name & params]
(let [fn-sym (with-meta (gensym "fn-") {:tag 'function})]
`(let [~fn-sym (cljs.core/unchecked-get ~module ~name)]
(~fn-sym ~@params))))