Change "value" of stm to be the stm itself, since it couldn't be nil anyway

This commit is contained in:
Jeremy Penner 2013-04-30 17:15:41 -04:00
parent de29d67036
commit 4d0dd8ba8d
2 changed files with 34 additions and 30 deletions

View file

@ -1,10 +1,10 @@
(ns hottub.stm) (ns hottub.stm)
(defn- dispatch-id-state [stm] [(:id stm) (:state stm)]) (defn- dispatch-id-state [stm] [(::id stm) (::state stm)])
(defmulti enter-state dispatch-id-state) (defmulti enter-state dispatch-id-state)
(defmulti exit-state dispatch-id-state) (defmulti exit-state dispatch-id-state)
(defmulti on-event (fn [stm event] (dispatch-id-state stm))) (defmulti on-event (fn [stm event] (dispatch-id-state stm)))
(defmulti event-matches (fn [stm eventtype event] (:id stm))) (defmulti event-matches (fn [stm eventtype event] (::id stm)))
(defmulti on-call dispatch-id-state) (defmulti on-call dispatch-id-state)
(defmulti start-state-for-stm (fn [stmid] stmid)) (defmulti start-state-for-stm (fn [stmid] stmid))
@ -13,24 +13,31 @@
(defmethod enter-state :default [stm] nil) (defmethod enter-state :default [stm] nil)
(defmethod exit-state :default [stm]) (defmethod exit-state :default [stm])
(defmethod on-event :default [stm event] nil) (defmethod on-event :default [stm event] nil)
(defmethod event-matches :default [stm eventtype event] (= eventtype (:type event))) (defmethod event-matches :default [stm eventtype event] (or (nil? eventtype) (= eventtype (:type event))))
(defmethod on-call :default [stm] nil) (defmethod on-call :default [stm] nil)
(defmethod start-state-for-stm :default [stmid] :start) (defmethod start-state-for-stm :default [stmid] :start)
(defmethod is-end-state :default [stm] (= (:state stm) :end)) (defmethod is-end-state :default [stm] (= (::state stm) :end))
(defn state [stm] (:state stm)) (defn state [stm] (::state stm))
(defn value [stm] (:value stm))
(defn- stm-from-value [stm value]
(if (nil? value)
stm
(assoc value ::state (or (::state value) (::state stm))
::events (or (::events value) (::events stm))
::id (::id stm)
::return-to (::return-to stm))))
(defn goto [stm state & [value]] (defn goto [stm state & [value]]
(assoc stm :state state :value (or value (:value stm)))) (assoc (stm-from-value stm value) ::state state))
(defn post-event [stm event] (defn post-event [stm event]
(assoc stm :events (conj (:events stm) event))) (assoc stm ::events (conj (::events stm) event)))
(defn- transition [stepnext fntrans stmold & args] (defn- transition [stepnext fntrans stmold & args]
(if-let [stmnew (apply fntrans stmold args)] (if-let [stmnew (apply fntrans stmold args)]
(if-not (= (:state stmnew) (:state stmold)) (if-not (= (::state stmnew) (::state stmold))
(do (do
(exit-state stmold) (exit-state stmold)
[stmnew :enter]) [stmnew :enter])
@ -40,7 +47,7 @@
(declare start) (declare start)
(defn- process-state [stm step] (defn- process-state [stm step]
;(println step (:state stm) (:value stm) (seq (:events stm))) ;(println step (::state stm) (::value stm) (seq (::events stm)))
(case step (case step
:enter :enter
(let [[stmnew stepnext] (transition :return-from enter-state stm)] (let [[stmnew stepnext] (transition :return-from enter-state stm)]
@ -49,19 +56,19 @@
(if (is-end-state stm) (if (is-end-state stm)
(do (do
(exit-state stm) (exit-state stm)
(if-let [stmreturn (:return-to stm)] (if-let [stmreturn (::return-to stm)]
(let [stmreturn (assoc stmreturn :events (:events stm))] (let [stmreturn (assoc stmreturn ::events (::events stm))]
(recur (post-event stmreturn {:id ::return :stmid (:id stm) :state (:state stm) :value (:value stm)}) :events)) (recur (post-event stmreturn (dissoc (assoc stm ::id ::return ::stmid (::id stm)) ::events)) ::events))
nil)) nil))
(recur stm :call)) (recur stm :call))
:call :call
(if-let [[stmid value] (on-call stm)] (if-let [[stmid value] (on-call stm)]
(recur (assoc (start stmid value) :return-to (dissoc stm :events) :events (:events stm)) :events) (recur (assoc (start stmid value) ::return-to (dissoc stm ::events) ::events (::events stm)) :events)
(recur stm :events)) (recur stm :events))
:events :events
(let [queue (:events stm) (let [queue (::events stm)
event (first queue) event (first queue)
stm (if event (assoc stm :events (pop queue)) stm)] stm (if event (assoc stm ::events (pop queue)) stm)]
(if event (if event
(let [[stmnew stepnext] (transition :events on-event stm event)] (let [[stmnew stepnext] (transition :events on-event stm event)]
(recur stmnew stepnext)) (recur stmnew stepnext))
@ -69,10 +76,10 @@
stm)) stm))
(defn start [stmid & [value]] (defn start [stmid & [value]]
(let [stm {:id stmid (let [stm (assoc (or value {})
:state (start-state-for-stm stmid) ::id stmid
:value (or value {}) ::state (start-state-for-stm stmid)
:events clojure.lang.PersistentQueue/EMPTY}] ::events clojure.lang.PersistentQueue/EMPTY)]
(process-state stm :enter))) (process-state stm :enter)))
(defn run [stm & events] (defn run [stm & events]
@ -92,11 +99,9 @@
[(first handlerspec) (next handlerspec)] [(first handlerspec) (next handlerspec)]
optsimplicit optsimplicit
(if (:implicit-state optsdefault) (if (:implicit-state optsdefault)
{:returns-value true {:advances (not= handlertype ::enter)
:advances (not= handlertype ::enter)
:pass-next-state false} :pass-next-state false}
{:returns-value false {:advances false
:advances false
:pass-next-state false}) :pass-next-state false})
[optsoverridden args] [optsoverridden args]
(if (map? (first args)) (if (map? (first args))
@ -162,12 +167,11 @@
(defn call-stmfunc [fn opts args statenext] (defn call-stmfunc [fn opts args statenext]
(let [stm (first args) (let [stm (first args)
args (if (:returns-value opts) (cons (value stm) (next args)) args)
args (if (:pass-next-state opts) (concat args [statenext]) args) args (if (:pass-next-state opts) (concat args [statenext]) args)
result (apply fn args) result (apply fn args)
stm (if (:returns-value opts) (goto stm (state stm) result) (or result stm)) stmnew (stm-from-value stm result)
stm (if (:advances opts) (goto stm statenext (value stm)) stm)] stmnew (if (and (:advances opts) (= (::state stm) (::state stmnew))) (goto stmnew statenext) stmnew)]
stm)) stmnew))
(defn- handler-matches [stm handler event] (defn- handler-matches [stm handler event]
(and (event-matches stm (:eventtype handler) event) (and (event-matches stm (:eventtype handler) event)
@ -197,7 +201,7 @@
[(first args) [(gensym)] nil] [(first args) [(gensym)] nil]
(first args))] (first args))]
`(defmethod on-call [~stmid ~state] [stm#] `(defmethod on-call [~stmid ~state] [stm#]
(start ~stmidcall ((fn ~@(ensure-fnbody 1 body)) (value stm#)))))] (start ~stmidcall ((fn ~@(ensure-fnbody 1 body)) stm#))))]
[]))) [])))
(defn- out-event-handler [stmid state optsdefault statenext [handlertype opts & args]] (defn- out-event-handler [stmid state optsdefault statenext [handlertype opts & args]]

View file

@ -9,7 +9,7 @@
(contains? (:mousebuttons input) :left)) (contains? (:mousebuttons input) :left))
(stm/defstm ::click (stm/defstm ::click
[(::stm/enter {:returns-value false} [stm] [(::stm/enter [stm]
(let [input-now (:input (first (gs/q :name :input))) (let [input-now (:input (first (gs/q :name :input)))
stm (stm/post-event stm (assoc input-now :type :input))] stm (stm/post-event stm (assoc input-now :type :input))]
stm)) stm))