UI modifications, better use of binding
This commit is contained in:
parent
83159aef5e
commit
21ce9e8bdf
@ -1,16 +1,17 @@
|
|||||||
;; you should be in age-of-sail.core>
|
;; you should be in age-of-sail.core>
|
||||||
|
|
||||||
(def my-ship (ref {:position [0. 0.]
|
(def virginia-woolfe (ref {:position [0. 0.]
|
||||||
:name "Virginia Woolfe"
|
:name "Virginia Woolfe"
|
||||||
|
:heading (normalize [1.0 1.0])
|
||||||
|
:slots [{:type :downwind-sail :length 2 :furl 1.0}]
|
||||||
|
:velocity [1. 0.]}))
|
||||||
|
|
||||||
|
(def revenge (ref {:position [0. 0.]
|
||||||
|
:name "Revenge"
|
||||||
:heading (normalize [1.0 1.0])
|
:heading (normalize [1.0 1.0])
|
||||||
:slots [{:type :downwind-sail :length 2 :furl 1.0}]
|
:slots [{:type :downwind-sail :length 2 :furl 1.0}]
|
||||||
:velocity [1. 0.]}))
|
:velocity [1. 0.]}))
|
||||||
|
|
||||||
(reset! ships [my-ship])
|
(reset! ships [virginia-woolfe revenge])
|
||||||
|
|
||||||
(start-program)
|
|
||||||
@my-ship
|
|
||||||
(stop-program)
|
|
||||||
|
|
||||||
(show-ui)
|
|
||||||
@tracked-ship
|
@tracked-ship
|
||||||
|
@ -7,8 +7,10 @@
|
|||||||
(def tickrate 100)
|
(def tickrate 100)
|
||||||
(def hardcoded-wind [0.1 3.0]) ;; A strong easternly wind!
|
(def hardcoded-wind [0.1 3.0]) ;; A strong easternly wind!
|
||||||
(defonce ships (atom []))
|
(defonce ships (atom []))
|
||||||
(defonce program (atom nil))
|
|
||||||
|
|
||||||
|
(defn list-ships
|
||||||
|
[ships]
|
||||||
|
(map #(:name @%) ships))
|
||||||
(defn find-ship
|
(defn find-ship
|
||||||
[ships name]
|
[ships name]
|
||||||
(some #(when (= name (:name @%)) %) ships))
|
(some #(when (= name (:name @%)) %) ships))
|
||||||
@ -44,39 +46,60 @@
|
|||||||
(doseq [ship ships]
|
(doseq [ship ships]
|
||||||
(-> ship (physics-step hardcoded-wind))))
|
(-> ship (physics-step hardcoded-wind))))
|
||||||
|
|
||||||
(defn stop-program
|
;; Simulation controls
|
||||||
|
(defonce program (atom :stopped))
|
||||||
|
(defn game-loop
|
||||||
[]
|
[]
|
||||||
(when @program
|
(while (#{:running :paused} @program)
|
||||||
(reset! @program false)))
|
(when (= :running @program)
|
||||||
|
(tick @ships))
|
||||||
|
(Thread/sleep (quot 1000 tickrate)))
|
||||||
|
(when-not (compare-and-set! program :killed :stopped)
|
||||||
|
(throw "Error: tried to stop a program that wasn't killed!")))
|
||||||
|
|
||||||
|
(defn pause-program
|
||||||
|
[]
|
||||||
|
(compare-and-set! program :running :paused))
|
||||||
|
|
||||||
|
(defn kill-program
|
||||||
|
[]
|
||||||
|
(compare-and-set! program :running :paused)
|
||||||
|
(compare-and-set! program :paused :killed))
|
||||||
|
|
||||||
(defn start-program
|
(defn start-program
|
||||||
[]
|
[]
|
||||||
(stop-program)
|
(when (= (first (reset-vals! program :running)) :stopped)
|
||||||
(let [thread-continue (atom true)]
|
(.start (Thread. game-loop))))
|
||||||
(.start
|
|
||||||
(Thread.
|
|
||||||
(fn []
|
|
||||||
(while @thread-continue
|
|
||||||
(tick @ships)
|
|
||||||
(Thread/sleep (quot 1000 tickrate))))))
|
|
||||||
(reset! program thread-continue)))
|
|
||||||
|
|
||||||
;; UI
|
;; UI
|
||||||
|
(defn ignore-args
|
||||||
|
[f]
|
||||||
|
(fn [& _] (f)))
|
||||||
|
|
||||||
(def tracked-ship (atom nil))
|
(def tracked-ship (atom nil))
|
||||||
|
|
||||||
(defn ship-start-stop
|
(defn simulation-controls
|
||||||
[]
|
[]
|
||||||
(letfn [(indicator [running] (if running "Stop" "Start"))
|
(let [start-button (button :text "Start" :listen [:mouse-clicked (ignore-args start-program)])
|
||||||
(toggle-prgm [_] (if @@program (stop-program) (start-program)))]
|
pause-button (button :text "Pause" :listen [:mouse-clicked (ignore-args pause-program)])
|
||||||
(let [btn (button :text (indicator @@program))]
|
kill-button (button :text "Kill" :listen [:mouse-clicked (ignore-args kill-program)])]
|
||||||
(b/bind @program (b/transform indicator) (b/property btn :text))
|
(letfn [(start-enabled? [state] (contains? #{:stopped :paused} state))
|
||||||
(listen btn :mouse-clicked toggle-prgm)
|
(pause-enabled? [state] (= :running state))
|
||||||
btn)))
|
(kill-enabled? [state] (contains? #{:running :paused} state))]
|
||||||
|
(b/bind program (b/tee
|
||||||
|
(b/bind (b/transform start-enabled?) (b/property start-button :enabled?))
|
||||||
|
(b/bind (b/transform pause-enabled?) (b/property pause-button :enabled?))
|
||||||
|
(b/bind (b/transform kill-enabled?) (b/property kill-button :enabled?))))
|
||||||
|
(config! start-button :enabled? (start-enabled? @program))
|
||||||
|
(config! pause-button :enabled? (pause-enabled? @program))
|
||||||
|
(config! kill-button :enabled? (kill-enabled? @program))
|
||||||
|
(horizontal-panel :items [start-button pause-button kill-button]))))
|
||||||
|
|
||||||
(defn ship-chooser
|
(defn ship-chooser
|
||||||
[]
|
[]
|
||||||
(let [name (text :columns 20)]
|
(let [name (combobox :model (list-ships @ships))]
|
||||||
(b/bind (.getDocument name) (b/transform #(find-ship @ships %)) tracked-ship)
|
(b/bind ships (b/transform list-ships) (b/property name :model))
|
||||||
|
(b/bind (b/selection name) (b/transform #(find-ship @ships %)) tracked-ship)
|
||||||
(flow-panel :items ["Ship Name" name])))
|
(flow-panel :items ["Ship Name" name])))
|
||||||
|
|
||||||
(defn format-position
|
(defn format-position
|
||||||
@ -96,13 +119,12 @@
|
|||||||
(defn show-ui
|
(defn show-ui
|
||||||
[]
|
[]
|
||||||
(let [root (frame :title "Age of Sail" :content (vertical-panel))
|
(let [root (frame :title "Age of Sail" :content (vertical-panel))
|
||||||
start-stop (ship-start-stop)
|
|
||||||
chooser (ship-chooser)
|
chooser (ship-chooser)
|
||||||
info (ship-info)]
|
info (ship-info)]
|
||||||
(b/bind tracked-ship (b/transform boolean) (b/tee (b/property info :visible?)
|
(b/bind tracked-ship (b/transform boolean) (b/tee (b/property info :visible?)
|
||||||
(b/b-do [_] (pack! root))))
|
(b/b-do [_] (pack! root))))
|
||||||
(doto root
|
(doto root
|
||||||
(add! start-stop)
|
(add! (simulation-controls))
|
||||||
(add! chooser)
|
(add! chooser)
|
||||||
(add! info)
|
(add! info)
|
||||||
pack!
|
pack!
|
||||||
|
Loading…
Reference in New Issue
Block a user