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"]
|
||||
:dependencies [[org.clojure/clojure "1.5.0"]
|
||||
[ns-tracker "0.2.1"]
|
||||
[org.clojure/tools.nrepl "0.2.2"]
|
||||
[org.clojars.jyaan/slick "247.1"]
|
||||
[org.clojars.jyaan/slick-native "247.1"]
|
||||
[org.clojars.jyaan/slick-lwjgl "247.1"]])
|
||||
|
|
|
@ -3,3 +3,9 @@
|
|||
|
||||
(defn -main [& args]
|
||||
(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
|
||||
(: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 render-game (fn [state graphics] (:state state)))
|
||||
(defmulti eval-with-bindings (fn [state game f] (:state state)))
|
||||
|
||||
(def modified-namespaces (ns-tracker ["src" "test"]))
|
||||
|
||||
|
@ -16,24 +23,65 @@
|
|||
:extends org.newdawn.slick.BasicGame)
|
||||
|
||||
(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 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]
|
||||
(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
|
||||
(if-let [statenew (update-game @(.state this) delta)]
|
||||
(ref-set (.state this) (assoc @(.state this) :state statenew)))))
|
||||
(try
|
||||
(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]
|
||||
(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 render-game :default [state graphics])
|
||||
(defmethod eval-with-bindings :default [state game f] (f))
|
||||
|
||||
(defn start-game [title startstate & [value]]
|
||||
(let [game (hottub.slick.Game. title startstate value)
|
||||
container (AppGameContainer. game 640 480 false)]
|
||||
(.start container)))
|
||||
(.start container)
|
||||
game))
|
||||
|
|
Loading…
Reference in a new issue