Created
February 11, 2020 21:22
-
-
Save hiredman/d5f0cfe20af8328295edab23c20f9452 to your computer and use it in GitHub Desktop.
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
(require '[clojure.core.async.impl.protocols :as impl] | |
'[clojure.core.async.impl.dispatch :as dispatch] | |
'[clojure.core.async.impl.channels :as c] | |
'[clojure.core.async :as async]) | |
;;=> nil | |
(defn wait [watchable expected?] | |
(reify | |
impl/ReadPort | |
(take! [this handler] | |
(let [k (Object.) | |
handle! (fn [] | |
(.lock handler) | |
(let [good (and (impl/active? handler) | |
(impl/commit handler))] | |
(.unlock handler) | |
good))] | |
(add-watch watchable k (fn [k r os ns] | |
(if (impl/active? handler) | |
(when-let [good (and (expected? os ns) | |
(handle!))] | |
(remove-watch watchable k) | |
(dispatch/run #(good ns))) | |
(remove-watch watchable k)))) | |
(let [v @watchable] | |
(when-let [good (and (expected? v v) | |
(handle!))] | |
(remove-watch watchable k) | |
(c/box v))))))) | |
;;=> #'user/wait | |
(def x (atom :foo)) | |
;;=> #'user/x | |
(first (async/alts!! [(async/timeout 1000) (wait x (fn [old new] (= new :bar)))])) | |
;;=> nil | |
(reset! x :bar) | |
;;=> :bar | |
(first (async/alts!! [(async/timeout 1000) (wait x (fn [old new] (= new :bar)))])) | |
;;=> :bar | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment