Skip to content

Commit

Permalink
[vc] Start to move update-physics
Browse files Browse the repository at this point in the history
  • Loading branch information
pfeodrippe committed Jan 29, 2025
1 parent bfbc2fd commit 04f77b6
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 126 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches:
- main
- develop
# - develop
paths-ignore:
- '**/README.md'
- '**/CHANGELOG.md'
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Create `vc/eval*` to debug standalone forms
- Accept meta `^:void` in `if`/`cond` expressions to signal to the C compiler that we don't care about the return
- Move animation-node-player to VybeC
- CPU went from 84% to 63%
- Add `vf/defsystem-c`

## v0.7.469
Expand Down
168 changes: 91 additions & 77 deletions src/vybe/c.clj
Original file line number Diff line number Diff line change
Expand Up @@ -1466,7 +1466,7 @@ long long int: \"long long int\", unsigned long long int: \"unsigned long long i
([code-form {:keys [sym-meta sym sym-name] :as opts}]
(let [{:keys [c-code ::c-data form-hash final-form init-struct-val]}
(-> code-form
(transpile (assoc opts ::version 53)))
(transpile (assoc opts ::version 54)))

obj-name (str "vybe_" sym-name "_"
(when (or (:no-cache sym-meta)
Expand Down Expand Up @@ -1733,6 +1733,17 @@ long long int: \"long long int\", unsigned long long int: \"unsigned long long i

(defonce -*vybec-fn-watchers (atom {}))

(defn- adapt-form
[form]
(walk/postwalk (fn walk-fn [v]
(if-let [resolved (and (symbol? v)
(some-> (resolve v) deref))]
(if (= (type resolved) ::vp/Opaque)
(symbol (vp/comp-name (vp/component resolved)))
v)
v))
form))

(defmacro defn*
"Transpiles Clojure code into a C function.
Expand All @@ -1743,82 +1754,85 @@ long long int: \"long long int\", unsigned long long int: \"unsigned long long i
(simple v))"
{:clj-kondo/lint-as 'schema.core/defn}
[n _ ret-schema args & fn-tail]
`(let [args-desc-1# (quote ~(->> args
(partition-all 3 3)
(mapv (fn [[sym _ schema]]
[sym schema]))))
args-desc-2# ~(->> args
(partition-all 3 3)
(mapv (fn [[sym _ schema]]
[`(quote ~sym) schema])))]
(def ~n
(let [v# (-> (c-compile
{:sym (quote ~n)
:sym-name ~(->name (symbol (str *ns*) (str n)))
:sym-meta ~(meta n)
:ret-schema ~ret-schema
:args (quote ~args)}

(defn ~n
~(with-meta (adapt-fn-args args)
(adapt-schema ret-schema))
~@fn-tail))

(with-meta {::c-function ~(->name (symbol (str *ns*) (str n)))})
(merge {:fn-desc (into [:fn ~ret-schema] args-desc-2#)}))

v# (-> (vp/map->VybeCFn (merge v# (-c-fn-builder v#)))
;; TODO We could put this in the returned map instead of in the metadata.
(with-meta {::c-function ~(->name (symbol (str *ns*) (str n)))}))

initializer# (when (:init-struct-val v#)
#(when-let [init-struct-val# %]
((-> ((:symbol-finder v#)
(quote ~(->name (symbol (str *ns*) (str n "__init")))))
(vp/c-fn [:fn :void [:some_struct [:* :void]]]))
(vp/mem init-struct-val#))))]

;; Initialize globals, if any.
(when initializer#
(initializer# (:init-struct-val v#)))

;; Return.
(merge v# {:initializer initializer#})))

;; Set some metadata for documentation.
(alter-meta! (var ~n) merge
{:arglists (list args-desc-1#)
:doc (cond-> (format "Returns %s" (if (vp/component? ~ret-schema)
(vp/comp-name ~ret-schema)
(quote ~ret-schema)))
(:doc (meta (var ~n)))
(str "\n\n" (:doc (meta (var ~n)))))})

;; Remove any existing watchers.
(->> (get @-*vybec-fn-watchers (var ~n))
(mapv (fn [[v# identifier#]]
(remove-watch v# identifier#))))
;; Watch global fn pointers vars (if any) so we can have hot reloading.
(let [global-fn-pointers# (:global-fn-pointers (::c-data ~n))
watchers# (->> global-fn-pointers#
(mapv (fn [{v# :var}]
(let [identifier# (symbol (str "_vybe_c_watcher_" (symbol (var ~n)) "_" (symbol v#)))]
(add-watch v# identifier#
(fn [& _args#]
(try
#_(tap> {:vybec-debug-msg "Updating VybeC fn"
:vybec-fn (var ~n)
:trigger v#})
(set-globals! ~n {(symbol v#) @v#})
;; Trigger var mutation so other vars can know
;; about it.
(alter-var-root (var ~n) (constantly @(var ~n)))
(catch Exception ex#
(println ex#)))))
[v# identifier#]))))]
(swap! -*vybec-fn-watchers assoc (var ~n) watchers#))

(var ~n)))
(let [ret-schema (adapt-form ret-schema)
args (adapt-form args)
fn-tail (adapt-form fn-tail)]
`(let [args-desc-1# (quote ~(->> args
(partition-all 3 3)
(mapv (fn [[sym _ schema]]
[sym schema]))))
args-desc-2# ~(->> args
(partition-all 3 3)
(mapv (fn [[sym _ schema]]
[`(quote ~sym) schema])))]
(def ~n
(let [v# (-> (c-compile
{:sym (quote ~n)
:sym-name ~(->name (symbol (str *ns*) (str n)))
:sym-meta ~(meta n)
:ret-schema ~ret-schema
:args (quote ~args)}

(defn ~n
~(with-meta (adapt-fn-args args)
(adapt-schema ret-schema))
~@fn-tail))

(with-meta {::c-function ~(->name (symbol (str *ns*) (str n)))})
(merge {:fn-desc (into [:fn ~ret-schema] args-desc-2#)}))

v# (-> (vp/map->VybeCFn (merge v# (-c-fn-builder v#)))
;; TODO We could put this in the returned map instead of in the metadata.
(with-meta {::c-function ~(->name (symbol (str *ns*) (str n)))}))

initializer# (when (:init-struct-val v#)
#(when-let [init-struct-val# %]
((-> ((:symbol-finder v#)
(quote ~(->name (symbol (str *ns*) (str n "__init")))))
(vp/c-fn [:fn :void [:some_struct [:* :void]]]))
(vp/mem init-struct-val#))))]

;; Initialize globals, if any.
(when initializer#
(initializer# (:init-struct-val v#)))

;; Return.
(merge v# {:initializer initializer#})))

;; Set some metadata for documentation.
(alter-meta! (var ~n) merge
{:arglists (list args-desc-1#)
:doc (cond-> (format "Returns %s" (if (vp/component? ~ret-schema)
(vp/comp-name ~ret-schema)
(quote ~ret-schema)))
(:doc (meta (var ~n)))
(str "\n\n" (:doc (meta (var ~n)))))})

;; Remove any existing watchers.
(->> (get @-*vybec-fn-watchers (var ~n))
(mapv (fn [[v# identifier#]]
(remove-watch v# identifier#))))
;; Watch global fn pointers vars (if any) so we can have hot reloading.
(let [global-fn-pointers# (:global-fn-pointers (::c-data ~n))
watchers# (->> global-fn-pointers#
(mapv (fn [{v# :var}]
(let [identifier# (symbol (str "_vybe_c_watcher_" (symbol (var ~n)) "_" (symbol v#)))]
(add-watch v# identifier#
(fn [& _args#]
(try
#_(tap> {:vybec-debug-msg "Updating VybeC fn"
:vybec-fn (var ~n)
:trigger v#})
(set-globals! ~n {(symbol v#) @v#})
;; Trigger var mutation so other vars can know
;; about it.
(alter-var-root (var ~n) (constantly @(var ~n)))
(catch Exception ex#
(println ex#)))))
[v# identifier#]))))]
(swap! -*vybec-fn-watchers assoc (var ~n) watchers#))

(var ~n))))
#_ (vybe.c/defn* ^:debug eita :- :int
[a :- :int]
(tap> (+ a 4550)))
Expand Down
67 changes: 40 additions & 27 deletions src/vybe/flecs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2195,7 +2195,7 @@
bindings-only-valid (->> bindings
(remove (comp keyword? first))
vec)
i 'vybe_c_i
i 'vybe_c_idx
it 'vybe_c_it

f (fn [idx [k v]]
Expand Down Expand Up @@ -2234,7 +2234,11 @@

:else
v)
flags @*flags]
flags @*flags
meta-default {:idx idx
:sym k
:flags flags
:rvalue v}]
;; We return a vector of vectors because of the
;; destructuring (note that we use `(apply concat)` below.
(cond
Expand All @@ -2243,13 +2247,21 @@
[(with-meta [(symbol (str k "--arr"))
;; TODO support `:maybe`
`(vf.c/ecs-field-src ~it ~idx)]
{:idx idx
:type nil
:sym k
:flags flags})]
meta-default)]

(and (vector? v)
#_(some #{:* :_} v))
;; Get root entity.
(= v :vf/entity)
[(with-meta [(symbol (str k "--arr"))
`(vp/as (:entities @~it) [:* :long])]
meta-default )]

;; Get iter pointer.
(= v :vf/iter)
[(with-meta [(symbol (str k "--arr"))
it]
meta-default)]

(vector? v)
(if (vector? k)
(->> k
;; Index for the vector destructuring.
Expand All @@ -2269,22 +2281,20 @@
(remove nil?)
vec)
[(with-meta [(symbol (str k "--arr"))
;; TODO support `:maybe`
`(vf.c/ecs-field-id ~it ~idx)]
{:idx idx
:type nil
:sym k
:flags flags})])
(if (contains? flags :maybe)
`(when (vf.c/ecs-field-is-set ~it ~idx)
(vf.c/ecs-field-id ~it ~idx))
`(vf.c/ecs-field-id ~it ~idx))]
meta-default)])

;; Tag branch.
(keyword? v)
[(with-meta [(symbol (str k "--arr"))
;; TODO support `:maybe`
`(vf.c/ecs-field-id ~it ~idx)]
{:idx idx
:type nil
:sym k
:flags flags})]
(if (contains? flags :maybe)
`(when (vf.c/ecs-field-is-set ~it ~idx)
(vf.c/ecs-field-id ~it ~idx))
`(vf.c/ecs-field-id ~it ~idx))]
meta-default)]

;; Component branch.
:else
Expand All @@ -2297,11 +2307,10 @@
(-field ~it ~v ~idx)
(vp/as vp/null [:* ~v]))
`(-field ~it ~v ~idx))]
{:idx idx
:type v
:sym k-sym
:binding-form k
:flags flags})])))))
(merge meta-default
{:type v
:sym k-sym
:binding-form k}))])))))

bindings-processed (->> bindings-only-valid
(map-indexed f)
Expand All @@ -2326,7 +2335,7 @@
(doseq [~i (range (:count @~it))]
(let ~ (->> bindings-processed
(mapv (fn [k-and-v]
(let [{:keys [sym flags binding-form type idx]} (meta k-and-v)
(let [{:keys [sym flags binding-form type idx rvalue]} (meta k-and-v)
[k _v] k-and-v
;; If we are up, it means we are self.
;; TODO Use `is-self` so we can cover up
Expand Down Expand Up @@ -2362,7 +2371,11 @@
[sym form]))
;; Not a component branch.
;; TODO support `:maybe`
[sym k]))))
[sym
(case rvalue
:vf/entity
`(nth ~k ~i)
k)]))))
(apply concat)
vec)
~@body))))
Expand Down
Loading

0 comments on commit 04f77b6

Please sign in to comment.