-
Notifications
You must be signed in to change notification settings - Fork 4
/
statechart.cljc
73 lines (70 loc) · 4.05 KB
/
statechart.cljc
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
63
64
65
66
67
68
69
70
71
72
73
(ns com.fulcrologic.statecharts.invocation.statechart
"Support for invoking other statecharts. This support can be added by adding it to the
env's `::sc/invocation-processors`. An invoke element can specify it wants to
run another statechart by specifying the type as :statechart, ::sc/chart, or the official w3 URL for scxml.
The `src` attribute of the `invoke` element must be the name of a machine that is in the
statechart registry (in env as ::sc/statechart-registry).
"
(:require
[clojure.string :as str]
[com.fulcrologic.statecharts :as sc]
[com.fulcrologic.statecharts.environment :as env]
[com.fulcrologic.statecharts.events :as evts]
[com.fulcrologic.statecharts.protocols :as sp]
[taoensso.timbre :as log]))
(defrecord StatechartInvocationProcessor [active-invocations]
sp/InvocationProcessor
(supports-invocation-type? [this typ]
(or
(and (string? typ) (str/starts-with? (str/lower-case typ) "http://www.w3.org/tr/scxml"))
(= typ :statechart)
(= typ ::sc/chart)))
(start-invocation! [this {::sc/keys [event-queue processor statechart-registry working-memory-store]
:as env} {:keys [invokeid src params]}]
(log/trace "Start invocation" invokeid src params)
(let [source-session-id (env/session-id env)
child-session-id (str source-session-id "." invokeid)
statechart (sp/get-statechart statechart-registry src)]
(if-not statechart
(do
(log/error "Invocation failed. No statechart found for src:" src)
(sp/send! event-queue env {:target source-session-id
:sendid child-session-id
:source-session-id child-session-id
:event :error.platform
:data {:message "Could not invoke child chart. Not registered."
:target src}}))
(let [wmem (sp/start! processor env src {::sc/invocation-data params
::sc/session-id child-session-id
::sc/parent-session-id source-session-id
:org.w3.scxml.event/invokeid invokeid})]
(sp/save-working-memory! working-memory-store env child-session-id wmem)))
true))
(stop-invocation! [this {::sc/keys [event-queue] :as env} {:keys [invokeid] :as data}]
(log/trace "Stop invocation" invokeid)
(let [source-session-id (env/session-id env)
child-session-id (str source-session-id "." invokeid)]
(when event-queue
(log/trace "Sending cancel event to invoked child machine")
(sp/send! event-queue env {:target child-session-id
:sendid source-session-id
:source-session-id source-session-id
:event evts/cancel-event}))
true))
(forward-event! [this {::sc/keys [ event-queue] :as env} {:keys [type invokeid event]}]
(log/trace "Forward event " invokeid event)
(let [source-session-id (env/session-id env)
child-session-id (str source-session-id "." invokeid) ]
(when event-queue
(log/trace "sending event on event queue to" child-session-id)
(sp/send! event-queue env {:target child-session-id
:type (or type ::sc/chart)
:sendid child-session-id
:source-session-id source-session-id
:data (or (:data event) {})
:event (:name event)}))
true)))
(defn new-invocation-processor
"Create an invocation processor that can be used with a statechart to start other statecharts."
[]
(->StatechartInvocationProcessor (atom {})))