Initial commit with working gamestate + indexing.

This commit is contained in:
Jeremy Penner 2013-03-05 23:14:20 -05:00
commit a32058babd
4 changed files with 98 additions and 0 deletions

8
.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
/pom.xml
*jar
/lib
/classes
/native
/.lein-failures
/checkouts
/.lein-deps-sum

13
README Normal file
View 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
View 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
View 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) #{}))