From dbe6c1bc3ea5989291eed0458b5b17aa61c8ddf3 Mon Sep 17 00:00:00 2001 From: Paulo Feodrippe Date: Tue, 28 Jan 2025 23:47:52 -0500 Subject: [PATCH] [vc] Only lerp remaining (CPU got from ~84% to ~63%) --- CHANGELOG.md | 1 + src/vybe/c.clj | 24 ++++++++--- src/vybe/game/system.clj | 90 ++++++++++++---------------------------- 3 files changed, 47 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 709aae87..5b0c14d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Fix caching - Now it's working fine with the `vybe-games` builds - 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 - Add `vf/defsystem-c` ## v0.7.469 diff --git a/src/vybe/c.clj b/src/vybe/c.clj index 2b8c8583..914c52bc 100644 --- a/src/vybe/c.clj +++ b/src/vybe/c.clj @@ -1003,20 +1003,34 @@ signal(SIGSEGV, sighandler); :if (let [{:keys [then else] t :test} v + void-form? (or (:void (meta (:form v))) + (:void (meta v))) + void-str (if void-form? "NULL;" "") ;; For supporting the `:else` from a `cond` macro. t (if (= (:form t) :else) (analyze true) - t)] + t) + then (if void-form? + (vary-meta then merge {:void true}) + then) + else (if (and else void-form?) + (vary-meta else merge {:void true}) + else)] (if (:form else) - (format "( %s ? \n ({%s;}) : \n ({%s;}) )" + (format "( %s ? \n ({%s;%s}) : \n ({%s;%s}) )" (emit t) (emit then) - (emit else)) - (format "(typeof(({%s;})))( %s ? \n ({%s;}) : \n (typeof(({%s;}))){0} )" + void-str + (emit else) + void-str) + (format "(typeof(({%s;%s})))( %s ? \n ({%s;%s}) : \n (typeof(({%s;%s}))){0} )" (emit then) + void-str (emit t) (emit then) + void-str (emit then) + void-str #_(emit else)))) ;; Loops have special handling as we want to output a normal @@ -1449,7 +1463,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 51))) + (transpile (assoc opts ::version 52))) obj-name (str "vybe_" sym-name "_" (when (or (:no-cache sym-meta) diff --git a/src/vybe/game/system.clj b/src/vybe/game/system.clj index 19b33b62..d16390d4 100644 --- a/src/vybe/game/system.clj +++ b/src/vybe/game/system.clj @@ -264,26 +264,19 @@ c))) nil)) -(vf/defsystem-c ^:debug animation-node-player-2 w - [_ [:vg.anim/target-node '?node] +(vf/defsystem-c animation-node-player-2 w + [[_ node] [:vg.anim/target-node '?node] translation [:src '?node vt/Translation] scale [:src '?node vt/Scale] rotation [:src '?node vt/Rotation] - ;; TODO Maybe [:vg.anim/target-component [:vf/component'?c]] ? - _ [:vg.anim/target-component '?c] - {:keys [id]} [:src '?c vf/VybeComponentId] + [_ c] [:vg.anim/target-component '?c] {:keys [kind timeline_count values timeline]} vt/AnimationChannel player [:meta {:flags #{:up :cascade} :inout :mut} vt/AnimationPlayer] parent-e [:vf/entity {:flags #{:up}} :vg.anim/active] _ [:not {:flags #{:up}} :vg.anim/stop]] - #_(tap> id) - (let [#_ #_values (-> (if (= 0 0) - (vp/arr values timeline_count vt/Translation) - (vp/arr values timeline_count vt/Scale)) - (vp/as [:* :void])) - timeline* (vp/arr timeline timeline_count :float) + (let [timeline* (vp/arr timeline timeline_count :float) ;; TODO OPTM We could also leverage the previous index. idx* (vc/bs_lower_bound timeline* timeline_count (:current_time @player)) idx (cond @@ -294,74 +287,45 @@ -1 :else - (dec idx*)) - - #_ #_my-ref (-> (vf.c/ecs-ref-get-id (:w @node-ref) - (vp/& (:flecs_ref @node-ref)) - (:id (:flecs_ref @node-ref))) - #_(vp/p->map c))] - #_(tap> (long (vp/& (:flecs_ref @node-ref)))) - - #_(when tttt - (tap> @tttt)) + (dec idx*))] - ;; TODO We could use some `:void` metadata to indicate that - ;; a form does not return anything. (if (>= idx 0) (let [v (/ (- (:current_time @player) (nth timeline* idx)) (- (nth timeline* (inc idx)) (nth timeline* idx)))] + ;; You can use `^:void` to signal that an `if` or a `cond` don't + ;; care about the returned expression. ^:void (cond (= kind 0) - (do (merge @translation - (nth (vp/arr values timeline_count vt/Translation) idx)) - nil) - - (= kind 2) - (do (merge @rotation - (nth (vp/arr values timeline_count vt/Rotation) idx)) - nil) - - #_(= kind 1) - #_(nth (vp/arr values timeline_count vt/Scale) idx) - - #_(= kind 2) - #_(nth (vp/arr values timeline_count vt/Rotation) idx)) + (merge @translation + (nth (vp/arr values timeline_count vt/Translation) idx)) - #_(merge @node-ref (nth values idx) - #_(if t - (lerp-p (nth values idx) - (nth values (inc idx)) - t) - (nth values idx))))) + (= kind 1) + (merge @scale + (nth (vp/arr values timeline_count vt/Scale) idx)) - #_(when (< idx* 0) + (= kind 2) + (merge @rotation + (nth (vp/arr values timeline_count vt/Rotation) idx))) + + #_(merge @node-ref (if t + (lerp-p (nth values idx) + (nth values (inc idx)) + t) + (nth values idx))) + + ;; We modify the component from the ref and then we have to notify flecs + ;; that it was modified. + (vf.c/ecs-modified-id w node c)) + (do (conj parent-e :vg.anim/stop) ;; Just for triggering the `animation-loop` system. ;; TODO Use `(vf/ent w node)` instead of just `node` (conj node :vg.anim.entity/stop) - #_(conj (vf/ent w node) :vg.anim.entity/stop)) - - ;; TODO Using `comp-id` is not great as the ID may change - ;; after restart. - #_(when (= id (vc/comptime (vp/comp-id vt/Translation))) - (tap> (nth (vp/arr values timeline_count vt/Translation) idx))) - - ;; We modify the component from the ref and then we have to notify flecs - ;; that it was modified. - #_(merge node-ref (nth values idx)) - - ;; TODO lerp - #_(merge @node-ref (if t - (lerp-p (nth values idx) - (nth values (inc idx)) - t) - (nth values idx))) - - #_(vf/modified! w node c))) + #_(conj (vf/ent w node) :vg.anim.entity/stop))))) (vf/defsystem animation-loop w [[_ action] [:vg.anim/loop :*]