(ns re-frame.handlers (:refer-clojure :exclude [flush]) (:require-macros [cljs.core.async.macros :refer [go-loop go]]) (:require [reagent.core :refer [flush]] [re-frame.db :refer [app-db]] [re-frame.utils :refer [first-in-vector warn]] [cljs.core.async :refer [chan put! fn (atom {})) (defn register "register a handler for an event" ([event-id handler-fn] (when (contains? @id->fn event-id) (warn "re-frame: overwriting an event-handler for: " event-id)) ;; allow it, but warn. (swap! id->fn assoc event-id handler-fn)) ([event-id middleware handler-fn] (let [mware (comp-middleware middleware) hander-fn (mware handler-fn)] (register event-id hander-fn)))) ;; -- The Event Conveyor Belt -------------------------------------------------------------------- ;; ;; Moves events from "dispatch" to the router loop. ;; Allows for the aysnc handling of events. ;; (def ^:private event-chan (chan)) ;; TODO: set buffer size? ;; -- lookup and call ----------------------------------------------------------------------------- (defn lookup-handler [event-id] (get @id->fn event-id)) (defn handle "Given an event vector, look up the right handler, then call it. By default, handlers are not assumed to be pure. They are called with two paramters: - the `app-db` atom and - the event vector The handler is assumed to side-effect on the atom, the return value is ignored. To write pure handlers, use the \"pure\" middleware when registering the handler." [event-v] (let [event-id (first-in-vector event-v) handler-fn (lookup-handler event-id)] (if (nil? handler-fn) (warn "re-frame: no event handler registered for: \"" event-id "\". Ignoring.") ;; TODO: make exception (handler-fn app-db event-v)))) ;; -- router loop --------------------------------------------------------------------------------- ;; ;; In a perpretual loop, read events from the dispatch channel, and route them ;; to the right handler. ;; ;; Because handlers occupy the CPU, before each event is handled, hand ;; back control to the browser, via a (