updating main readme for publishing on repo.or.cz
[propagator.git] / src / propagator.clj
blob65170f257fc5df1c05a6a90f8b620544789ea067
1 (ns #^{:author "Eric Schulte",
2        :license "GPLV3",
3        :doc "Simple concurrent propagator system."}
4   propagator
5   (:use clojure.contrib.repl-utils clojure.contrib.math))
7 (defn set-cell "Set the value of a cell" [cell value]
8   (send cell (constantly value)))
10 (defmacro run-propagator
11   "Run a propagator, first collect the most recent values from all
12 cells associated with the propagator, then evaluate."
13   [propagator]
14   `(let [results# (apply ~propagator (map deref (:in-cells (meta ~propagator))))]
15      (doseq [cell# (:out-cells (meta ~propagator))]
16        (when (not (= @cell# results#))
17          (set-cell cell# results#)))
18      results#))
20 (defn add-neighbor "Add a neighbor to the given cell." [cell neighbor]
21   (add-watch cell nil (fn [_ _ _ _] (future (run-propagator neighbor)))))
23 (defmacro defcell "Define a new cell." [name state]
24   `(def ~name (agent ~state)))
26 (defmacro defpropagator "Define a new propagator."
27   [name in-cells out-cells & body]
28   `(let [v# (defn ~(vary-meta name assoc :in-cells in-cells :out-cells out-cells)
29               ~in-cells ~@body)]
30      (doseq [cell# ~in-cells] (add-neighbor cell# ~name))
31      v#))