Skip to content

Commit

Permalink
First pass at providing what @pupeno needs for #118
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-thompson-day8 committed Dec 6, 2015
1 parent e59cccd commit 927d318
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 43 deletions.
6 changes: 6 additions & 0 deletions src/re_frame/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
(def on-changes middleware/on-changes)


;; -- Event Procssing Callbacks

(defn add-post-event-callback
[f]
(add-post-event-callback re-frame.router/event-queue f))

;; -- Logging -----
;; re-frame uses the logging functions: warn, log, error, group and groupEnd
;; By default, these functions map directly to the js/console implementations
Expand Down
100 changes: 57 additions & 43 deletions src/re_frame/router.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
(defprotocol IEventQueue
(enqueue [this event])

(add-post-event-callback [this f])

;; Finite State Machine transitions
(-fsm-trigger [this trigger arg])

Expand All @@ -78,14 +80,57 @@
(-resume [this]))


;; Want to understand this? Look at FSM in -fsm-trigger?
(deftype EventQueue [^:mutable fsm-state ^:mutable queue]
;;
(deftype EventQueue [^:mutable fsm-state
^:mutable queue
^:mutable post-event-callback-fns]
IEventQueue

;; -- API ------------------------------------------------------------------
(enqueue [this event]
(-fsm-trigger this :add-event event))

;; Finite State Machine "Actions"
(add-post-event-callback [this f]
(set! post-event-callback-fns (conj post-event-callback-fns f)))


;; -- FSM ------------------------------------------------------------------
(-fsm-trigger
[this trigger arg]

;; work out new FSM state and action function for the transition
(let [[new-state action-fn]
(case [fsm-state trigger]

;; The following specifies all FSM states, tranistions and actions
;; [current-state trigger] [new-state action-fn]

;; the queue is idle
[:idle :add-event] [:scheduled #(do (-add-event this arg)
(-run-next-tick this))]

;; processing has already been scheduled to run in the future
[:scheduled :add-event] [:scheduled #(-add-event this arg)]
[:scheduled :run-queue] [:running #(-run-queue this)]

;; processing one event after another
[:running :add-event ] [:running #(-add-event this arg)]
[:running :pause ] [:paused #(-pause this arg)]
[:running :exception ] [:idle #(-exception this arg)]
[:running :finish-run] (if (empty? queue) ;; FSM guard
[:idle]
[:scheduled #(-run-next-tick this)])

;; event processing is paused - probably by :flush-dom metadata
[:paused :add-event] [:paused #(-add-event this arg)]
[:paused :resume ] [:running #(-resume this)]

(throw (str "re-frame: state transition not found. " fsm-state " " trigger)))]

;; change state and run the action fucntion
(set! fsm-state new-state)
(when action-fn (action-fn))))

(-add-event
[this event]
(set! queue (conj queue event)))
Expand All @@ -97,7 +142,11 @@
(handle event-v)
(catch :default ex
(-fsm-trigger this :exception ex)))
(set! queue (pop queue))))
(set! queue (pop queue))

;; Tell all registed callbacks that an event was just processed.
;; Pass in the event just handled and the new state of the queue
(doseq [f post-event-callback-fns] (f event-v queue))))

(-run-next-tick
[this]
Expand All @@ -110,7 +159,7 @@
(loop [n (count queue)]
(if (zero? n)
(-fsm-trigger this :finish-run nil)
(if-let [later-fn (some later-fns (-> queue peek meta keys))]
(if-let [later-fn (some later-fns (-> queue peek meta keys))] ;; any metadata which causes pausing?
(-fsm-trigger this :pause later-fn)
(do (-process-1st-event this)
(recur (dec n)))))))
Expand All @@ -126,52 +175,17 @@

(-resume
[this]
(-process-1st-event this) ;; do the event which paused processing
(-run-queue this)) ;; do the rest of the queued events

(-fsm-trigger
[this trigger arg]

;; work out new FSM state and action function for the transition
(let [[new-state action-fn]
(case [fsm-state trigger]

;; Here is the FSM
;; [current-state trigger] [new-state action-fn]

;; the queue is idle
[:quiescent :add-event] [:scheduled #(do (-add-event this arg)
(-run-next-tick this))]

;; processing has already been scheduled to run in the future
[:scheduled :add-event] [:scheduled #(-add-event this arg)]
[:scheduled :run-queue] [:running #(-run-queue this)]

;; processing one event after another
[:running :add-event ] [:running #(-add-event this arg)]
[:running :pause ] [:paused #(-pause this arg)]
[:running :exception ] [:quiescent #(-exception this arg)]
[:running :finish-run] (if (empty? queue) ;; FSM guard
[:quiescent]
[:scheduled #(-run-next-tick this)])
(-process-1st-event this) ;; do the event which paused processing
(-run-queue this))) ;; do the rest of the queued events

;; event processing is paused - probably by :flush-dom metadata
[:paused :add-event] [:paused #(-add-event this arg)]
[:paused :resume ] [:running #(-resume this)]

(throw (str "re-frame: state transition not found. " fsm-state " " trigger)))]

;; change state and run the action fucntion
(set! fsm-state new-state)
(when action-fn (action-fn)))))

;; ---------------------------------------------------------------------------
;; This is the global queue for events
;; When an event is dispatched, it is put into this queue. Later the queue
;; will "run" and the event will be "handled" by the registered event handler.
;;

(def event-queue (->EventQueue :quiescent #queue []))
(def event-queue (->EventQueue :idle #queue [] []))


;; ---------------------------------------------------------------------------
Expand Down

0 comments on commit 927d318

Please sign in to comment.