Implement nrepl support, catch exceptions. Hot code reload is now fully operational.
This commit is contained in:
parent
246213c8a2
commit
339e6f5444
|
@ -6,6 +6,7 @@
|
||||||
:jvm-opts ["-Djava.library.path=native"]
|
:jvm-opts ["-Djava.library.path=native"]
|
||||||
:dependencies [[org.clojure/clojure "1.5.0"]
|
:dependencies [[org.clojure/clojure "1.5.0"]
|
||||||
[ns-tracker "0.2.1"]
|
[ns-tracker "0.2.1"]
|
||||||
|
[org.clojure/tools.nrepl "0.2.2"]
|
||||||
[org.clojars.jyaan/slick "247.1"]
|
[org.clojars.jyaan/slick "247.1"]
|
||||||
[org.clojars.jyaan/slick-native "247.1"]
|
[org.clojars.jyaan/slick-native "247.1"]
|
||||||
[org.clojars.jyaan/slick-lwjgl "247.1"]])
|
[org.clojars.jyaan/slick-lwjgl "247.1"]])
|
||||||
|
|
|
@ -3,3 +3,9 @@
|
||||||
|
|
||||||
(defn -main [& args]
|
(defn -main [& args]
|
||||||
(slick/start-game "test-game" :game))
|
(slick/start-game "test-game" :game))
|
||||||
|
|
||||||
|
(defmethod slick/update-game :game [state delta])
|
||||||
|
(def ^:dynamic g nil)
|
||||||
|
(def ^:dynamic s nil)
|
||||||
|
(defmethod slick/eval-with-bindings :game [state game f]
|
||||||
|
(binding [g game s state] (f)))
|
|
@ -1,9 +1,16 @@
|
||||||
(ns hottub.slick
|
(ns hottub.slick
|
||||||
(:import [org.newdawn.slick AppGameContainer])
|
(:import [org.newdawn.slick AppGameContainer])
|
||||||
(:use ns-tracker.core))
|
(:use ns-tracker.core)
|
||||||
|
(:require (clojure.tools.nrepl [server :as server]
|
||||||
|
[middleware :as middleware])
|
||||||
|
(clojure.tools.nrepl.middleware interruptible-eval
|
||||||
|
pr-values
|
||||||
|
session
|
||||||
|
load-file)))
|
||||||
|
|
||||||
(defmulti update-game (fn [state delta] (:state state)))
|
(defmulti update-game (fn [state delta] (:state state)))
|
||||||
(defmulti render-game (fn [state graphics] (:state state)))
|
(defmulti render-game (fn [state graphics] (:state state)))
|
||||||
|
(defmulti eval-with-bindings (fn [state game f] (:state state)))
|
||||||
|
|
||||||
(def modified-namespaces (ns-tracker ["src" "test"]))
|
(def modified-namespaces (ns-tracker ["src" "test"]))
|
||||||
|
|
||||||
|
@ -16,24 +23,65 @@
|
||||||
:extends org.newdawn.slick.BasicGame)
|
:extends org.newdawn.slick.BasicGame)
|
||||||
|
|
||||||
(defn game-create [title startstate value]
|
(defn game-create [title startstate value]
|
||||||
[[title] (ref (assoc (or value {}) :state startstate))])
|
[[title]
|
||||||
|
(let [evalqueueatom (atom [])
|
||||||
|
executor (reify java.util.concurrent.Executor
|
||||||
|
(execute [this f] (swap! evalqueueatom #(conj % f))))
|
||||||
|
server (server/start-server :handler
|
||||||
|
(-> server/unknown-op
|
||||||
|
clojure.tools.nrepl.middleware/wrap-describe
|
||||||
|
(clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval :executor executor)
|
||||||
|
clojure.tools.nrepl.middleware.load-file/wrap-load-file
|
||||||
|
clojure.tools.nrepl.middleware.pr-values/pr-values
|
||||||
|
clojure.tools.nrepl.middleware.session/add-stdin
|
||||||
|
clojure.tools.nrepl.middleware.session/session
|
||||||
|
; ((fn [h] (fn [val] (prn val) (h val))))))]
|
||||||
|
))]
|
||||||
|
(prn "nrepl started on port " (:port server) server)
|
||||||
|
{:state (ref (assoc (or value {}) :state startstate))
|
||||||
|
:evalqueue evalqueueatom
|
||||||
|
:server server})])
|
||||||
|
|
||||||
|
(defn game-state-ref [this] (:state (.state this)))
|
||||||
|
|
||||||
(defn game-init [this container])
|
(defn game-init [this container])
|
||||||
|
|
||||||
|
(defn clear-and-get-evalqueue [this]
|
||||||
|
(let [evalqueueatom (:evalqueue (.state this))]
|
||||||
|
(loop [evalqueue @evalqueueatom]
|
||||||
|
(if (compare-and-set! evalqueueatom evalqueue [])
|
||||||
|
evalqueue
|
||||||
|
(recur @evalqueueatom)))))
|
||||||
|
|
||||||
(defn game-update [this container delta]
|
(defn game-update [this container delta]
|
||||||
(doseq [ns-sym (modified-namespaces)]
|
(doseq [ns-sym (modified-namespaces)]
|
||||||
(require ns-sym :reload))
|
(try
|
||||||
|
(require ns-sym :reload)
|
||||||
|
(catch Exception e (prn "Couldn't load" ns-sym (.getMessage e)))))
|
||||||
|
(doseq [f (clear-and-get-evalqueue this)]
|
||||||
|
(try
|
||||||
|
(eval-with-bindings @(game-state-ref this) this f)
|
||||||
|
(catch Exception e (prn "couldn't eval" f (.getMessage e)))))
|
||||||
(dosync
|
(dosync
|
||||||
(if-let [statenew (update-game @(.state this) delta)]
|
(try
|
||||||
(ref-set (.state this) (assoc @(.state this) :state statenew)))))
|
(if-let [statenew (update-game @(game-state-ref this) delta)]
|
||||||
|
(ref-set (game-state-ref this) statenew))
|
||||||
|
(catch Exception e (prn "Couldn't update" (:state @(game-state-ref this)) (.getMessage e))))))
|
||||||
|
|
||||||
(defn game-render [this container graphics]
|
(defn game-render [this container graphics]
|
||||||
(render-game @(.state this) graphics))
|
(try
|
||||||
|
(render-game @(game-state-ref this) graphics)
|
||||||
|
(catch Exception e (prn "Couldn't render" (:state @(game-state-ref this)) (.getMessage e)))))
|
||||||
|
|
||||||
|
(defn game-setstate [this statenew]
|
||||||
|
(dosync (ref-set (game-state-ref this) statenew)))
|
||||||
|
|
||||||
(defmethod update-game :default [state delta])
|
(defmethod update-game :default [state delta])
|
||||||
(defmethod render-game :default [state graphics])
|
(defmethod render-game :default [state graphics])
|
||||||
|
(defmethod eval-with-bindings :default [state game f] (f))
|
||||||
|
|
||||||
(defn start-game [title startstate & [value]]
|
(defn start-game [title startstate & [value]]
|
||||||
(let [game (hottub.slick.Game. title startstate value)
|
(let [game (hottub.slick.Game. title startstate value)
|
||||||
container (AppGameContainer. game 640 480 false)]
|
container (AppGameContainer. game 640 480 false)]
|
||||||
(.start container)))
|
(.start container)
|
||||||
|
game))
|
||||||
|
|
Loading…
Reference in a new issue