 ;;     particular, we handle the case where handling one event will beget
 ;;     another event. The freshly begat event will be handled next cycle,
 ;;     with yielding in-between.
-;;   - In some cases, an event should not be run until after the GUI has been
+;;   - In some cases, an event should not be handled until after the GUI has been
 ;;     updated, i.e., after the next Reagent animation frame. In such a case,
 ;;     the event should be dispatched with :flush-dom metadata like this:
 ;;       (dispatch ^:flush-dom [:event-id other params])
 ;;     Such an event will temporarily block all further processing because
-;;     events are processed sequentially: we handle each event before we
-;;     handle the ones behind it.
-;;
-;; Implementation
+;;     events are processed sequentially: we handle one event completely
+;;     before we handle the ones behind it.
+;;
+;; Implementation Notes:
 ;;   - queue processing can be in a number of states: scheduled, running, paused
-;;     etc. So it is modeled below as a Finite State Machine.
+;;     etc. So it is modeled as a Finite State Machine.
 ;;     See "-fsm-trigger" (below) for the states and transitions.
 ;;   - the scheduling is done via "goog.async.nextTick" which is pretty quick
 ;;   - when the event has :flush-dom metadata we schedule via
-;;       "reagent.impl.batching.do-later"
-;;     which will run event processing after the next reagent animation frame.
-;;
-
+;;       "reagent.core.after-render"
+;;     which will run event processing after the next Reagent animation frame.
+;;
+
+;; Events can have metadata which say to pause event processing.
 ;; event metadata -> "run later" functions
 (def later-fns
   {:flush-dom (fn [f] ((.-after-render reagent.core) #(goog.async.nextTick f)))   ;; one tick after the end of the next annimation frame
    :yield     goog.async.nextTick})           ;; almost immediately
 
+
+;; Abstract representation of the Queue
 (defprotocol IEventQueue
+
+  ;; -- Public API
   (enqueue [this event])
-
   (add-post-event-callback [this f])
 
-  ;; Finite State Machine transitions
+  ;; -- Implementation via a Finite State Machine
   (-fsm-trigger [this trigger arg])
 
-  ;; Finite State Machine (FSM) actions
+  ;; -- Finite State Machine actions
   (-add-event [this event])
   (-process-1st-event [this])
   (-run-next-tick [this])


(defn dispatch-sync
  "Send an event to be processed by the registered handler
  immediately. Note: dispatch-sync may not be called while another
  event is being handled.

  Usage example:

;; to process all queued events, or else something like a bursty websocket
;; (producing events) might overwhelm the queue. So there's a balance.
;;
;; The processing/handling of an event happens "asynchronously" sometime after
;; that event was enqueued via "dispatch". The original implementation of this router loop
;; used core.async. It was fairly simple, and it mostly worked, but it did not
;; give enough control. So now we hand-roll our own, finite-state-machine and all.
;;
;; The strategy is this:
;;   - maintain a FIFO queue of `dispatched` events.
;;   - when a new event arrives, "schedule" processing of this queue using
;;     goog.async.nextTick, which means it will happen "very soon".
;;   - when processing events, one after the other, do ALL the those currently
;;     queued. Don't stop. Don't yield to the browser. Hog that CPU.
;;   - but if any new events are dispatched during this cycle of processing,
;;     don't do them immediately. Leave them queued. Yield first to the browser,
;;     and do these new events in the next processing cycle. That way we drain
