Initial commit with working gamestate + indexing.
This commit is contained in:
commit
a32058babd
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/pom.xml
|
||||||
|
*jar
|
||||||
|
/lib
|
||||||
|
/classes
|
||||||
|
/native
|
||||||
|
/.lein-failures
|
||||||
|
/checkouts
|
||||||
|
/.lein-deps-sum
|
13
README
Normal file
13
README
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# hottub
|
||||||
|
|
||||||
|
FIXME: write description
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
FIXME: write
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Copyright (C) 2013 FIXME
|
||||||
|
|
||||||
|
Distributed under the Eclipse Public License, the same as Clojure.
|
3
project.clj
Normal file
3
project.clj
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
(defproject hottub "1.0.0-SNAPSHOT"
|
||||||
|
:description "Hot Tub Time Machine Game Engine"
|
||||||
|
:dependencies [[org.clojure/clojure "1.5.0"]])
|
74
src/hottub/gs.clj
Normal file
74
src/hottub/gs.clj
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
(ns hottub.gs)
|
||||||
|
|
||||||
|
(defmulti update-index (fn [indextype indexold id entityold entitynew] indextype))
|
||||||
|
(defmulti query-index (fn [indextype index query] indextype))
|
||||||
|
|
||||||
|
|
||||||
|
(def gs-empty {:entities {} :indices {} :id-lim 0})
|
||||||
|
|
||||||
|
(def ^:dynamic *gamestate* (ref gs-empty))
|
||||||
|
(defn gen-id []
|
||||||
|
(let [id (:id-lim @*gamestate*)]
|
||||||
|
(ref-set *gamestate* (assoc @*gamestate* :id-lim (+ id 1)))
|
||||||
|
id))
|
||||||
|
|
||||||
|
(defmacro with-gs [gs & body]
|
||||||
|
`(binding [*gamestate* (ref ~gs)] (dosync ~@body)))
|
||||||
|
|
||||||
|
(defn get-gs [] @*gamestate*)
|
||||||
|
|
||||||
|
(defn entity [id] (get-in @*gamestate* [:entities id]))
|
||||||
|
|
||||||
|
(defn- update-indices [id entityold entitynew]
|
||||||
|
(ref-set *gamestate*
|
||||||
|
(loop [gs @*gamestate* indextypes (keys (:indices gs))]
|
||||||
|
(if (seq indextypes)
|
||||||
|
(let [indextype (first indextypes)
|
||||||
|
indexold (get-in gs [:indices indextype])
|
||||||
|
indexnew (update-index indextype indexold id entityold entitynew)
|
||||||
|
gsnew (assoc-in gs [:indices indextype] indexnew)]
|
||||||
|
(recur gsnew (next indextypes)))
|
||||||
|
gs))))
|
||||||
|
|
||||||
|
(defn add-index [indextype]
|
||||||
|
(ref-set *gamestate*
|
||||||
|
(loop [index {} ids (keys (:entities @*gamestate*))]
|
||||||
|
(if (seq ids)
|
||||||
|
(let [id (first ids)
|
||||||
|
indexnew (update-index indextype index id nil (entity id))]
|
||||||
|
(recur indexnew (next ids)))
|
||||||
|
(assoc-in @*gamestate* [:indices indextype] index)))))
|
||||||
|
|
||||||
|
(defn remove-id-from-index [index id key]
|
||||||
|
(if-let [idsbefore (get index key)]
|
||||||
|
(let [idsafter (disj idsbefore id)]
|
||||||
|
(if (empty? idsafter)
|
||||||
|
(dissoc index key)
|
||||||
|
(assoc index key idsafter)))
|
||||||
|
index))
|
||||||
|
|
||||||
|
(defn add-id-to-index [index id key]
|
||||||
|
(if-let [idsbefore (get index key)]
|
||||||
|
(assoc index key (conj idsbefore id))
|
||||||
|
(if key
|
||||||
|
(assoc index key #{id})
|
||||||
|
index)))
|
||||||
|
|
||||||
|
(defn set-entity [id value]
|
||||||
|
(update-indices id (entity id) value)
|
||||||
|
(let [gsnew
|
||||||
|
(if (= value nil)
|
||||||
|
(assoc @*gamestate* :entities (dissoc (get @*gamestate* :entities) id))
|
||||||
|
(assoc-in @*gamestate* [:entities id] value))]
|
||||||
|
(ref-set *gamestate* gsnew)))
|
||||||
|
|
||||||
|
(defn q [indextype query]
|
||||||
|
(query-index indextype (get-in @*gamestate* [:indices indextype]) query))
|
||||||
|
|
||||||
|
(defmethod update-index :name [indextype indexold id entityold entitynew]
|
||||||
|
(-> indexold
|
||||||
|
(remove-id-from-index id (get entityold :name))
|
||||||
|
(add-id-to-index id (get entitynew :name))))
|
||||||
|
|
||||||
|
(defmethod query-index :name [indextype index query] (or (get index query) #{}))
|
||||||
|
|
Loading…
Reference in a new issue