diff --git a/project.clj b/project.clj index 80eab2ccc..c71adf559 100644 --- a/project.clj +++ b/project.clj @@ -4,6 +4,7 @@ :dependencies [[org.clojure/clojure "1.6.0"] [org.clojure/clojurescript "0.0-2371"] + [org.clojure/core.async "0.1.346.0-17112a-alpha" :scope "provided"] [reagent "0.4.3"] [historian "1.0.7"]] diff --git a/src/re_frame/handlers.cljs b/src/re_frame/handlers.cljs index 34f2e4397..f4b16cb77 100644 --- a/src/re_frame/handlers.cljs +++ b/src/re_frame/handlers.cljs @@ -1,8 +1,12 @@ (ns re-frame.handlers + (:require-macros [cljs.core.async.macros :refer [go-loop]]) (:require [re-frame.db :refer [app-db]] - [re-frame.utils :refer [first-in-vector]])) + [re-frame.utils :refer [first-in-vector]] + [cljs.core.async :refer [chan put! fn (atom {})) @@ -15,17 +19,36 @@ assoc event-id handler-fn)) +;; -- dispatching and routing --------------------------------------------------------------------- + +(def ^:private dispatch-chan (chan)) + (defn dispatch - "reagent components handle events by calling this function. + "reagent components send events by calling this function. Usage example: (dispatch [:delete-item 42])" [event-v] - (let [event-id (first-in-vector event-v) - handler-fn (get @id->fn event-id)] - (assert (not (nil? handler-fn)) (str "No event handler registered for event: " event-id )) - (handler-fn app-db event-v))) + (assert (some? event-v)) ;; nil would close the channel + (put! dispatch-chan event-v)) + + +(defn- router + "route an event, arriving on the dispatch channel, to the right handler" + [] + (go-loop [] + (let [event-v (fn event-id)] + (assert (not (nil? handler-fn)) (str "No event handler registered for event: " event-id )) + (handler-fn app-db event-v) + (recur)))) + +(router) ;; run the router loop it + +;; -- helper -------------------------------------------------------------------------------------- +;; TODO: this has to go. (defn transaction! "A helper fucntion to be used when writting event handlers. Allows a handler to perform an atomic modification of the atom.