(ns age-of-sail.simulation) (def tickrate 100) (def hooks (atom '())) (defn subscribe! "Adds a hook to the hooks" [f] (swap! hooks conj f)) (defonce program (atom :stopped)) (defn game-loop [] (while (#{:running :paused} @program) (when (= :running @program) (doseq [hook @hooks] (hook))) (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 [] (when (= (first (reset-vals! program :running)) :stopped) (.start (Thread. game-loop))))