Last active
October 12, 2018 22:34
-
-
Save borkdude/7fcf0b2f96ba40b253fe6aae13ce5eef to your computer and use it in GitHub Desktop.
core.async stopwatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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