@lovelace_lol/polymer 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -0
- package/dist/index.d.ts +2603 -0
- package/dist/index.js +1031 -0
- package/dist/test.cjs +1519 -0
- package/dist/worker/agency-worker.js +972 -0
- package/dist/worker/manifest.edn +1 -0
- package/package.json +57 -0
- package/shadow-cljs.edn +173 -0
- package/src/polymer/animation/agency.cljs +84 -0
- package/src/polymer/animation/domain.cljs +110 -0
- package/src/polymer/animation/planner.cljs +88 -0
- package/src/polymer/animation/runtime.cljs +137 -0
- package/src/polymer/animation/scheduler.cljs +178 -0
- package/src/polymer/animation/service.cljs +981 -0
- package/src/polymer/animation/state.cljs +112 -0
- package/src/polymer/blink/agency.cljs +131 -0
- package/src/polymer/blink/planner.cljs +115 -0
- package/src/polymer/blink/scheduler.cljs +90 -0
- package/src/polymer/blink/snippet.cljs +50 -0
- package/src/polymer/blink/state.cljs +102 -0
- package/src/polymer/camera_context/agency.cljs +132 -0
- package/src/polymer/camera_context/domain.cljs +186 -0
- package/src/polymer/camera_context/planner.cljs +50 -0
- package/src/polymer/camera_context/scheduler.cljs +113 -0
- package/src/polymer/camera_context/state.cljs +121 -0
- package/src/polymer/character.cljs +471 -0
- package/src/polymer/conversation/agency.cljs +83 -0
- package/src/polymer/conversation/domain.cljs +35 -0
- package/src/polymer/conversation/effector.cljs +130 -0
- package/src/polymer/conversation/planner.cljs +178 -0
- package/src/polymer/conversation/scheduler.cljs +202 -0
- package/src/polymer/conversation/service.cljs +329 -0
- package/src/polymer/conversation/state.cljs +186 -0
- package/src/polymer/core.cljs +172 -0
- package/src/polymer/eye_head/agency.cljs +75 -0
- package/src/polymer/eye_head/domain.cljs +133 -0
- package/src/polymer/eye_head/goap.cljs +106 -0
- package/src/polymer/eye_head/scheduler.cljs +176 -0
- package/src/polymer/eye_head/service.cljs +259 -0
- package/src/polymer/eye_head/snippet.cljs +92 -0
- package/src/polymer/eye_head/state.cljs +167 -0
- package/src/polymer/gaze/agency.cljs +85 -0
- package/src/polymer/gaze/domain.cljs +211 -0
- package/src/polymer/gaze/goap.cljs +208 -0
- package/src/polymer/gaze/scheduler.cljs +184 -0
- package/src/polymer/gaze/state.cljs +202 -0
- package/src/polymer/gesture/agency.cljs +185 -0
- package/src/polymer/gesture/goap.cljs +461 -0
- package/src/polymer/gesture/scheduler.cljs +122 -0
- package/src/polymer/gesture/snippet.cljs +198 -0
- package/src/polymer/gesture/state.cljs +273 -0
- package/src/polymer/lipsync/agency.cljs +593 -0
- package/src/polymer/lipsync/articulation/jaw.cljs +258 -0
- package/src/polymer/lipsync/articulation/snippet.cljs +605 -0
- package/src/polymer/lipsync/articulation/tongue.cljs +418 -0
- package/src/polymer/lipsync/articulation/visemes.cljs +429 -0
- package/src/polymer/lipsync/goap.cljs +132 -0
- package/src/polymer/lipsync/pronunciation/effector.cljs +51 -0
- package/src/polymer/lipsync/scheduler.cljs +302 -0
- package/src/polymer/lipsync/state.cljs +202 -0
- package/src/polymer/nlp/phonemes.cljs +164 -0
- package/src/polymer/prosodic/agency.cljs +196 -0
- package/src/polymer/prosodic/goap.cljs +122 -0
- package/src/polymer/prosodic/scheduler.cljs +99 -0
- package/src/polymer/prosodic/snippet.cljs +106 -0
- package/src/polymer/prosodic/state.cljs +139 -0
- package/src/polymer/runtime/embody.cljs +117 -0
- package/src/polymer/runtime/embody_wasm.cljs +177 -0
- package/src/polymer/runtime/rust_embody_host.cljs +645 -0
- package/src/polymer/society.cljs +239 -0
- package/src/polymer/stream.cljs +130 -0
- package/src/polymer/transcription/agency.cljs +69 -0
- package/src/polymer/transcription/domain.cljs +68 -0
- package/src/polymer/transcription/effector.cljs +611 -0
- package/src/polymer/transcription/planner.cljs +203 -0
- package/src/polymer/transcription/scheduler.cljs +225 -0
- package/src/polymer/transcription/service.cljs +209 -0
- package/src/polymer/transcription/state.cljs +239 -0
- package/src/polymer/tts/agency.cljs +503 -0
- package/src/polymer/tts/azure.cljs +290 -0
- package/src/polymer/tts/planner.cljs +178 -0
- package/src/polymer/tts/runtime.cljs +624 -0
- package/src/polymer/tts/scheduler.cljs +162 -0
- package/src/polymer/tts/state.cljs +191 -0
- package/src/polymer/worker.cljs +70 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
(ns polymer.gaze.state
|
|
2
|
+
(:require [polymer.gaze.domain :as domain]))
|
|
3
|
+
|
|
4
|
+
;; Gaze state is a local ledger of attention targets and accepted look requests.
|
|
5
|
+
;; It is serializable diagnostic data; high-frequency eye/head execution belongs
|
|
6
|
+
;; in the downstream movement agency that consumes Gaze requests.
|
|
7
|
+
|
|
8
|
+
(def default-config
|
|
9
|
+
{:enabled true
|
|
10
|
+
:eyesEnabled true
|
|
11
|
+
:headEnabled true
|
|
12
|
+
:headFollowEyes true
|
|
13
|
+
:mirrored false
|
|
14
|
+
:smoothFactor 0.25
|
|
15
|
+
:minDelta 0.01
|
|
16
|
+
:transitionDurationMs 300
|
|
17
|
+
:eyeIntensity 1.0
|
|
18
|
+
:headIntensity 0.5
|
|
19
|
+
:coalesceMs 16})
|
|
20
|
+
|
|
21
|
+
(defn input-value
|
|
22
|
+
[input camel-key kebab-key fallback]
|
|
23
|
+
(let [camel (get input camel-key ::missing)
|
|
24
|
+
kebab (get input kebab-key ::missing)]
|
|
25
|
+
(cond
|
|
26
|
+
(not= camel ::missing) camel
|
|
27
|
+
(not= kebab ::missing) kebab
|
|
28
|
+
:else fallback)))
|
|
29
|
+
|
|
30
|
+
(defn normalize-config
|
|
31
|
+
[config]
|
|
32
|
+
(let [input (merge default-config (domain/data-map config))]
|
|
33
|
+
{:enabled (boolean (input-value input :enabled :enabled (:enabled default-config)))
|
|
34
|
+
:eyesEnabled (boolean (input-value input :eyesEnabled :eyes-enabled (:eyesEnabled default-config)))
|
|
35
|
+
:headEnabled (boolean (input-value input :headEnabled :head-enabled (:headEnabled default-config)))
|
|
36
|
+
:headFollowEyes (boolean (input-value input :headFollowEyes :head-follow-eyes (:headFollowEyes default-config)))
|
|
37
|
+
:mirrored (boolean (input-value input :mirrored :mirrored (:mirrored default-config)))
|
|
38
|
+
:smoothFactor (domain/clamp 0 1
|
|
39
|
+
(domain/number-or (input-value input :smoothFactor :smooth-factor nil)
|
|
40
|
+
(:smoothFactor default-config)))
|
|
41
|
+
:minDelta (domain/clamp 0 1
|
|
42
|
+
(domain/number-or (input-value input :minDelta :min-delta nil)
|
|
43
|
+
(:minDelta default-config)))
|
|
44
|
+
:transitionDurationMs (int (domain/clamp 50 3000
|
|
45
|
+
(domain/number-or
|
|
46
|
+
(input-value input :transitionDurationMs :transition-duration-ms nil)
|
|
47
|
+
(:transitionDurationMs default-config))))
|
|
48
|
+
:eyeIntensity (domain/clamp 0 2
|
|
49
|
+
(domain/number-or (input-value input :eyeIntensity :eye-intensity nil)
|
|
50
|
+
(:eyeIntensity default-config)))
|
|
51
|
+
:headIntensity (domain/clamp 0 2
|
|
52
|
+
(domain/number-or (input-value input :headIntensity :head-intensity nil)
|
|
53
|
+
(:headIntensity default-config)))
|
|
54
|
+
:coalesceMs (int (domain/clamp 0 1000
|
|
55
|
+
(domain/number-or (input-value input :coalesceMs :coalesce-ms nil)
|
|
56
|
+
(:coalesceMs default-config))))}))
|
|
57
|
+
|
|
58
|
+
(defn default-state
|
|
59
|
+
[config]
|
|
60
|
+
{:agency "gaze"
|
|
61
|
+
:status "idle"
|
|
62
|
+
:mode "manual"
|
|
63
|
+
:active false
|
|
64
|
+
:rawTarget domain/zero-target
|
|
65
|
+
:target domain/zero-target
|
|
66
|
+
:baseTarget domain/zero-target
|
|
67
|
+
:cameraRelativeOffset domain/zero-target
|
|
68
|
+
:lastCameraFact nil
|
|
69
|
+
:lastRequestedTarget domain/zero-target
|
|
70
|
+
:pendingRequest nil
|
|
71
|
+
:lastRequest nil
|
|
72
|
+
:lastIgnored nil
|
|
73
|
+
:lastPlan nil
|
|
74
|
+
:lastEvent nil
|
|
75
|
+
:receivedCount 0
|
|
76
|
+
:plannedCount 0
|
|
77
|
+
:requestedCount 0
|
|
78
|
+
:ignoredCount 0
|
|
79
|
+
:resetCount 0
|
|
80
|
+
:cancelCount 0
|
|
81
|
+
:config (normalize-config config)})
|
|
82
|
+
|
|
83
|
+
(defn config->state
|
|
84
|
+
[config]
|
|
85
|
+
(default-state config))
|
|
86
|
+
|
|
87
|
+
(defn visible-state
|
|
88
|
+
[state]
|
|
89
|
+
(clj->js state))
|
|
90
|
+
|
|
91
|
+
(defn configure
|
|
92
|
+
[state config]
|
|
93
|
+
(assoc state :config (normalize-config (merge (:config state)
|
|
94
|
+
(domain/data-map config)))))
|
|
95
|
+
|
|
96
|
+
(defn reset-state
|
|
97
|
+
[state]
|
|
98
|
+
(default-state (:config state)))
|
|
99
|
+
|
|
100
|
+
(defn set-mode
|
|
101
|
+
[state mode now-ms]
|
|
102
|
+
(assoc state
|
|
103
|
+
:mode (or mode "manual")
|
|
104
|
+
:lastEvent {:type "gaze.status"
|
|
105
|
+
:status (:status state)
|
|
106
|
+
:mode (or mode "manual")
|
|
107
|
+
:at now-ms}))
|
|
108
|
+
|
|
109
|
+
(defn set-active
|
|
110
|
+
[state active now-ms]
|
|
111
|
+
(assoc state
|
|
112
|
+
:active (boolean active)
|
|
113
|
+
:lastEvent {:type "gaze.status"
|
|
114
|
+
:status (:status state)
|
|
115
|
+
:active (boolean active)
|
|
116
|
+
:at now-ms}))
|
|
117
|
+
|
|
118
|
+
(defn set-enabled
|
|
119
|
+
[state enabled now-ms]
|
|
120
|
+
(assoc-in (assoc state
|
|
121
|
+
:lastEvent {:type "gaze.status"
|
|
122
|
+
:status (if enabled "enabled" "disabled")
|
|
123
|
+
:at now-ms})
|
|
124
|
+
[:config :enabled]
|
|
125
|
+
(boolean enabled)))
|
|
126
|
+
|
|
127
|
+
(defn record-plan
|
|
128
|
+
[state plan]
|
|
129
|
+
(-> state
|
|
130
|
+
(assoc :status "planning"
|
|
131
|
+
:rawTarget (:rawTarget plan)
|
|
132
|
+
:target (:target plan)
|
|
133
|
+
:baseTarget (or (:baseTarget plan) (:target plan))
|
|
134
|
+
:cameraRelativeOffset (or (:cameraRelativeOffset plan)
|
|
135
|
+
(:cameraRelativeOffset state))
|
|
136
|
+
:lastCameraFact (or (:cameraFact plan)
|
|
137
|
+
(:lastCameraFact state))
|
|
138
|
+
:lastPlan plan
|
|
139
|
+
:lastEvent {:type "gaze.targetPlanned"
|
|
140
|
+
:requestId (:requestId plan)
|
|
141
|
+
:at (:createdAt plan)})
|
|
142
|
+
(update :receivedCount inc)
|
|
143
|
+
(update :plannedCount inc)))
|
|
144
|
+
|
|
145
|
+
(defn record-pending
|
|
146
|
+
[state request]
|
|
147
|
+
(assoc state
|
|
148
|
+
:status "pending"
|
|
149
|
+
:pendingRequest request
|
|
150
|
+
:lastEvent {:type "gaze.requestQueued"
|
|
151
|
+
:requestId (:requestId request)
|
|
152
|
+
:at (:queuedAt request)}))
|
|
153
|
+
|
|
154
|
+
(defn record-requested
|
|
155
|
+
[state request published-at]
|
|
156
|
+
(-> state
|
|
157
|
+
(assoc :status "requested"
|
|
158
|
+
:pendingRequest nil
|
|
159
|
+
:lastRequest (assoc request :publishedAt published-at)
|
|
160
|
+
:lastRequestedTarget (:target request)
|
|
161
|
+
:lastEvent {:type "eyeHeadTracking.requestGaze"
|
|
162
|
+
:requestId (:requestId request)
|
|
163
|
+
:at published-at})
|
|
164
|
+
(update :requestedCount inc)))
|
|
165
|
+
|
|
166
|
+
(defn record-ignored
|
|
167
|
+
[state ignored]
|
|
168
|
+
(-> state
|
|
169
|
+
(assoc :status "ignored"
|
|
170
|
+
:lastIgnored ignored
|
|
171
|
+
:lastEvent {:type "gaze.targetIgnored"
|
|
172
|
+
:reason (:reason ignored)
|
|
173
|
+
:requestId (:requestId ignored)
|
|
174
|
+
:at (:ignoredAt ignored)})
|
|
175
|
+
(update :ignoredCount inc)))
|
|
176
|
+
|
|
177
|
+
(defn record-reset
|
|
178
|
+
[state request]
|
|
179
|
+
(-> state
|
|
180
|
+
(assoc :status "reset"
|
|
181
|
+
:rawTarget domain/zero-target
|
|
182
|
+
:target domain/zero-target
|
|
183
|
+
:baseTarget domain/zero-target
|
|
184
|
+
:cameraRelativeOffset domain/zero-target
|
|
185
|
+
:lastCameraFact nil
|
|
186
|
+
:lastRequestedTarget domain/zero-target
|
|
187
|
+
:pendingRequest nil
|
|
188
|
+
:lastRequest request
|
|
189
|
+
:lastEvent {:type "eyeHeadTracking.requestReset"
|
|
190
|
+
:requestId (:requestId request)
|
|
191
|
+
:at (:requestedAt request)})
|
|
192
|
+
(update :resetCount inc)))
|
|
193
|
+
|
|
194
|
+
(defn record-cancel
|
|
195
|
+
[state request]
|
|
196
|
+
(-> state
|
|
197
|
+
(assoc :status "cancelled"
|
|
198
|
+
:pendingRequest nil
|
|
199
|
+
:lastEvent {:type "eyeHeadTracking.requestCancel"
|
|
200
|
+
:requestId (:requestId request)
|
|
201
|
+
:at (:requestedAt request)})
|
|
202
|
+
(update :cancelCount inc)))
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
(ns polymer.gesture.agency
|
|
2
|
+
(:require [polymer.gesture.goap :as goap]
|
|
3
|
+
[polymer.gesture.scheduler :as scheduler]
|
|
4
|
+
[polymer.gesture.snippet :as snippet]
|
|
5
|
+
[polymer.gesture.state :as state]
|
|
6
|
+
[polymer.stream :as stream]))
|
|
7
|
+
|
|
8
|
+
;; Gesture consumes authored arm/hand gesture snapshots and emits animation
|
|
9
|
+
;; intent. It does not own host persistence, host UI state, scene bones, or the
|
|
10
|
+
;; animation runtime.
|
|
11
|
+
|
|
12
|
+
(defn js-command [type value]
|
|
13
|
+
#js {:type type :value value})
|
|
14
|
+
|
|
15
|
+
(defn plan-error-message [plan]
|
|
16
|
+
(let [step (or (some #(when (= "fail" (:op %)) %) (:steps plan))
|
|
17
|
+
(first (:steps plan)))]
|
|
18
|
+
(case (:reason step)
|
|
19
|
+
"unsupported-command" (str "Gesture plan failed: unsupported command " (:commandType step))
|
|
20
|
+
"missing-emoji" "Gesture playEmoji command requires emoji"
|
|
21
|
+
"missing-gesture" "Gesture command requires gestureId"
|
|
22
|
+
"missing-goal" "Gesture goal command requires a gesture goal, intent, tag, scope, emoji, or effector constraint"
|
|
23
|
+
"unknown-gesture" (str "Unknown gesture: " (:gestureId step))
|
|
24
|
+
"gesture-has-no-motion" (str "Gesture has no bone motion: " (:gestureId step))
|
|
25
|
+
"empty-library" "Gesture plan failed: gesture library is empty"
|
|
26
|
+
"no-gesture-candidate" "Gesture plan failed: no gesture matched the goal"
|
|
27
|
+
(str "Gesture plan failed: " (:reason step)))))
|
|
28
|
+
|
|
29
|
+
(defn should-emit-plan? [plan]
|
|
30
|
+
(or (false? (:ok plan))
|
|
31
|
+
(not (:noop plan))
|
|
32
|
+
(contains? goap/playable-command-types (get-in plan [:goal :type]))))
|
|
33
|
+
|
|
34
|
+
(defn public-plan [plan]
|
|
35
|
+
(-> plan
|
|
36
|
+
(dissoc :gesture)
|
|
37
|
+
(update :goal dissoc :gesture :activeSnippets :config)))
|
|
38
|
+
|
|
39
|
+
(defn create-gesture-agency [config]
|
|
40
|
+
(let [input-stream (stream/create-stream)
|
|
41
|
+
event-stream (stream/create-stream)
|
|
42
|
+
state-atom (atom (state/config->state config))
|
|
43
|
+
disposed? (atom false)
|
|
44
|
+
agency-scheduler (atom nil)
|
|
45
|
+
emit-input (:emit input-stream)
|
|
46
|
+
emit-event (:emit event-stream)]
|
|
47
|
+
(letfn [(complete-active! [name]
|
|
48
|
+
(when (get-in @state-atom [:activeSnippets name])
|
|
49
|
+
(remove-active! [name] "completed")))
|
|
50
|
+
|
|
51
|
+
(emit-plan! [plan]
|
|
52
|
+
(when (should-emit-plan? plan)
|
|
53
|
+
(emit-event {:type "gesturePlanCreated"
|
|
54
|
+
:agency "gesture"
|
|
55
|
+
:plan (public-plan plan)})))
|
|
56
|
+
|
|
57
|
+
(remove-active! [names reason]
|
|
58
|
+
(let [removed-at (state/now-ms)]
|
|
59
|
+
((:remove-many @agency-scheduler) names reason)
|
|
60
|
+
(doseq [name names]
|
|
61
|
+
(swap! state-atom state/record-remove name reason removed-at)
|
|
62
|
+
(emit-event {:type "gestureRemoved"
|
|
63
|
+
:agency "gesture"
|
|
64
|
+
:name name
|
|
65
|
+
:reason reason
|
|
66
|
+
:removedAt removed-at}))))
|
|
67
|
+
|
|
68
|
+
(schedule-gesture! [gesture context]
|
|
69
|
+
(let [context (or context {})
|
|
70
|
+
snippet-data (snippet/build-gesture-snippet gesture
|
|
71
|
+
(:config @state-atom)
|
|
72
|
+
context)]
|
|
73
|
+
(if snippet-data
|
|
74
|
+
(do
|
|
75
|
+
((:schedule @agency-scheduler) snippet-data {:autoPlay true})
|
|
76
|
+
(let [scheduled-at (state/now-ms)]
|
|
77
|
+
(swap! state-atom state/record-schedule gesture snippet-data scheduled-at)
|
|
78
|
+
(emit-event {:type "gestureScheduled"
|
|
79
|
+
:agency "gesture"
|
|
80
|
+
:gestureId (:id gesture)
|
|
81
|
+
:gestureName (:name gesture)
|
|
82
|
+
:emoji (:emoji gesture)
|
|
83
|
+
:scope (:scope gesture)
|
|
84
|
+
:affectedBones (:affectedBones gesture)
|
|
85
|
+
:name (:name snippet-data)
|
|
86
|
+
:trigger (:trigger context)
|
|
87
|
+
:intent (:intent context)
|
|
88
|
+
:scheduledAt scheduled-at}))
|
|
89
|
+
snippet-data)
|
|
90
|
+
(emit-event {:type "error"
|
|
91
|
+
:agency "gesture"
|
|
92
|
+
:message (str "Gesture produced no animation channels: " (:id gesture))}))))
|
|
93
|
+
|
|
94
|
+
(dispatch! [command]
|
|
95
|
+
(when-not @disposed?
|
|
96
|
+
(let [payload (state/js-data command)
|
|
97
|
+
type (:type payload)
|
|
98
|
+
now (state/now-ms)
|
|
99
|
+
plan (goap/plan-command payload @state-atom now)]
|
|
100
|
+
(emit-input {:type "command"
|
|
101
|
+
:agency "gesture"
|
|
102
|
+
:command payload})
|
|
103
|
+
(emit-plan! plan)
|
|
104
|
+
(if (false? (:ok plan))
|
|
105
|
+
(emit-event {:type "error"
|
|
106
|
+
:agency "gesture"
|
|
107
|
+
:message (plan-error-message plan)})
|
|
108
|
+
(case type
|
|
109
|
+
"configure"
|
|
110
|
+
(do
|
|
111
|
+
(swap! state-atom state/configure (:config payload))
|
|
112
|
+
(emit-event {:type "gestureConfigChanged"
|
|
113
|
+
:agency "gesture"
|
|
114
|
+
:state (state/visible-state-map @state-atom)}))
|
|
115
|
+
|
|
116
|
+
"loadGestures"
|
|
117
|
+
(let [loaded-at (state/now-ms)]
|
|
118
|
+
(swap! state-atom state/load-gestures
|
|
119
|
+
(or (:gestures payload)
|
|
120
|
+
(:characterGestures payload)
|
|
121
|
+
(:gestureLibrary payload))
|
|
122
|
+
(or (:emojiMappings payload) (:gestureEmojiMappings payload))
|
|
123
|
+
loaded-at)
|
|
124
|
+
(emit-event {:type "gestureLibraryUpdated"
|
|
125
|
+
:agency "gesture"
|
|
126
|
+
:gestureCount (count (:gestures @state-atom))
|
|
127
|
+
:emojiCount (count (:emojiMappings @state-atom))
|
|
128
|
+
:updatedAt loaded-at}))
|
|
129
|
+
|
|
130
|
+
("playGesture" "playEmoji" "gesture.goal" "performGestureGoal" "playGoal")
|
|
131
|
+
(when-not (:noop plan)
|
|
132
|
+
(doseq [step (:steps plan)]
|
|
133
|
+
(when (= "remove-active-gestures" (:op step))
|
|
134
|
+
(remove-active! (:names step) (:reason step))))
|
|
135
|
+
(schedule-gesture! (:gesture plan) (merge payload (:context plan))))
|
|
136
|
+
|
|
137
|
+
"stopGesture"
|
|
138
|
+
(remove-active! (:removeNames plan) (:removeReason plan))
|
|
139
|
+
|
|
140
|
+
"stopAll"
|
|
141
|
+
(remove-active! (:removeNames plan) (:removeReason plan))
|
|
142
|
+
|
|
143
|
+
"reset"
|
|
144
|
+
(do
|
|
145
|
+
(remove-active! (:removeNames plan) (:removeReason plan))
|
|
146
|
+
(reset! state-atom (state/config->state nil))
|
|
147
|
+
(emit-event {:type "gestureConfigChanged"
|
|
148
|
+
:agency "gesture"
|
|
149
|
+
:state (state/visible-state-map @state-atom)}))
|
|
150
|
+
|
|
151
|
+
(emit-event {:type "error"
|
|
152
|
+
:agency "gesture"
|
|
153
|
+
:message (str "Unknown Gesture command: " type)}))))))]
|
|
154
|
+
(reset! agency-scheduler
|
|
155
|
+
(scheduler/create-scheduler
|
|
156
|
+
{:emit-event emit-event
|
|
157
|
+
:on-complete complete-active!}))
|
|
158
|
+
#js {:dispatch dispatch!
|
|
159
|
+
:snapshot (fn [] (state/visible-state @state-atom))
|
|
160
|
+
:schedulerQueue (fn [] (clj->js ((:queue @agency-scheduler))))
|
|
161
|
+
:input (stream/writable-port input-stream dispatch!)
|
|
162
|
+
:events (stream/readable-port event-stream)
|
|
163
|
+
:subscribeInput (fn [listener] ((:subscribe input-stream) listener))
|
|
164
|
+
:subscribeEvents (fn [listener] ((:subscribe event-stream) listener))
|
|
165
|
+
:subscribe (fn [listener] ((:subscribe event-stream) listener))
|
|
166
|
+
:subscribeStatus (fn [listener] ((:subscribe event-stream) listener))
|
|
167
|
+
:configure (fn [next-config] (dispatch! #js {:type "configure" :config next-config}))
|
|
168
|
+
:loadGestures (fn
|
|
169
|
+
([gestures] (dispatch! #js {:type "loadGestures" :gestures gestures}))
|
|
170
|
+
([gestures emoji-mappings]
|
|
171
|
+
(dispatch! #js {:type "loadGestures"
|
|
172
|
+
:gestures gestures
|
|
173
|
+
:emojiMappings emoji-mappings})))
|
|
174
|
+
:playGesture (fn [gesture-id] (dispatch! #js {:type "playGesture" :gestureId gesture-id}))
|
|
175
|
+
:playEmoji (fn [emoji] (dispatch! #js {:type "playEmoji" :emoji emoji}))
|
|
176
|
+
:performGoal (fn [goal] (dispatch! #js {:type "gesture.goal" :goal goal}))
|
|
177
|
+
:stopGesture (fn [gesture-id] (dispatch! #js {:type "stopGesture" :gestureId gesture-id}))
|
|
178
|
+
:stopAll (fn [] (dispatch! #js {:type "stopAll"}))
|
|
179
|
+
:reset (fn [] (dispatch! #js {:type "reset"}))
|
|
180
|
+
:dispose (fn []
|
|
181
|
+
(when-not @disposed?
|
|
182
|
+
(reset! disposed? true)
|
|
183
|
+
((:dispose @agency-scheduler))
|
|
184
|
+
((:dispose input-stream))
|
|
185
|
+
((:dispose event-stream))))})))
|