Created
May 17, 2010 17:22
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
(ns | |
#^{:author "Eric Schulte", | |
:license "GPLV3", | |
:doc "Simple concurrent propagator system."} | |
propagator | |
(:use clojure.contrib.repl-utils clojure.contrib.math)) | |
(defmacro cell "Define a new cell." | |
[name state] | |
`(def ~name (agent ~state))) | |
(defn set-cell "Set the value of a cell" [cell value] | |
(send cell (fn [_] value))) | |
(defmacro propagator "Define a new propagator." | |
[name in-cells out-cells & body] | |
`(do | |
(defn ~(with-meta name | |
(assoc (meta name) | |
:in-cells in-cells :out-cells out-cells)) | |
~in-cells ~@body) | |
(doseq [cell# ~in-cells] (add-neighbor cell# ~name)) | |
~name)) | |
(defmacro run-propagator | |
"Run a propagator, first collect the most recent values from all | |
cells associated with the propagator, then evaluate." | |
[propagator] | |
`(let [results# (apply ~propagator (map deref (:in-cells ^#'~propagator)))] | |
(doseq [cell# (:out-cells ^#'~propagator)] | |
(when (not (= @cell# results#)) | |
(send cell# (fn [_#] results#)))) | |
results#)) | |
(defmacro add-neighbor "Add a neighbor to the given cell." | |
[cell neighbor] | |
`(add-watcher | |
~cell :send | |
(agent nil :validator (fn [_#] (do (future (run-propagator ~neighbor)) true))) | |
(fn [_# _#]))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment