From 69c533ceec697f585224a835cd8478dafaf6b623 Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Sat, 4 May 2013 00:18:22 -0400 Subject: [PATCH] fix state machine bugs --- src/hottub/stm.clj | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/hottub/stm.clj b/src/hottub/stm.clj index 9e7506e..b267791 100644 --- a/src/hottub/stm.clj +++ b/src/hottub/stm.clj @@ -29,7 +29,7 @@ ::id (::id stm) ::return-to (::return-to stm)))) -(defn goto [stm state & [value]] +(defn goto [stm state & [value]] (assoc (stm-from-value stm value) ::state state)) (defn post-event [stm event] @@ -49,8 +49,8 @@ (defn- process-state [stm step] ;(println step (::state stm) (::value stm) (seq (::events stm))) (case step - :enter - (let [[stmnew stepnext] (transition :return-from enter-state stm)] + :enter + (let [[stmnew stepnext] (transition :return-from enter-state stm)] (recur stmnew stepnext)) :return-from (if (is-end-state stm) @@ -75,10 +75,10 @@ stm)) stm)) -(defn start [stmid & [value]] - (let [stm (assoc (or value {}) - ::id stmid - ::state (start-state-for-stm stmid) +(defn start [stmid & [value]] + (let [stm (assoc (or value {}) + ::id stmid + ::state (start-state-for-stm stmid) ::events clojure.lang.PersistentQueue/EMPTY)] (process-state stm :enter))) @@ -114,9 +114,9 @@ `(~handlertype ~opts ~@args))) (defn- normalize-statespec [statespec statedefault] - (let [state-defined + (let [state-defined (keyword? (first statespec)) - [state args] + [state args] (if state-defined [(first statespec) (next statespec)] [statedefault statespec]) @@ -130,23 +130,23 @@ `(~state ~opts ~@(map #(normalize-handlerspec % opts) handlerspecs)))) (defn- states-from-specs [statespecs start-state] - (loop [states [] + (loop [states [] statespecs statespecs statenext start-state statenextindex 0] - + (if (empty? statespecs) (conj states :end) - (let [statespec + (let [statespec (first statespecs) given-state (if (keyword? (first statespec)) (first statespec)) - state + state (or given-state (keyword (str (name statenext) (if (= statenextindex 0) "" statenextindex))))] - + (recur (conj states state) - (next statespecs) + (next statespecs) (if given-state given-state statenext) (if given-state 1 (+ statenextindex 1))))))) @@ -186,8 +186,8 @@ ((:fnhandler handler) stm event)))) (defn- out-stmfnbody [body opts statenext] - `[[& args#] (call-stmfunc (fn ~@body) ~opts args# ~statenext)]) - + `[[& args#] (call-stmfunc (fn ~@body) ~opts args# ~statenext)]) + (defn- out-def-handler [stmid state optsdefault statenext [handlertype opts & args]] (let [opts (into optsdefault opts)] (case handlertype @@ -196,11 +196,11 @@ ::exit [`(defmethod exit-state [~stmid ~state] ~@(out-stmfnbody opts statenext 1 args))] ::call - [(let [[stmidcall & body] + [(let [[stmidcall & body] (if (keyword? (first args)) [(first args) [(gensym)] nil] (first args))] - `(defmethod on-call [~stmid ~state] [stm#] + `(defmethod on-call [~stmid ~state] [stm#] (start ~stmidcall ((fn ~@(ensure-fnbody 1 body)) stm#))))] []))) @@ -211,7 +211,7 @@ ::call [(let [body (next args)] `{:eventtype ::return :fnhandler (fn ~@(out-stmfnbody body opts statenext))})] - [(let [[fnguard body] (if (vector? (first args)) [nil args] args)] + [(let [[fnguard & body] (if (vector? (first args)) [nil args] args)] `{:eventtype ~handlertype :fnguard ~fnguard :fnhandler (fn ~@(out-stmfnbody (ensure-fnbody 2 body) opts statenext))})]))) (defn- out-def-state [stmid [state opts & handlerspecs] statenext] @@ -220,12 +220,12 @@ [`(let [handlers# [~@(apply concat (map #(out-event-handler stmid state opts statenext %) handlerspecs))]] (defmethod on-event [~stmid ~state] [stm# event#] (call-eventhandlers stm# event# handlers#)))])) - + (defmacro defstm [stmid & args] - (let [stmopts + (let [stmopts {:start-state :start} - [stmopts statespecs] - (if (map? (first args)) + [stmopts statespecs] + (if (map? (first args)) [(into stmopts (first args)) (next args)] [stmopts args]) states @@ -234,7 +234,7 @@ (map normalize-statespec statespecs states) endstates (filter #(:is-end-state (second %)) statespecs) - sstmid + sstmid (gensym "stmid")] `(let [~sstmid ~stmid] (remove-stm ~sstmid)