Skip to content

Instantly share code, notes, and snippets.

@Orbots
Last active June 13, 2017 08:26
Show Gist options
  • Save Orbots/6888137 to your computer and use it in GitHub Desktop.
Save Orbots/6888137 to your computer and use it in GitHub Desktop.
component entity system in clojurescript
;; component access, query and data
(ns forces.framework.component
)
;; support stuff
(defn dissoc-in
"Dissociates an entry from a nested associative structure returning a new
nested structure. keys is a sequence of keys. Any empty maps that result
will not be present in the new structure."
[m [k & ks :as keys]]
(if ks
(if-let [nextmap (get m k)]
(let [newmap (dissoc-in nextmap ks)]
(if (seq newmap)
(assoc m k newmap)
(dissoc m k)))
m)
(dissoc m k)))
;;
;; API
(def !components (atom {} ))
(defn clearComponents []
(reset! !components {}))
;; want a sorted map, should specify a debug mode to check access is to a sorted map
(defn registerComponentType [componentID]
(swap! !components assoc componentID (sorted-map)))
(defn addComponent [entity component value]
(swap! !components assoc-in [component entity] value))
(defn deleteComponent [entity component]
(swap! !components dissoc-in [component entity] ))
(defn getComponent [entity component]
(get-in @!components [component entity]))
(defn getComponentList [component]
(get @!components component))
(defn getComponentTypes [ cvec ]
(let [allc @!components]
(map #(get allc %) cvec )))
;; takes a vector of componentTypes to be iterated simultaneously. with each entityID that matches all call the systemFn
;;!me this is a function that should probably be implemented in JS. Profile it, I imagine it's a bit slow in cljs
(defn processSystem [ systemFn componentTypes ]
(letfn [(findGE [cl] (key (first (reduce (fn [a b] (if (> (key (first a)) (key (first b))) a b)) {0 0} cl))))
(allAtEntity? [cl ie ] (empty? ( filter #(not (= ie (key (first %)))) cl)))
(anyEmpty? [cl] (not (empty? (filter empty? cl))))
(moveToEntity [cl ie]
(map (fn [onel]
(loop [shl onel]
(cond
(empty? shl)
{}
(>= (key (first shl)) ie)
shl
:else
(recur (rest shl)))))
cl ))]
(loop [cl (getComponentTypes componentTypes)
accr []]
(cond
(anyEmpty? cl)
(do
;; (js/alert "end")
accr )
:else
(let [ie (findGE cl)]
;; (js/alert ie)
(cond
(allAtEntity? cl ie)
(let [ firsts (map first cl)
r (systemFn firsts)]
;;(js/alert (str "r" firsts "=" r ))
(recur (map rest cl) (conj accr r )))
:else
(do
;; (js/alert (str "recuring" ie ))
(recur (moveToEntity cl ie) accr ))
))))))
;; debug stuff
;; sorted? not implemnted in cljs?
(defn validateAll []
(reduce (fn [a b] (and (sorted? a) (sorted? b) )) @!components ))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment