Skip to content

Instantly share code, notes, and snippets.

@borkdude
Last active October 12, 2018 22:34
Show Gist options
  • Save borkdude/7fcf0b2f96ba40b253fe6aae13ce5eef to your computer and use it in GitHub Desktop.
Save borkdude/7fcf0b2f96ba40b253fe6aae13ce5eef to your computer and use it in GitHub Desktop.
core.async stopwatch
(defn stopwatch
"When started, invokes action every ms, until stopped. Reset will
start the stopwatch if it wasn't yet or will reset the timer."
[ms action]
(let [state (volatile! :paused)
started? #(= :started @state)
cmd-ch (a/chan)
start (fn []
(a/go-loop []
(vreset! state :started)
(a/alt! cmd-ch ([v ch]
(case v
:reset (recur)
:stop (vreset! state :stopped)
:fire (do (action)
(recur))))
(a/timeout ms) ([v ch]
(do
(action)
(recur))))))
stop (fn []
(when (started?)
(a/put! cmd-ch :stop)))
reset (fn []
(if (started?)
(a/put! cmd-ch :reset)
(start)))
fire (fn []
(when (started?)
(a/put! cmd-ch :fire)))]
{:reset reset
:start start
:stop stop
:fire fire}))
(comment
(def s (stopwatch 5000 #(println "action")))
((:start s))
((:stop s))
((:reset s))
((:fire s))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment