Implement more flexible state management
This commit is contained in:
parent
81964a0d73
commit
850ef80139
3
deps.edn
3
deps.edn
@ -1,5 +1,6 @@
|
|||||||
{:deps {org.clojure/clojure {:mvn/version "1.9.0"}
|
{:deps {org.clojure/clojure {:mvn/version "1.9.0"}
|
||||||
org.clojure/clojurescript {:mvn/version "1.10.520"}}
|
org.clojure/clojurescript {:mvn/version "1.10.520"}
|
||||||
|
binaryage/oops {:mvn/version "0.7.0"}}
|
||||||
:paths ["src" "resources"]
|
:paths ["src" "resources"]
|
||||||
:aliases {:fig {:extra-deps
|
:aliases {:fig {:extra-deps
|
||||||
{com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}
|
{com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
(ns ^:figwheel-hooks three-playground.core
|
(ns ^:figwheel-hooks three-playground.core
|
||||||
(:require
|
(:require
|
||||||
[goog.dom :as gdom]
|
[goog.dom :as gdom]
|
||||||
|
[goog.object :as obj]
|
||||||
|
[oops.core :refer [oset!+]]
|
||||||
[three]))
|
[three]))
|
||||||
|
|
||||||
(defn get-app-element []
|
(defn get-app-element []
|
||||||
@ -24,31 +26,53 @@
|
|||||||
(.setSize renderer (.-innerWidth js/window) (.-innerHeight js/window))
|
(.setSize renderer (.-innerWidth js/window) (.-innerHeight js/window))
|
||||||
(.add scene cube)
|
(.add scene cube)
|
||||||
(atom {:running true
|
(atom {:running true
|
||||||
:cube {:rotation {:x 0 :y 0}}
|
|
||||||
:renderer renderer
|
:renderer renderer
|
||||||
:scene scene
|
:entity-state {:cube {:rotation {:x 0 :y 0}}
|
||||||
:camera {:position {:z 5}}
|
:camera {:position {:z 5}}}
|
||||||
:entities {:cube cube
|
:entities {:scene scene
|
||||||
|
:cube cube
|
||||||
:camera camera}})))
|
:camera camera}})))
|
||||||
|
|
||||||
(defonce app-state (init-state))
|
(defonce app-state (init-state))
|
||||||
|
|
||||||
(defn update-state [state]
|
(defn update-state [state]
|
||||||
(-> state
|
(-> state
|
||||||
(assoc-in [:cube :rotation :x]
|
(assoc-in [:entity-state :cube :rotation :x]
|
||||||
(+ (get-in state [:cube :rotation :x])
|
(+ (get-in state [:entity-state :cube :rotation :x])
|
||||||
0.01))
|
0.03))
|
||||||
(assoc-in [:cube :rotation :y]
|
(assoc-in [:entity-state :cube :rotation :y]
|
||||||
(+ (get-in state [:cube :rotation :y])
|
(+ (get-in state [:entity-state :cube :rotation :y])
|
||||||
0.01))))
|
0.01))))
|
||||||
|
|
||||||
|
(defn map->paths [m]
|
||||||
|
(if (map? m)
|
||||||
|
(vec
|
||||||
|
(mapcat (fn [[k v]]
|
||||||
|
(let [sub (map->paths v)
|
||||||
|
nested (map #(into [k] %) (filter (comp not empty?) sub))]
|
||||||
|
(if (seq nested)
|
||||||
|
nested
|
||||||
|
[[k]])))
|
||||||
|
m))
|
||||||
|
[]))
|
||||||
|
|
||||||
|
(defn update-entities! [state]
|
||||||
|
(doseq [[id entity] (:entities state)]
|
||||||
|
(let [target-state (get-in state [:entity-state id])]
|
||||||
|
(when target-state
|
||||||
|
(doseq [path (map->paths target-state)]
|
||||||
|
(let [str-path (map name path)
|
||||||
|
current (apply aget entity str-path)
|
||||||
|
new (get-in target-state path)]
|
||||||
|
(when-not (= current new)
|
||||||
|
(oset!+ entity str-path new))))))))
|
||||||
|
|
||||||
(defn render [state]
|
(defn render [state]
|
||||||
(let [{:keys [renderer scene]} state
|
(let [renderer (:renderer state)
|
||||||
|
scene (get-in state [:entities :scene])
|
||||||
camera (get-in state [:entities :camera])
|
camera (get-in state [:entities :camera])
|
||||||
cube (get-in state [:entities :cube])]
|
cube (get-in state [:entities :cube])]
|
||||||
(set! (-> camera (.-position) (.-z)) (get-in state [:camera :position :z]))
|
(update-entities! state)
|
||||||
(set! (-> cube (.-rotation) (.-x)) (get-in state [:cube :rotation :x]))
|
|
||||||
(set! (-> cube (.-rotation) (.-y)) (get-in state [:cube :rotation :y]))
|
|
||||||
(.render renderer scene camera)))
|
(.render renderer scene camera)))
|
||||||
|
|
||||||
(defn the-loop []
|
(defn the-loop []
|
||||||
|
@ -1 +1,8 @@
|
|||||||
(ns three-playground.core-test)
|
(ns three-playground.core-test
|
||||||
|
(:require [cljs.test :refer-macros [deftest testing is]]
|
||||||
|
[three-playground.core :as core]))
|
||||||
|
|
||||||
|
(deftest test-map->paths
|
||||||
|
(testing "Basic case"
|
||||||
|
(is (= (core/map->paths {:foo {:bar 1 :baz 2} :qux 3})
|
||||||
|
[[:foo :bar] [:foo :baz] [:qux]]))))
|
||||||
|
Loading…
Reference in New Issue
Block a user