re-frame/src/re_frame/handlers.cljs

77 lines
2.4 KiB
Plaintext
Raw Normal View History

2014-12-15 11:56:32 +00:00
(ns re-frame.handlers
(:require-macros [cljs.core.async.macros :refer [go-loop]])
2014-12-15 11:56:32 +00:00
(:require [re-frame.db :refer [app-db]]
[re-frame.utils :refer [first-in-vector]]
[cljs.core.async :refer [chan put! <! timeout]]))
2014-12-08 03:48:59 +00:00
;; -- register of handlers ------------------------------------------------------------------------
2014-12-15 11:56:32 +00:00
(def ^:private id->fn (atom {}))
(defn register
"register a handler for an event"
[event-id handler-fn]
(if (contains? @id->fn event-id)
(println "Warning: overwritting an event-handler" event-id)) ;; TODO: more generic logging
(swap! id->fn
assoc event-id handler-fn))
;; -- dispatching and routing ---------------------------------------------------------------------
(def ^:private dispatch-chan (chan))
(defn dispatch
"components send events by calling this function.
2014-12-15 11:56:32 +00:00
Usage example:
(dispatch [:delete-item 42])"
[event-v]
(assert (some? event-v)) ;; nil would close the channel
(put! dispatch-chan event-v))
2015-01-05 21:49:20 +00:00
(defn dispatch-sync
"sync version of above that actually does the dispatch"
[event-v]
(let [event-id (first-in-vector event-v)
handler-fn (get @id->fn event-id)]
(assert (some? handler-fn) (str "No event handler registered for event: " event-id ))
2015-01-05 21:49:20 +00:00
(handler-fn app-db event-v)))
(defn- router
"route an event, arriving on the dispatch channel, to the right handler"
[]
(go-loop []
2015-01-05 21:49:20 +00:00
(let [event-v (<! dispatch-chan)]
(dispatch-sync event-v)
(<! (timeout 0)) ;; just in case we are handling one dispatch after an other, give the GU a chance to do its stuff.
(recur))))
(router) ;; run the router loop it
2014-12-08 03:48:59 +00:00
;; -- helper --------------------------------------------------------------------------------------
2014-12-08 03:48:59 +00:00
;; TODO: this has to go.
2014-12-15 11:56:32 +00:00
(defn transaction!
"A helper fucntion to be used when writting event handlers.
Allows a handler to perform an atomic modification of the atom.
Modification consist of one or more mutations, wrapped by a function,
followed by a call to a validation fucntion which may also annotate the
data structures with further information.
XXX This feels a bit too nested."
([db description mutation-fn]
(transaction! db description mutation-fn identity))
([db description mutation-fn validation-fn]
(reset! db
(-> @db
(assoc :undo-description description)
mutation-fn
validation-fn))))
2014-12-08 03:48:59 +00:00