/
make.cljs
65 lines (53 loc) · 2.03 KB
/
make.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
(ns statecharts.make
(:require [statecharts.state :as state]
[statecharts.context :as ctx]
[statecharts.transition :as transition]
[clojure.zip :as zip]
[statecharts.path :as path]))
(defn make-transitions [state state-index]
(let [{:keys [id transitions]} state]
(cond-> state
(some? transitions)
(update :transitions
(fn [transitions]
(->> transitions
(mapv (fn [transition]
(let [{:keys [target]} transition]
(-> transition
(assoc
:source id
:state-index state-index)
(update :target #(path/resolve-path id %)))))))))
true (transition/new-transition))))
(defn index-states [state]
(loop [loc (zip/zipper
(constantly true)
state/substates
nil
state)
idx {}]
(if (zip/end? loc)
idx
(let [value (zip/node loc)]
(recur (zip/next loc)
(assoc idx (:id value) value))))))
(defn make-statechart
([state]
(let [state-index (state/new-index {})
state (make-statechart [] (assoc state :id []
:state-index state-index)
state-index
(volatile! 0))]
(state/set-index state-index (index-states state))
state))
([path state state-index entry-order]
(let [order (vswap! entry-order inc)]
(-> (reduce-kv (fn [state id substate]
(assoc-in state [:states id] (make-statechart (conj path id) substate state-index entry-order)))
state
(:states state))
(assoc :id path
:state-index state-index
:order order)
(make-transitions state-index)
(state/new-state)))))