From dd5bf7a53adac07845e8d8be37240132a4cdbc5f Mon Sep 17 00:00:00 2001 From: Nicholas Kariniemi Date: Wed, 15 Oct 2014 11:07:55 +0300 Subject: [PATCH 1/2] Clean up state loop --- src/cljx/grub/state.cljx | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/cljx/grub/state.cljx b/src/cljx/grub/state.cljx index 5f6d3d3..b127b71 100644 --- a/src/cljx/grub/state.cljx +++ b/src/cljx/grub/state.cljx @@ -59,27 +59,23 @@ (go (loop [shadow initial-shadow states (sync/new-state @state)] (let [[v c] (a/alts! [new-states events] :priority true)] - (when v - (cond (= c new-states) - (let [current (sync/get-current-state states)] - (when-not (= shadow v) + (cond (nil? v) nil ;; drop out of loop + (= c new-states) + (do (when-not (= shadow v) (>! >remote (diff-msg shadow v))) - (recur shadow - (if (= v current) - states - (sync/add-history-state states v)))) - (= c events) - (let [event (assoc v - :states states - :client? client? - :shadow shadow) - {:keys [new-states new-shadow out-event]} (handle-event event)] - (when (and new-states (not= states new-states)) - (let [new-state (sync/get-current-state new-states)] - (reset! state new-state))) - (when out-event (a/put! >remote out-event)) - (recur (if new-shadow new-shadow shadow) - (if new-states new-states states)))))))))) + (recur shadow (sync/add-history-state states v))) + (= c events) + (let [event (assoc v + :states states + :client? client? + :shadow shadow) + {:keys [new-states new-shadow out-event]} (handle-event event)] + (when (and new-states (not= states new-states)) + (let [new-state (sync/get-current-state new-states)] + (reset! state new-state))) + (when out-event (a/put! >remote out-event)) + (recur (if new-shadow new-shadow shadow) + (if new-states new-states states))))))))) (def make-server-agent (partial make-agent false)) (def make-client-agent (partial make-agent true)) From fd249cefcab4ec25b1dd7022fbe17fc4b58615ac Mon Sep 17 00:00:00 2001 From: Nicholas Kariniemi Date: Wed, 15 Oct 2014 14:46:12 +0300 Subject: [PATCH 2/2] Use swap! in diff handling to update state - Ensures state updates always use the current state as a basis. --- src/cljx/grub/state.cljx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/cljx/grub/state.cljx b/src/cljx/grub/state.cljx index b127b71..67e336f 100644 --- a/src/cljx/grub/state.cljx +++ b/src/cljx/grub/state.cljx @@ -13,11 +13,10 @@ (defmulti handle-event (fn [event] (:type event))) -(defmethod handle-event :diff [{:keys [hash diff states shadow client?] :as msg}] +(defmethod handle-event :diff [{:keys [hash diff states shadow client? state] :as msg}] (let [history-shadow (sync/get-history-state states hash)] (if history-shadow - (let [state (sync/get-current-state states) - new-state (diff/patch-state state diff) + (let [new-state (swap! diff/patch-state state diff) new-states (sync/add-history-state states new-state) new-shadow (diff/patch-state history-shadow diff) new-diff (diff/diff-states new-shadow new-state) @@ -68,11 +67,9 @@ (let [event (assoc v :states states :client? client? - :shadow shadow) + :shadow shadow + :state state) {:keys [new-states new-shadow out-event]} (handle-event event)] - (when (and new-states (not= states new-states)) - (let [new-state (sync/get-current-state new-states)] - (reset! state new-state))) (when out-event (a/put! >remote out-event)) (recur (if new-shadow new-shadow shadow) (if new-states new-states states)))))))))