mirror of
https://github.com/penpot/penpot.git
synced 2025-08-03 22:58:29 +02:00
🎉 Add specific namespace for data macros
And additionally add optimized macros for get-in, select-keys and str.
This commit is contained in:
parent
165c551e39
commit
84a36624a6
9 changed files with 277 additions and 184 deletions
|
@ -417,45 +417,6 @@
|
|||
(not (mth/finite? v))
|
||||
(mth/nan? v)) default v)))
|
||||
|
||||
|
||||
(defmacro export
|
||||
"A helper macro that allows reexport a var in a current namespace."
|
||||
[v]
|
||||
(if (boolean (:ns &env))
|
||||
|
||||
;; Code for ClojureScript
|
||||
(let [mdata (aapi/resolve &env v)
|
||||
arglists (second (get-in mdata [:meta :arglists]))
|
||||
sym (symbol (core/name v))
|
||||
andsym (symbol "&")
|
||||
procarg #(if (= % andsym) % (gensym "param"))]
|
||||
(if (pos? (count arglists))
|
||||
`(def
|
||||
~(with-meta sym (:meta mdata))
|
||||
(fn ~@(for [args arglists]
|
||||
(let [args (map procarg args)]
|
||||
(if (some #(= andsym %) args)
|
||||
(let [[sargs dargs] (split-with #(not= andsym %) args)]
|
||||
`([~@sargs ~@dargs] (apply ~v ~@sargs ~@(rest dargs))))
|
||||
`([~@args] (~v ~@args)))))))
|
||||
`(def ~(with-meta sym (:meta mdata)) ~v)))
|
||||
|
||||
;; Code for Clojure
|
||||
(let [vr (resolve v)
|
||||
m (meta vr)
|
||||
n (:name m)
|
||||
n (with-meta n
|
||||
(cond-> {}
|
||||
(:dynamic m) (assoc :dynamic true)
|
||||
(:protocol m) (assoc :protocol (:protocol m))))]
|
||||
`(let [m# (meta ~vr)]
|
||||
(def ~n (deref ~vr))
|
||||
(alter-meta! (var ~n) merge (dissoc m# :name))
|
||||
;; (when (:macro m#)
|
||||
;; (.setMacro (var ~n)))
|
||||
~vr))))
|
||||
|
||||
|
||||
(defn any-key? [element & rest]
|
||||
(some #(contains? element %) rest))
|
||||
|
||||
|
@ -692,4 +653,3 @@
|
|||
(recur acc (step k))
|
||||
acc)))
|
||||
acc))))))
|
||||
|
||||
|
|
130
common/src/app/common/data/macros.cljc
Normal file
130
common/src/app/common/data/macros.cljc
Normal file
|
@ -0,0 +1,130 @@
|
|||
;; 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) UXBOX Labs SL
|
||||
|
||||
(ns app.common.data.macros
|
||||
"Data retrieval & manipulation specific macros."
|
||||
(:refer-clojure :exclude [get-in select-keys str])
|
||||
#?(:cljs (:require-macros [app.common.data.macros]))
|
||||
(:require
|
||||
#?(:clj [clojure.core :as c]
|
||||
:cljs [cljs.core :as c])
|
||||
[cljs.analyzer.api :as aapi]))
|
||||
|
||||
(defmacro select-keys
|
||||
"A macro version of `select-keys`. Usefull when keys vector is known
|
||||
at compile time (aprox 600% performance boost).
|
||||
|
||||
It is not 100% equivalent, this macro does not removes not existing
|
||||
keys in contrast to clojure.core/select-keys"
|
||||
[target keys]
|
||||
(assert (vector? keys) "keys expected to be a vector")
|
||||
`{ ~@(mapcat (fn [key] [key (list `c/get target key)]) keys) ~@[] })
|
||||
|
||||
(defmacro get-in
|
||||
"A macro version of `get-in`. Usefull when the keys vector is known at
|
||||
compile time (20-40% performance improvement)."
|
||||
([target keys]
|
||||
(assert (vector? keys) "keys expected to be a vector")
|
||||
`(-> ~target ~@(map (fn [key] (list `c/get key)) keys)))
|
||||
([target keys default]
|
||||
(assert (vector? keys) "keys expected to be a vector")
|
||||
`(let [v# (-> ~target ~@(map (fn [key] (list `c/get key)) keys))]
|
||||
(if (some? v#) v# ~default))))
|
||||
|
||||
|
||||
;; => benchmarking: clojure.core/str
|
||||
;; --> WARM: 100000
|
||||
;; --> BENCH: 500000
|
||||
;; --> TOTAL: 197.82ms
|
||||
;; --> MEAN: 395.64ns
|
||||
;; => benchmarking: app.commons.data.macros/str
|
||||
;; --> WARM: 100000
|
||||
;; --> BENCH: 500000
|
||||
;; --> TOTAL: 20.31ms
|
||||
;; --> MEAN: 40.63ns
|
||||
|
||||
(defmacro str
|
||||
"CLJS only macro variant of `str` function that performs string concat much faster."
|
||||
([a]
|
||||
(if (:ns &env)
|
||||
(list 'js* "\"\"+~{}" a)
|
||||
(list `c/str a)))
|
||||
([a b]
|
||||
(if (:ns &env)
|
||||
(list 'js* "\"\"+~{}+~{}" a b)
|
||||
(list `c/str a b)))
|
||||
([a b c]
|
||||
(if (:ns &env)
|
||||
(list 'js* "\"\"+~{}+~{}+~{}" a b c)
|
||||
(list `c/str a b c)))
|
||||
([a b c d]
|
||||
(if (:ns &env)
|
||||
(list 'js* "\"\"+~{}+~{}+~{}+~{}" a b c d)
|
||||
(list `c/str a b c d)))
|
||||
([a b c d e]
|
||||
(if (:ns &env)
|
||||
(list 'js* "\"\"+~{}+~{}+~{}+~{}+~{}" a b c d e)
|
||||
(list `c/str a b c d e)))
|
||||
([a b c d e f]
|
||||
(if (:ns &env)
|
||||
(list 'js* "\"\"+~{}+~{}+~{}+~{}+~{}+~{}" a b c d e f)
|
||||
(list `c/str a b c d e f)))
|
||||
([a b c d e f g]
|
||||
(if (:ns &env)
|
||||
(list 'js* "\"\"+~{}+~{}+~{}+~{}+~{}+~{}+~{}" a b c d e f g)
|
||||
(list `c/str a b c d e f g)))
|
||||
([a b c d e f g h]
|
||||
(if (:ns &env)
|
||||
(list 'js* "\"\"+~{}+~{}+~{}+~{}+~{}+~{}+~{}+~{}" a b c d e f g h)
|
||||
(list `c/str a b c d e f g h)))
|
||||
([a b c d e f g h & rest]
|
||||
(let [all (into [a b c d e f g h] rest)]
|
||||
(if (:ns &env)
|
||||
(let [xf (map (fn [items] `(str ~@items)))
|
||||
pall (partition-all 8 all)]
|
||||
(if (<= (count all) 64)
|
||||
`(str ~@(sequence xf pall))
|
||||
`(c/str ~@(sequence xf pall))))
|
||||
`(c/str ~@all)))))
|
||||
|
||||
(defmacro export
|
||||
"A helper macro that allows reexport a var in a current namespace."
|
||||
[v]
|
||||
(if (boolean (:ns &env))
|
||||
|
||||
;; Code for ClojureScript
|
||||
(let [mdata (aapi/resolve &env v)
|
||||
arglists (second (get-in mdata [:meta :arglists]))
|
||||
sym (symbol (c/name v))
|
||||
andsym (symbol "&")
|
||||
procarg #(if (= % andsym) % (gensym "param"))]
|
||||
(if (pos? (count arglists))
|
||||
`(def
|
||||
~(with-meta sym (:meta mdata))
|
||||
(fn ~@(for [args arglists]
|
||||
(let [args (map procarg args)]
|
||||
(if (some #(= andsym %) args)
|
||||
(let [[sargs dargs] (split-with #(not= andsym %) args)]
|
||||
`([~@sargs ~@dargs] (apply ~v ~@sargs ~@(rest dargs))))
|
||||
`([~@args] (~v ~@args)))))))
|
||||
`(def ~(with-meta sym (:meta mdata)) ~v)))
|
||||
|
||||
;; Code for Clojure
|
||||
(let [vr (resolve v)
|
||||
m (meta vr)
|
||||
n (:name m)
|
||||
n (with-meta n
|
||||
(cond-> {}
|
||||
(:dynamic m) (assoc :dynamic true)
|
||||
(:protocol m) (assoc :protocol (:protocol m))))]
|
||||
`(let [m# (meta ~vr)]
|
||||
(def ~n (deref ~vr))
|
||||
(alter-meta! (var ~n) merge (dissoc m# :name))
|
||||
;; (when (:macro m#)
|
||||
;; (.setMacro (var ~n)))
|
||||
~vr))))
|
||||
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.common.geom.shapes
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.bool :as gsb]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
|
@ -137,55 +138,55 @@
|
|||
|
||||
|
||||
;; EXPORTS
|
||||
(d/export gco/center-shape)
|
||||
(d/export gco/center-selrect)
|
||||
(d/export gco/center-rect)
|
||||
(d/export gco/center-points)
|
||||
(d/export gco/make-centered-rect)
|
||||
(d/export gco/transform-points)
|
||||
(dm/export gco/center-shape)
|
||||
(dm/export gco/center-selrect)
|
||||
(dm/export gco/center-rect)
|
||||
(dm/export gco/center-points)
|
||||
(dm/export gco/make-centered-rect)
|
||||
(dm/export gco/transform-points)
|
||||
|
||||
(d/export gpr/rect->selrect)
|
||||
(d/export gpr/rect->points)
|
||||
(d/export gpr/points->selrect)
|
||||
(d/export gpr/points->rect)
|
||||
(d/export gpr/center->rect)
|
||||
(d/export gpr/join-rects)
|
||||
(d/export gpr/contains-selrect?)
|
||||
(dm/export gpr/rect->selrect)
|
||||
(dm/export gpr/rect->points)
|
||||
(dm/export gpr/points->selrect)
|
||||
(dm/export gpr/points->rect)
|
||||
(dm/export gpr/center->rect)
|
||||
(dm/export gpr/join-rects)
|
||||
(dm/export gpr/contains-selrect?)
|
||||
|
||||
(d/export gtr/move)
|
||||
(d/export gtr/absolute-move)
|
||||
(d/export gtr/transform-matrix)
|
||||
(d/export gtr/inverse-transform-matrix)
|
||||
(d/export gtr/transform-point-center)
|
||||
(d/export gtr/transform-rect)
|
||||
(d/export gtr/calculate-adjust-matrix)
|
||||
(d/export gtr/update-group-selrect)
|
||||
(d/export gtr/resize-modifiers)
|
||||
(d/export gtr/rotation-modifiers)
|
||||
(d/export gtr/merge-modifiers)
|
||||
(d/export gtr/transform-shape)
|
||||
(d/export gtr/transform-selrect)
|
||||
(d/export gtr/modifiers->transform)
|
||||
(d/export gtr/empty-modifiers?)
|
||||
(dm/export gtr/move)
|
||||
(dm/export gtr/absolute-move)
|
||||
(dm/export gtr/transform-matrix)
|
||||
(dm/export gtr/inverse-transform-matrix)
|
||||
(dm/export gtr/transform-point-center)
|
||||
(dm/export gtr/transform-rect)
|
||||
(dm/export gtr/calculate-adjust-matrix)
|
||||
(dm/export gtr/update-group-selrect)
|
||||
(dm/export gtr/resize-modifiers)
|
||||
(dm/export gtr/rotation-modifiers)
|
||||
(dm/export gtr/merge-modifiers)
|
||||
(dm/export gtr/transform-shape)
|
||||
(dm/export gtr/transform-selrect)
|
||||
(dm/export gtr/modifiers->transform)
|
||||
(dm/export gtr/empty-modifiers?)
|
||||
|
||||
;; Constratins
|
||||
(d/export gct/calc-child-modifiers)
|
||||
(dm/export gct/calc-child-modifiers)
|
||||
|
||||
;; PATHS
|
||||
(d/export gsp/content->selrect)
|
||||
(d/export gsp/transform-content)
|
||||
(d/export gsp/open-path?)
|
||||
(dm/export gsp/content->selrect)
|
||||
(dm/export gsp/transform-content)
|
||||
(dm/export gsp/open-path?)
|
||||
|
||||
;; Intersection
|
||||
(d/export gin/overlaps?)
|
||||
(d/export gin/has-point?)
|
||||
(d/export gin/has-point-rect?)
|
||||
(d/export gin/rect-contains-shape?)
|
||||
(dm/export gin/overlaps?)
|
||||
(dm/export gin/has-point?)
|
||||
(dm/export gin/has-point-rect?)
|
||||
(dm/export gin/rect-contains-shape?)
|
||||
|
||||
;; Bool
|
||||
(d/export gsb/update-bool-selrect)
|
||||
(d/export gsb/calc-bool-content)
|
||||
(dm/export gsb/update-bool-selrect)
|
||||
(dm/export gsb/calc-bool-content)
|
||||
|
||||
;; Constraints
|
||||
(d/export gct/default-constraints-h)
|
||||
(d/export gct/default-constraints-v)
|
||||
(dm/export gct/default-constraints-h)
|
||||
(dm/export gct/default-constraints-v)
|
||||
|
|
|
@ -7,32 +7,32 @@
|
|||
(ns app.common.pages
|
||||
"A common (clj/cljs) functions and specs for pages."
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.pages.changes :as changes]
|
||||
[app.common.pages.common :as common]
|
||||
[app.common.pages.indices :as indices]
|
||||
[app.common.pages.init :as init]))
|
||||
|
||||
;; Common
|
||||
(d/export common/root)
|
||||
(d/export common/file-version)
|
||||
(d/export common/default-color)
|
||||
(d/export common/component-sync-attrs)
|
||||
(dm/export common/root)
|
||||
(dm/export common/file-version)
|
||||
(dm/export common/default-color)
|
||||
(dm/export common/component-sync-attrs)
|
||||
|
||||
;; Indices
|
||||
(d/export indices/calculate-z-index)
|
||||
(d/export indices/update-z-index)
|
||||
(d/export indices/generate-child-all-parents-index)
|
||||
(d/export indices/generate-child-parent-index)
|
||||
(d/export indices/create-clip-index)
|
||||
(dm/export indices/calculate-z-index)
|
||||
(dm/export indices/update-z-index)
|
||||
(dm/export indices/generate-child-all-parents-index)
|
||||
(dm/export indices/generate-child-parent-index)
|
||||
(dm/export indices/create-clip-index)
|
||||
|
||||
;; Process changes
|
||||
(d/export changes/process-changes)
|
||||
(dm/export changes/process-changes)
|
||||
|
||||
;; Initialization
|
||||
(d/export init/default-frame-attrs)
|
||||
(d/export init/default-shape-attrs)
|
||||
(d/export init/make-file-data)
|
||||
(d/export init/make-minimal-shape)
|
||||
(d/export init/make-minimal-group)
|
||||
(d/export init/empty-file-data)
|
||||
(dm/export init/default-frame-attrs)
|
||||
(dm/export init/default-shape-attrs)
|
||||
(dm/export init/make-file-data)
|
||||
(dm/export init/make-minimal-shape)
|
||||
(dm/export init/make-minimal-group)
|
||||
(dm/export init/empty-file-data)
|
||||
|
|
|
@ -7,15 +7,15 @@
|
|||
(ns app.common.uri
|
||||
(:refer-clojure :exclude [uri?])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[lambdaisland.uri :as u]
|
||||
[lambdaisland.uri.normalize :as un]))
|
||||
|
||||
(d/export u/uri)
|
||||
(d/export u/join)
|
||||
(d/export u/query-encode)
|
||||
(d/export un/percent-encode)
|
||||
(d/export u/uri?)
|
||||
(dm/export u/uri)
|
||||
(dm/export u/join)
|
||||
(dm/export u/query-encode)
|
||||
(dm/export un/percent-encode)
|
||||
(dm/export u/uri?)
|
||||
|
||||
(defn query-string->map
|
||||
[s]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(ns app.common.uuid
|
||||
(:refer-clojure :exclude [next uuid zero?])
|
||||
(:require
|
||||
#?(:clj [app.common.data :as d])
|
||||
#?(:clj [app.common.data.macros :as dm])
|
||||
#?(:clj [clj-uuid :as impl])
|
||||
#?(:clj [clojure.core :as c])
|
||||
#?(:cljs [app.common.uuid-impl :as impl])
|
||||
|
@ -47,4 +47,4 @@
|
|||
([b a] #?(:clj (UUID. b a) :cljs (c/uuid (impl/custom b a)))))
|
||||
|
||||
#?(:clj
|
||||
(d/export impl/get-word-high))
|
||||
(dm/export impl/get-word-high))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue