UI modifications, better use of binding

This commit is contained in:
Dane Johnson 2023-11-07 14:12:46 -06:00
parent 83159aef5e
commit 21ce9e8bdf
2 changed files with 55 additions and 32 deletions

View File

@ -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

View File

@ -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!