@benev/tact 0.3.0-5 → 0.4.0-0

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.
Files changed (504) hide show
  1. package/README.md +72 -53
  2. package/package.json +18 -20
  3. package/s/_archive/deck/deck.ts +76 -53
  4. package/s/_archive/demo/demo-app/element.ts +17 -0
  5. package/s/_archive/{deck/views/bindings → demo/demo-app}/style.css.ts +4 -0
  6. package/s/_archive/demo/main.bundle.ts +67 -6
  7. package/s/_archive/demo/main.css +6 -8
  8. package/s/_archive/lib/bindings/resolver.ts +61 -0
  9. package/s/_archive/lib/bindings/types.ts +67 -0
  10. package/s/_archive/lib/bindings/utils/action-resolver.ts +51 -0
  11. package/s/_archive/lib/bindings/utils/evaluator.ts +162 -0
  12. package/s/_archive/lib/bindings/utils/hash-bindings.ts +22 -0
  13. package/s/_archive/lib/bindings/utils/intent-coding.ts +50 -0
  14. package/s/_archive/lib/bindings/utils/intent-resolver.ts +52 -0
  15. package/s/_archive/lib/bindings/utils/investigate.ts +47 -0
  16. package/s/_archive/lib/bindings/utils/is-expression.ts +11 -0
  17. package/s/_archive/lib/index.ts +12 -0
  18. package/s/_archive/lib/sampling/sources/example.ts +7 -0
  19. package/s/_archive/lib/sampling/sources/gamepad.ts +63 -0
  20. package/s/_archive/lib/sampling/sources/keyboard.ts +52 -0
  21. package/s/_archive/lib/sampling/sources/pointer.ts +56 -0
  22. package/s/_archive/lib/sampling/sources/sources.ts +13 -0
  23. package/s/_archive/lib/sampling/sources/stick.ts +27 -0
  24. package/s/_archive/lib/sampling/types.ts +11 -0
  25. package/s/_archive/lib/sampling/utils/add-sample.ts +12 -0
  26. package/s/_archive/lib/test.ts +57 -0
  27. package/s/_archive/lib/utils/backwards.ts +6 -0
  28. package/s/_archive/lib/utils/mouse-button.ts +10 -0
  29. package/s/_archive/lib/utils/pad/on-pad.ts +50 -0
  30. package/s/_archive/lib/utils/pad/pad.ts +10 -0
  31. package/s/_archive/lib2/core/decoder/decoder.ts +34 -0
  32. package/s/_archive/lib2/core/decoder/utils/update-input.ts +21 -0
  33. package/s/_archive/lib2/core/encoder/encoder.ts +60 -0
  34. package/s/_archive/lib2/core/encoder/evaluate/context.ts +22 -0
  35. package/s/_archive/lib2/core/encoder/evaluate/evaluate.ts +144 -0
  36. package/s/_archive/lib2/core/encoder/parts/expression-index.ts +27 -0
  37. package/s/_archive/lib2/core/encoder/parts/hash-bindings.ts +22 -0
  38. package/s/_archive/lib2/core/encoder/parts/investigate.ts +50 -0
  39. package/s/_archive/lib2/core/encoder/parts/sampler.ts +22 -0
  40. package/s/_archive/lib2/core/sources/example.ts +9 -0
  41. package/s/_archive/lib2/core/sources/sources.ts +16 -0
  42. package/s/_archive/lib2/core/types.ts +78 -0
  43. package/s/_archive/lib2/core/utils/data.ts +50 -0
  44. package/s/_archive/lib2/core/utils/is-down.ts +5 -0
  45. package/s/_archive/lib2/core/utils/is-expression.ts +11 -0
  46. package/s/_archive/lib3/input/data/decode.ts +25 -0
  47. package/s/_archive/lib3/input/data/encode.ts +24 -0
  48. package/s/_archive/lib3/input/data/params.ts +7 -0
  49. package/s/_archive/lib3/input/decoder.ts +56 -0
  50. package/s/_archive/lib3/input/encoder.ts +99 -0
  51. package/s/_archive/lib3/input/evaluate/context.ts +15 -0
  52. package/s/_archive/lib3/input/evaluate/evaluate.ts +142 -0
  53. package/s/_archive/lib3/input/evaluate/utils/clock.ts +14 -0
  54. package/s/_archive/lib3/input/investigate/hash-bindings.ts +22 -0
  55. package/s/_archive/lib3/input/investigate/investigate.ts +42 -0
  56. package/s/_archive/lib3/input/investigate/is-expression.ts +11 -0
  57. package/s/_archive/lib3/input/investigate/make-input.ts +18 -0
  58. package/s/_archive/lib3/input/investigate/root-index.ts +26 -0
  59. package/s/_archive/lib3/input/mixer.ts +20 -0
  60. package/s/_archive/lib3/input/sources/gamepad.ts +58 -0
  61. package/s/_archive/lib3/input/sources/keyboard.ts +49 -0
  62. package/s/_archive/lib3/input/sources/plain.ts +9 -0
  63. package/s/_archive/lib3/input/sources/pointer.ts +58 -0
  64. package/s/_archive/lib3/input/sources/sources.ts +24 -0
  65. package/s/_archive/lib3/input/sources/stick.ts +29 -0
  66. package/s/_archive/lib3/input/testing/quickbind.ts +20 -0
  67. package/s/_archive/lib3/input/types.ts +96 -0
  68. package/s/_archive/lib3/input/utils/evergreen.ts +10 -0
  69. package/s/_archive/lib3/input/utils/is-down.ts +5 -0
  70. package/s/_archive/lib3/input/utils/mouse-button.ts +10 -0
  71. package/s/_archive/lib3/input/utils/pad/on-pad.ts +50 -0
  72. package/s/_archive/lib3/input/utils/pad/pad.ts +10 -0
  73. package/s/_archive/lib3/input/utils/sampler.ts +28 -0
  74. package/s/_archive/lib3/input/utils/split-axis.ts +15 -0
  75. package/s/_archive/lib3/test.ts +100 -0
  76. package/s/_archive/lib4/input/data/decode.ts +25 -0
  77. package/s/_archive/lib4/input/data/encode.ts +24 -0
  78. package/s/_archive/lib4/input/data/params.ts +7 -0
  79. package/s/_archive/lib4/input/encoder.ts +100 -0
  80. package/s/_archive/lib4/input/evaluate/context.ts +16 -0
  81. package/s/_archive/lib4/input/evaluate/evaluate.ts +157 -0
  82. package/s/_archive/lib4/input/evaluate/utils/clock.ts +14 -0
  83. package/s/_archive/lib4/input/investigate/hash-bindings.ts +22 -0
  84. package/s/_archive/lib4/input/investigate/investigate.ts +37 -0
  85. package/s/_archive/lib4/input/investigate/is.ts +19 -0
  86. package/s/_archive/lib4/input/investigate/make-input.ts +18 -0
  87. package/s/_archive/lib4/input/investigate/root-index.ts +26 -0
  88. package/s/_archive/lib4/input/sources/gamepad.ts +58 -0
  89. package/s/_archive/lib4/input/sources/keyboard.ts +46 -0
  90. package/s/_archive/lib4/input/sources/plain.ts +9 -0
  91. package/s/_archive/lib4/input/sources/pointer.ts +50 -0
  92. package/s/_archive/lib4/input/sources/sources.ts +24 -0
  93. package/s/_archive/lib4/input/sources/stick.ts +25 -0
  94. package/s/_archive/lib4/input/types.ts +102 -0
  95. package/s/_archive/lib4/input/utils/evergreen.ts +10 -0
  96. package/s/_archive/lib4/input/utils/is-down.ts +5 -0
  97. package/s/_archive/lib4/input/utils/mouse-button.ts +10 -0
  98. package/s/_archive/lib4/input/utils/pad/on-pad.ts +50 -0
  99. package/s/_archive/lib4/input/utils/pad/pad.ts +10 -0
  100. package/s/_archive/lib4/input/utils/sampler.ts +28 -0
  101. package/s/_archive/lib4/input/utils/split-axis.ts +15 -0
  102. package/s/_archive/lib4/test.ts +12 -0
  103. package/s/_archive/utils/circular-clamp.ts +2 -2
  104. package/s/_archive/utils/is-down.ts +5 -0
  105. package/s/demo/demo-app/element.ts +2 -4
  106. package/s/demo/main.bundle.ts +2 -65
  107. package/s/gamepad/gamepad-app/element.ts +14 -11
  108. package/s/lib/index.ts +18 -0
  109. package/s/lib/input/data/decode.ts +25 -0
  110. package/s/lib/input/data/encode.ts +24 -0
  111. package/s/lib/input/data/params.ts +7 -0
  112. package/s/lib/input/decoder.ts +40 -0
  113. package/s/lib/input/encoder.ts +64 -0
  114. package/s/lib/input/evaluate/context.ts +17 -0
  115. package/s/lib/input/evaluate/evaluate.ts +199 -0
  116. package/s/lib/input/expression.ts +44 -0
  117. package/s/lib/input/investigate/hash-bindings.ts +22 -0
  118. package/s/lib/input/investigate/investigate.ts +35 -0
  119. package/s/lib/input/investigate/is-compatible.ts +8 -0
  120. package/s/lib/input/investigate/is-expression.ts +12 -0
  121. package/s/lib/input/investigate/make-input.ts +11 -0
  122. package/s/lib/input/sources/gamepad.ts +55 -0
  123. package/s/lib/input/sources/keyboard.ts +46 -0
  124. package/s/lib/input/sources/plain.ts +9 -0
  125. package/s/lib/input/sources/pointer.ts +56 -0
  126. package/s/lib/input/sources/sources.ts +24 -0
  127. package/s/lib/input/sources/stick.ts +32 -0
  128. package/s/lib/input/testing/quickbind.ts +20 -0
  129. package/s/lib/input/types.ts +52 -0
  130. package/s/lib/input/utils/clock.ts +14 -0
  131. package/s/lib/input/utils/evergreen.ts +10 -0
  132. package/s/lib/input/utils/is-down.ts +5 -0
  133. package/s/lib/input/utils/mouse-button.ts +10 -0
  134. package/s/lib/input/utils/pad/on-pad.ts +50 -0
  135. package/s/lib/input/utils/pad/pad.ts +10 -0
  136. package/s/lib/input/utils/sampler.ts +28 -0
  137. package/s/lib/input/utils/split-axis.ts +15 -0
  138. package/s/lib/test.ts +180 -0
  139. package/x/_archive/demo/main.css +6 -8
  140. package/x/demo/demo-app/element.d.ts +1 -3
  141. package/x/demo/demo-app/element.js +2 -3
  142. package/x/demo/demo-app/element.js.map +1 -1
  143. package/x/demo/main.bundle.js +1 -50
  144. package/x/demo/main.bundle.js.map +1 -1
  145. package/x/demo/main.bundle.min.js +9 -134
  146. package/x/demo/main.bundle.min.js.map +4 -4
  147. package/x/gamepad/gamepad-app/element.js +12 -10
  148. package/x/gamepad/gamepad-app/element.js.map +1 -1
  149. package/x/gamepad/index.html +2 -2
  150. package/x/gamepad/main.bundle.min.js +9 -9
  151. package/x/gamepad/main.bundle.min.js.map +4 -4
  152. package/x/index.html +2 -2
  153. package/x/lib/index.d.ts +13 -0
  154. package/x/lib/index.js +14 -0
  155. package/x/lib/index.js.map +1 -0
  156. package/x/lib/input/data/decode.d.ts +5 -0
  157. package/x/lib/input/data/decode.js +17 -0
  158. package/x/lib/input/data/decode.js.map +1 -0
  159. package/x/lib/input/data/encode.d.ts +2 -0
  160. package/x/lib/input/data/encode.js +17 -0
  161. package/x/lib/input/data/encode.js.map +1 -0
  162. package/x/lib/input/data/params.d.ts +5 -0
  163. package/x/lib/input/data/params.js +6 -0
  164. package/x/lib/input/data/params.js.map +1 -0
  165. package/x/lib/input/decoder.d.ts +7 -0
  166. package/x/lib/input/decoder.js +31 -0
  167. package/x/lib/input/decoder.js.map +1 -0
  168. package/x/lib/input/encoder.d.ts +10 -0
  169. package/x/lib/input/encoder.js +49 -0
  170. package/x/lib/input/encoder.js.map +1 -0
  171. package/x/lib/input/evaluate/context.d.ts +16 -0
  172. package/x/lib/input/evaluate/context.js +12 -0
  173. package/x/lib/input/evaluate/context.js.map +1 -0
  174. package/x/lib/input/evaluate/evaluate.d.ts +3 -0
  175. package/x/lib/input/evaluate/evaluate.js +147 -0
  176. package/x/lib/input/evaluate/evaluate.js.map +1 -0
  177. package/x/lib/input/expression.d.ts +1 -0
  178. package/x/lib/input/expression.js +2 -0
  179. package/x/lib/input/expression.js.map +1 -0
  180. package/x/lib/input/investigate/hash-bindings.d.ts +2 -0
  181. package/x/lib/input/investigate/hash-bindings.js +17 -0
  182. package/x/lib/input/investigate/hash-bindings.js.map +1 -0
  183. package/x/lib/input/investigate/investigate.d.ts +8 -0
  184. package/x/lib/input/investigate/investigate.js +28 -0
  185. package/x/lib/input/investigate/investigate.js.map +1 -0
  186. package/x/lib/input/investigate/is-compatible.d.ts +2 -0
  187. package/x/lib/input/investigate/is-compatible.js +5 -0
  188. package/x/lib/input/investigate/is-compatible.js.map +1 -0
  189. package/x/lib/input/investigate/is-expression.d.ts +3 -0
  190. package/x/lib/input/investigate/is-expression.js +11 -0
  191. package/x/lib/input/investigate/is-expression.js.map +1 -0
  192. package/x/lib/input/investigate/make-input.d.ts +2 -0
  193. package/x/lib/input/investigate/make-input.js +8 -0
  194. package/x/lib/input/investigate/make-input.js.map +1 -0
  195. package/x/lib/input/sources/gamepad.d.ts +9 -0
  196. package/x/lib/input/sources/gamepad.js +45 -0
  197. package/x/lib/input/sources/gamepad.js.map +1 -0
  198. package/x/lib/input/sources/keyboard.d.ts +5 -0
  199. package/x/lib/input/sources/keyboard.js +36 -0
  200. package/x/lib/input/sources/keyboard.js.map +1 -0
  201. package/x/lib/input/sources/plain.d.ts +5 -0
  202. package/x/lib/input/sources/plain.js +6 -0
  203. package/x/lib/input/sources/plain.js.map +1 -0
  204. package/x/lib/input/sources/pointer.d.ts +7 -0
  205. package/x/lib/input/sources/pointer.js +54 -0
  206. package/x/lib/input/sources/pointer.js.map +1 -0
  207. package/x/lib/input/sources/sources.d.ts +7 -0
  208. package/x/lib/input/sources/sources.js +15 -0
  209. package/x/lib/input/sources/sources.js.map +1 -0
  210. package/x/lib/input/sources/stick.d.ts +10 -0
  211. package/x/lib/input/sources/stick.js +25 -0
  212. package/x/lib/input/sources/stick.js.map +1 -0
  213. package/x/lib/input/testing/quickbind.d.ts +11 -0
  214. package/x/lib/input/testing/quickbind.js +12 -0
  215. package/x/lib/input/testing/quickbind.js.map +1 -0
  216. package/x/lib/input/types.d.ts +37 -0
  217. package/x/lib/input/types.js +2 -0
  218. package/x/lib/input/types.js.map +1 -0
  219. package/x/lib/input/utils/clock.d.ts +7 -0
  220. package/x/lib/input/utils/clock.js +14 -0
  221. package/x/lib/input/utils/clock.js.map +1 -0
  222. package/x/lib/input/utils/evergreen.js.map +1 -0
  223. package/x/lib/input/utils/is-down.js.map +1 -0
  224. package/x/lib/input/utils/mouse-button.d.ts +1 -0
  225. package/x/lib/input/utils/mouse-button.js +9 -0
  226. package/x/lib/input/utils/mouse-button.js.map +1 -0
  227. package/x/lib/input/utils/pad/on-pad.js.map +1 -0
  228. package/x/lib/input/utils/pad/pad.js.map +1 -0
  229. package/x/lib/input/utils/sampler.d.ts +7 -0
  230. package/x/lib/input/utils/sampler.js +23 -0
  231. package/x/lib/input/utils/sampler.js.map +1 -0
  232. package/x/lib/input/utils/split-axis.js.map +1 -0
  233. package/x/lib/test.d.ts +1 -0
  234. package/x/lib/test.js +134 -0
  235. package/x/lib/test.js.map +1 -0
  236. package/s/_archive/README.md +0 -435
  237. package/s/_archive/core/bindings/action.ts +0 -30
  238. package/s/_archive/core/bindings/parts/defaults.ts +0 -32
  239. package/s/_archive/core/bindings/parts/is-pressed.ts +0 -5
  240. package/s/_archive/core/bindings/parts/lens-algo.ts +0 -84
  241. package/s/_archive/core/bindings/parts/lookup-proxies.ts +0 -17
  242. package/s/_archive/core/bindings/resolver.ts +0 -103
  243. package/s/_archive/core/bindings/sample-map.ts +0 -25
  244. package/s/_archive/core/bindings/types.ts +0 -60
  245. package/s/_archive/core/core.test.ts +0 -155
  246. package/s/_archive/core/devices/auto-gamepads.ts +0 -8
  247. package/s/_archive/core/devices/device.ts +0 -12
  248. package/s/_archive/core/devices/infra/group.ts +0 -24
  249. package/s/_archive/core/devices/infra/sampler.ts +0 -22
  250. package/s/_archive/core/devices/standard/gamepad.ts +0 -83
  251. package/s/_archive/core/devices/standard/index.ts +0 -8
  252. package/s/_archive/core/devices/standard/keyboard.ts +0 -31
  253. package/s/_archive/core/devices/standard/pointer.ts +0 -97
  254. package/s/_archive/core/devices/standard/primary.ts +0 -20
  255. package/s/_archive/core/devices/standard/stick.ts +0 -27
  256. package/s/_archive/core/devices/standard/vpad.ts +0 -25
  257. package/s/_archive/core/devices/types.ts +0 -3
  258. package/s/_archive/core/hub/hub.ts +0 -118
  259. package/s/_archive/core/hub/meta-bindings.ts +0 -23
  260. package/s/_archive/core/hub/parts/connected.ts +0 -15
  261. package/s/_archive/core/hub/port.ts +0 -26
  262. package/s/_archive/core/hub/types.ts +0 -13
  263. package/s/_archive/core/index.ts +0 -19
  264. package/s/_archive/core/testing/testing.ts +0 -57
  265. package/s/_archive/deck/index.ts +0 -13
  266. package/s/_archive/deck/parts/catalog.ts +0 -58
  267. package/s/_archive/deck/parts/db.ts +0 -65
  268. package/s/_archive/deck/parts/device-skins/device-icons.ts +0 -38
  269. package/s/_archive/deck/parts/device-skins/device-skin.ts +0 -29
  270. package/s/_archive/deck/parts/local-storage-kv.ts +0 -8
  271. package/s/_archive/deck/parts/merge-bindings.ts +0 -21
  272. package/s/_archive/deck/parts/overlay-visibility.ts +0 -49
  273. package/s/_archive/deck/views/bindings/view.ts +0 -95
  274. package/s/_archive/deck/views/overlay/style.css.ts +0 -110
  275. package/s/_archive/deck/views/overlay/view.ts +0 -46
  276. package/s/_archive/demo/game/game.ts +0 -85
  277. package/s/_archive/demo/game/parts/agent.ts +0 -10
  278. package/s/_archive/demo/game/parts/game-bindings.ts +0 -20
  279. package/s/_archive/demo/game/parts/logic.ts +0 -24
  280. package/s/_archive/demo/game/parts/player.ts +0 -32
  281. package/s/_archive/demo/game/parts/renderer.ts +0 -112
  282. package/s/_archive/demo/game/parts/state.ts +0 -23
  283. package/s/_archive/demo/game/parts/virtual-device.ts +0 -13
  284. package/s/_archive/demo/ui/theater/styles.css.ts +0 -57
  285. package/s/_archive/demo/ui/theater/view.ts +0 -55
  286. package/s/_archive/demo/ui/theater/virtual/style.css.ts +0 -43
  287. package/s/_archive/demo/ui/theater/virtual/view.ts +0 -29
  288. package/s/_archive/demo/ui/utils/loader.ts +0 -5
  289. package/s/_archive/index.html.ts +0 -61
  290. package/s/_archive/index.ts +0 -8
  291. package/s/_archive/nubs/index.ts +0 -5
  292. package/s/_archive/nubs/lookpad/styles.ts +0 -21
  293. package/s/_archive/nubs/lookpad/view.ts +0 -39
  294. package/s/_archive/nubs/stick/style.css.ts +0 -70
  295. package/s/_archive/nubs/stick/view.ts +0 -108
  296. package/s/_archive/nubs/vpad/styles.css.ts +0 -134
  297. package/s/_archive/nubs/vpad/utils/gamepad-inputs.ts +0 -42
  298. package/s/_archive/nubs/vpad/utils/prevent-default-touch-shenanigans.ts +0 -12
  299. package/s/_archive/nubs/vpad/utils/touch-tracking.ts +0 -75
  300. package/s/_archive/nubs/vpad/view.ts +0 -141
  301. package/s/_archive/tests.test.ts +0 -6
  302. package/s/_archive/utils/dispensers.ts +0 -20
  303. package/s/_archive/utils/gamepads.ts +0 -41
  304. package/s/_archive/utils/quick-math.ts +0 -13
  305. package/s/deck/deck.ts +0 -92
  306. package/s/index.ts +0 -31
  307. package/s/utils/circular-clamp.ts +0 -14
  308. package/x/core/atom/defaults.d.ts +0 -3
  309. package/x/core/atom/defaults.js +0 -26
  310. package/x/core/atom/defaults.js.map +0 -1
  311. package/x/core/atom/lens-algo.d.ts +0 -2
  312. package/x/core/atom/lens-algo.js +0 -54
  313. package/x/core/atom/lens-algo.js.map +0 -1
  314. package/x/core/atom/types.d.ts +0 -27
  315. package/x/core/atom/types.js +0 -2
  316. package/x/core/atom/types.js.map +0 -1
  317. package/x/core/bindings/normalize.d.ts +0 -2
  318. package/x/core/bindings/normalize.js +0 -17
  319. package/x/core/bindings/normalize.js.map +0 -1
  320. package/x/core/bindings/shape.d.ts +0 -2
  321. package/x/core/bindings/shape.js +0 -10
  322. package/x/core/bindings/shape.js.map +0 -1
  323. package/x/core/bindings/table.d.ts +0 -2
  324. package/x/core/bindings/table.js +0 -15
  325. package/x/core/bindings/table.js.map +0 -1
  326. package/x/core/intent/bucket.d.ts +0 -7
  327. package/x/core/intent/bucket.js +0 -21
  328. package/x/core/intent/bucket.js.map +0 -1
  329. package/x/core/intent/consts.d.ts +0 -2
  330. package/x/core/intent/consts.js +0 -3
  331. package/x/core/intent/consts.js.map +0 -1
  332. package/x/core/intent/decode.d.ts +0 -3
  333. package/x/core/intent/decode.js +0 -18
  334. package/x/core/intent/decode.js.map +0 -1
  335. package/x/core/intent/encode.d.ts +0 -3
  336. package/x/core/intent/encode.js +0 -15
  337. package/x/core/intent/encode.js.map +0 -1
  338. package/x/core/intent/merge.d.ts +0 -3
  339. package/x/core/intent/merge.js +0 -10
  340. package/x/core/intent/merge.js.map +0 -1
  341. package/x/core/parts/action.d.ts +0 -14
  342. package/x/core/parts/action.js +0 -30
  343. package/x/core/parts/action.js.map +0 -1
  344. package/x/core/parts/sample-map.d.ts +0 -6
  345. package/x/core/parts/sample-map.js +0 -21
  346. package/x/core/parts/sample-map.js.map +0 -1
  347. package/x/core/resolvers/actions.d.ts +0 -2
  348. package/x/core/resolvers/actions.js +0 -23
  349. package/x/core/resolvers/actions.js.map +0 -1
  350. package/x/core/resolvers/intents.d.ts +0 -2
  351. package/x/core/resolvers/intents.js +0 -89
  352. package/x/core/resolvers/intents.js.map +0 -1
  353. package/x/core/types.d.ts +0 -43
  354. package/x/core/types.js +0 -2
  355. package/x/core/types.js.map +0 -1
  356. package/x/deck/controller.d.ts +0 -11
  357. package/x/deck/controller.js +0 -28
  358. package/x/deck/controller.js.map +0 -1
  359. package/x/deck/deck.d.ts +0 -31
  360. package/x/deck/deck.js +0 -68
  361. package/x/deck/deck.js.map +0 -1
  362. package/x/deck/parts/profiles.d.ts +0 -12
  363. package/x/deck/parts/profiles.js +0 -31
  364. package/x/deck/parts/profiles.js.map +0 -1
  365. package/x/deck/parts/runtime.d.ts +0 -8
  366. package/x/deck/parts/runtime.js +0 -7
  367. package/x/deck/parts/runtime.js.map +0 -1
  368. package/x/deck/parts/settings.d.ts +0 -11
  369. package/x/deck/parts/settings.js +0 -26
  370. package/x/deck/parts/settings.js.map +0 -1
  371. package/x/deck/port.d.ts +0 -10
  372. package/x/deck/port.js +0 -24
  373. package/x/deck/port.js.map +0 -1
  374. package/x/deck/types.d.ts +0 -11
  375. package/x/deck/types.js +0 -2
  376. package/x/deck/types.js.map +0 -1
  377. package/x/device/devices.d.ts +0 -7
  378. package/x/device/devices.js +0 -17
  379. package/x/device/devices.js.map +0 -1
  380. package/x/device/gamepad.d.ts +0 -9
  381. package/x/device/gamepad.js +0 -37
  382. package/x/device/gamepad.js.map +0 -1
  383. package/x/device/keyboard.d.ts +0 -6
  384. package/x/device/keyboard.js +0 -30
  385. package/x/device/keyboard.js.map +0 -1
  386. package/x/device/pad/on-pad.js.map +0 -1
  387. package/x/device/pad/pad.js.map +0 -1
  388. package/x/device/pointer.d.ts +0 -12
  389. package/x/device/pointer.js +0 -73
  390. package/x/device/pointer.js.map +0 -1
  391. package/x/device/sampler.d.ts +0 -9
  392. package/x/device/sampler.js +0 -19
  393. package/x/device/sampler.js.map +0 -1
  394. package/x/device/stick.d.ts +0 -14
  395. package/x/device/stick.js +0 -22
  396. package/x/device/stick.js.map +0 -1
  397. package/x/index-ui.d.ts +0 -1
  398. package/x/index-ui.js +0 -2
  399. package/x/index-ui.js.map +0 -1
  400. package/x/index.d.ts +0 -27
  401. package/x/index.js +0 -28
  402. package/x/index.js.map +0 -1
  403. package/x/test.d.ts +0 -9
  404. package/x/test.js +0 -307
  405. package/x/test.js.map +0 -1
  406. package/x/ui/views/desk/style.css.d.ts +0 -2
  407. package/x/ui/views/desk/style.css.js +0 -69
  408. package/x/ui/views/desk/style.css.js.map +0 -1
  409. package/x/ui/views/desk/view.d.ts +0 -7
  410. package/x/ui/views/desk/view.js +0 -102
  411. package/x/ui/views/desk/view.js.map +0 -1
  412. package/x/utils/circular-clamp.d.ts +0 -2
  413. package/x/utils/circular-clamp.js +0 -8
  414. package/x/utils/circular-clamp.js.map +0 -1
  415. package/x/utils/do-async.d.ts +0 -1
  416. package/x/utils/do-async.js +0 -4
  417. package/x/utils/do-async.js.map +0 -1
  418. package/x/utils/evergreen.js.map +0 -1
  419. package/x/utils/freeze-clone.d.ts +0 -1
  420. package/x/utils/freeze-clone.js +0 -5
  421. package/x/utils/freeze-clone.js.map +0 -1
  422. package/x/utils/identifier.d.ts +0 -6
  423. package/x/utils/identifier.js +0 -25
  424. package/x/utils/identifier.js.map +0 -1
  425. package/x/utils/insert.d.ts +0 -1
  426. package/x/utils/insert.js +0 -5
  427. package/x/utils/insert.js.map +0 -1
  428. package/x/utils/is-down.js.map +0 -1
  429. package/x/utils/make-id.d.ts +0 -1
  430. package/x/utils/make-id.js +0 -5
  431. package/x/utils/make-id.js.map +0 -1
  432. package/x/utils/remap.d.ts +0 -1
  433. package/x/utils/remap.js +0 -6
  434. package/x/utils/remap.js.map +0 -1
  435. package/x/utils/shift-limit.d.ts +0 -2
  436. package/x/utils/shift-limit.js +0 -7
  437. package/x/utils/shift-limit.js.map +0 -1
  438. package/x/utils/sort-by-key.d.ts +0 -1
  439. package/x/utils/sort-by-key.js +0 -6
  440. package/x/utils/sort-by-key.js.map +0 -1
  441. package/x/utils/split-axis.js.map +0 -1
  442. package/x/utils/tmax.d.ts +0 -1
  443. package/x/utils/tmax.js +0 -6
  444. package/x/utils/tmax.js.map +0 -1
  445. package/x/utils/tmin.d.ts +0 -1
  446. package/x/utils/tmin.js +0 -6
  447. package/x/utils/tmin.js.map +0 -1
  448. /package/s/{core → _archive/core}/atom/defaults.ts +0 -0
  449. /package/s/{core → _archive/core}/atom/lens-algo.ts +0 -0
  450. /package/s/{core → _archive/core}/atom/types.ts +0 -0
  451. /package/s/{core → _archive/core}/bindings/normalize.ts +0 -0
  452. /package/s/{core → _archive/core}/bindings/shape.ts +0 -0
  453. /package/s/{core → _archive/core}/bindings/table.ts +0 -0
  454. /package/s/{core → _archive/core}/intent/bucket.ts +0 -0
  455. /package/s/{core → _archive/core}/intent/consts.ts +0 -0
  456. /package/s/{core → _archive/core}/intent/decode.ts +0 -0
  457. /package/s/{core → _archive/core}/intent/encode.ts +0 -0
  458. /package/s/{core → _archive/core}/intent/merge.ts +0 -0
  459. /package/s/{core → _archive/core}/parts/action.ts +0 -0
  460. /package/s/{core → _archive/core}/parts/sample-map.ts +0 -0
  461. /package/s/{core → _archive/core}/resolvers/actions.ts +0 -0
  462. /package/s/{core → _archive/core}/resolvers/intents.ts +0 -0
  463. /package/s/{core → _archive/core}/types.ts +0 -0
  464. /package/s/{deck → _archive/deck}/controller.ts +0 -0
  465. /package/s/{deck → _archive/deck}/parts/profiles.ts +0 -0
  466. /package/s/{deck → _archive/deck}/parts/runtime.ts +0 -0
  467. /package/s/{deck → _archive/deck}/parts/settings.ts +0 -0
  468. /package/s/{deck → _archive/deck}/port.ts +0 -0
  469. /package/s/{deck → _archive/deck}/types.ts +0 -0
  470. /package/s/{device → _archive/device}/devices.ts +0 -0
  471. /package/s/{device → _archive/device}/gamepad.ts +0 -0
  472. /package/s/{device → _archive/device}/keyboard.ts +0 -0
  473. /package/s/{device → _archive/device}/pad/on-pad.ts +0 -0
  474. /package/s/{device → _archive/device}/pad/pad.ts +0 -0
  475. /package/s/{device → _archive/device}/pointer.ts +0 -0
  476. /package/s/{device → _archive/device}/sampler.ts +0 -0
  477. /package/s/{device → _archive/device}/stick.ts +0 -0
  478. /package/s/{index-ui.ts → _archive/index-ui.ts} +0 -0
  479. /package/s/{utils → _archive/lib/bindings/utils}/is-down.ts +0 -0
  480. /package/s/{utils → _archive/lib/utils}/evergreen.ts +0 -0
  481. /package/s/{utils → _archive/lib/utils}/split-axis.ts +0 -0
  482. /package/s/{test.ts → _archive/test.ts} +0 -0
  483. /package/s/{ui → _archive/ui}/views/desk/style.css.ts +0 -0
  484. /package/s/{ui → _archive/ui}/views/desk/view.ts +0 -0
  485. /package/s/{utils → _archive/utils}/do-async.ts +0 -0
  486. /package/s/{utils → _archive/utils}/freeze-clone.ts +0 -0
  487. /package/s/{utils → _archive/utils}/identifier.ts +0 -0
  488. /package/s/{utils → _archive/utils}/insert.ts +0 -0
  489. /package/s/{utils → _archive/utils}/make-id.ts +0 -0
  490. /package/s/{utils → _archive/utils}/remap.ts +0 -0
  491. /package/s/{utils → _archive/utils}/shift-limit.ts +0 -0
  492. /package/s/{utils → _archive/utils}/sort-by-key.ts +0 -0
  493. /package/s/{utils → _archive/utils}/tmax.ts +0 -0
  494. /package/s/{utils → _archive/utils}/tmin.ts +0 -0
  495. /package/x/{utils → lib/input/utils}/evergreen.d.ts +0 -0
  496. /package/x/{utils → lib/input/utils}/evergreen.js +0 -0
  497. /package/x/{utils → lib/input/utils}/is-down.d.ts +0 -0
  498. /package/x/{utils → lib/input/utils}/is-down.js +0 -0
  499. /package/x/{device → lib/input/utils}/pad/on-pad.d.ts +0 -0
  500. /package/x/{device → lib/input/utils}/pad/on-pad.js +0 -0
  501. /package/x/{device → lib/input/utils}/pad/pad.d.ts +0 -0
  502. /package/x/{device → lib/input/utils}/pad/pad.js +0 -0
  503. /package/x/{utils → lib/input/utils}/split-axis.d.ts +0 -0
  504. /package/x/{utils → lib/input/utils}/split-axis.js +0 -0
package/README.md CHANGED
@@ -1,93 +1,112 @@
1
1
 
2
2
  # 🎮 @benev/tact
3
- > *from keypress to couch co-op*
3
+ > *from keypress to couch co-op.*
4
+
5
+ **tact is a tiny input toolkit for web games.**
6
+ keyboards, mice, gamepads. expressive bindings json dsl.
7
+ binary messages for efficient networking and web worker multithreading.
4
8
 
5
9
  ```ts
6
- npm install @benev/tact
10
+ npm install @benev/tact@next
7
11
  ```
8
12
 
9
- tact is a toolkit for handling user input on the web.
10
- customizable keybindings, multiple-gamepad couch co-op, ready-made configurator ui, efficient networking, mobile virtual thumbsticks.
11
-
12
13
 
13
14
 
14
15
  <br/>
15
16
 
16
- ## 🎮 tact basics
17
+ ## 🕹️ sources emit samples.
17
18
 
18
- ```ts
19
- import {
20
- Devices, KeyboardDevice, PointerDevice,
21
- makeIntentsResolver, makeActionsResolver,
22
- } from "@benev/tact"
23
- ```
24
-
25
- 1. **setup your game's keybindings**
19
+ - **samples look like** `{code: "KeyW", value: 1}`
26
20
  ```ts
27
- const bindings = {
28
- running: {forward: "KeyW", jump: ["and", "ShiftLeft", "Space"]},
29
- gunning: {shoot: ["or", "pointer.button.left", "gamepad.trigger.right"]},
30
- }
21
+ import {Sources, KeyboardSource, PointerSource} from "@benev/tact"
31
22
  ```
32
- 1. **create your devices (which provide raw input samples)**
33
23
  ```ts
34
- const devices = new Devices(
35
- new KeyboardDevice(),
36
- new PointerDevice(),
24
+ const source = new Sources(
25
+ new KeyboardSource(),
26
+ new PointerSource(),
37
27
  )
38
28
  ```
39
- 1. **make your resolvers**
40
- ```ts
41
- const resolveIntents = makeIntentsResolver(bindings)
42
- const resolveActions = makeActionsResolver(bindings)
43
- ```
44
- 1. **run your resolvers, read your actions**
45
- ```ts
46
- import {cycle} from "@e280/stz"
29
+ - proper sources: [GamepadSource](./s/lib/input/sources/gamepad.ts), [KeyboardSource](./s/lib/input/sources/keyboard.ts), [PointerSource](./s/lib/input/sources/pointer.ts), [StickSource](./s/lib/input/sources/stick.ts).
30
+ - utility sources: [Sources](./s/lib/input/sources/sources.ts) *(consolidates sources)*, [PlainSource](./s/lib/input/sources/plain.ts) *(handy base class)*.
31
+
47
32
 
48
- cycle(function myGameTick() {
49
33
 
50
- // 🧙‍♂️ samples get resolved into compact intent tuples, good for networking.
51
- const intents = resolveIntents(Date.now(), devices.samples())
34
+ <br/>
52
35
 
53
- // 🧙‍♂️ actions are your ergonomic accessors for values.
54
- const actions = resolveActions(intents)
36
+ ## 🕹️ bindings describe controls.
55
37
 
56
- // 🧙‍♂️ okay, now check your actions.
57
- actions.running.forward.value // 1.0
58
- actions.running.forward.pressed // true
38
+ - **bindings are tiny programs,** a dsl in js data.
39
+ ```ts
40
+ import {asBindings} from "@benev/tact"
41
+ ```
42
+ ```ts
43
+ const bindings = asBindings({
44
+ forward: ["max", "KeyW", "ArrowUp"],
45
+ jump: ["down", "Space"],
46
+ look: ["accumulate", ["sum", "pointer.x"]],
59
47
  })
60
48
  ```
49
+ - see [expression.ts](./s/lib/input/expression.ts) to learn what's possible.
50
+
61
51
 
62
- ### 🧙‍♂️ wizardly tips
63
52
 
64
- 1. **for networking, you should encode intents as Uint8Array for better efficiency down the wire.**
53
+ <br/>
54
+
55
+ ## 🕹️ encode and decode.
56
+
57
+ - **the data is binary for efficient networking.**
58
+ ```ts
59
+ import {InputEncoder, InputDecoder} from "@benev/tact"
60
+ ```
65
61
  ```ts
66
- import {encodeIntents, decodeIntents} from "@benev/tact"
62
+ const encoder = new InputEncoder(source, bindings)
63
+ const decoder = new InputDecoder(bindings)
64
+ ```
65
+ ```ts
66
+ function frame() {
67
67
 
68
- const intents = [[1, 0.7853981633974483]]
68
+ // data is an ArrayBuffer (you could stream it over the network).
69
+ const data = encoder.encode()
69
70
 
70
- console.log(JSON.stringify(intents).length)
71
- // 22 — yikes
71
+ // decoding interprets the data as handy input objects.
72
+ const inputs = decoder.decode(data)
72
73
 
73
- const bytes = encodeIntents(intents)
74
+ // your game logic can read these handy input values.
75
+ inputs.forward.value // current held state.
76
+ inputs.jump.value // down-presses this frame.
77
+ inputs.look.value // total accumulated mouse movement.
74
78
 
75
- console.log(bytes.length)
76
- // 6 — noice
79
+ // this was so cool, let's do this forever.
80
+ requestAnimationFrame(frame)
81
+ }
77
82
 
78
- const intents = decodeIntents(bytes)
83
+ requestAnimationFrame(frame)
79
84
  ```
80
- 1. **you can normalize bindings**
85
+ - **understanding networking situations.**
86
+ - the encoder could be on your clientside.
87
+ - the decoder could be on your serverside.
88
+ - thus, clients are streaming their input data to the serverside, which is decoding it and using it in game logic.
89
+ - don't worry, it's not a keylogger -- the encoded data is more like `jump: 1`, `look: 5`, etc.
90
+ - the decoder can accept multiple data packets at once, `decoder.decode(...datas)`.
91
+ - **understanding multithreaded worker situations.**
92
+ - the encoder would be on the main thread, where javascript events are accessible.
93
+ - you can then send the encoded input data to the thread where you're simulating the game.
94
+ - you can have multiple encoders -- one encoder sending data to a worker thread -- another encoder sending data to the serverside.
95
+ - **update the encoder's bindings anytime.**
81
96
  ```ts
82
- import {normalizeBindings} from "@benev/tact"
83
-
84
- const bindings = normalizeBindings(appBindings, susBindings)
97
+ // the new bindings must be schema-compatible or an error is thrown.
98
+ encoder.bindings = {
99
+ forward: "KeyE",
100
+ jump: "Space",
101
+ look: "gamepad.axis.2"
102
+ }
85
103
  ```
86
- this clones your app bindings and cherry-picks any compatible user bindings. useful when loading from localStorage, so changes to your schema don’t break things.
87
104
 
88
105
 
89
106
 
90
107
  <br/><br/>
91
108
 
109
+ ---
110
+
92
111
  👼 *https://benev.gg/*
93
112
 
package/package.json CHANGED
@@ -1,15 +1,14 @@
1
1
  {
2
2
  "name": "@benev/tact",
3
- "version": "0.3.0-5",
3
+ "version": "0.4.0-0",
4
4
  "description": "🎮 keybindings and couch co-op",
5
5
  "license": "MIT",
6
6
  "author": "Chase Moskal <chasemoskal@gmail.com>",
7
7
  "type": "module",
8
- "main": "./x/index.js",
8
+ "main": "./x/lib/index.js",
9
9
  "sideEffects": false,
10
10
  "exports": {
11
- ".": "./x/index.js",
12
- "./ui": "./x/index-ui.js"
11
+ ".": "./x/lib/index.js"
13
12
  },
14
13
  "files": [
15
14
  "x",
@@ -17,29 +16,32 @@
17
16
  ],
18
17
  "scripts": {
19
18
  "build": "octo-s 'rm -rf x' 'tsc' 'scute -v'",
20
- "dev": "octo 'scute -vw' 'tsc -w' 'node --watch x/test.js' 'hottie x --port=8081'",
21
- "test": "node x/test.js",
19
+ "dev": "octo 'scute -vw' 'tsc -w' 'node --watch x/lib/test.js' 'hottie x --port=8081'",
20
+ "test": "node x/lib/test.js",
22
21
  "count": "find s -path '*/_archive' -prune -o -name '*.ts' -exec wc -l {} +"
23
22
  },
24
23
  "peerDependencies": {
25
- "@e280/sly": "^0.4.8",
26
- "@e280/strata": "^0.5.2",
24
+ "@e280/sly": "^0.4.9",
25
+ "@e280/strata": "^0.5.6",
27
26
  "lit": "^3.3.3"
28
27
  },
29
28
  "dependencies": {
30
- "@benev/math": "^0.4.0-8",
31
- "@e280/kv": "^0.2.1",
32
- "@e280/stz": "^0.4.2"
29
+ "@benev/math": "0.4.0-9",
30
+ "@e280/kv": "^0.2.4",
31
+ "@e280/stz": "^0.4.11"
33
32
  },
34
33
  "devDependencies": {
35
- "@e280/hottie": "^0.1.5",
36
- "@e280/octo": "^0.1.5",
37
- "@e280/science": "^0.1.12",
38
- "@e280/scute": "^0.5.2",
34
+ "@e280/hottie": "^0.1.7",
35
+ "@e280/octo": "^0.1.7",
36
+ "@e280/science": "^0.1.14",
37
+ "@e280/scute": "^0.5.3",
39
38
  "http-server": "^14.1.1",
40
39
  "npm-run-all": "^4.1.5",
41
40
  "typescript": "^7.0.2"
42
41
  },
42
+ "allowScripts": {
43
+ "esbuild@0.28.2": true
44
+ },
43
45
  "repository": {
44
46
  "type": "git",
45
47
  "url": "git+https://github.com/benev-gg/tact.git"
@@ -53,9 +55,5 @@
53
55
  "keybinds",
54
56
  "keybindings",
55
57
  "gamepad"
56
- ],
57
- "allowScripts": {
58
- "classic-level@3.0.0": true,
59
- "esbuild@0.28.2": true
60
- }
58
+ ]
61
59
  }
@@ -1,69 +1,92 @@
1
1
 
2
- import {Kv} from "@e280/kv"
3
- import {disposer, range} from "@e280/stz"
4
-
5
- import {Db} from "./parts/db.js"
6
- import {Hub} from "../core/hub/hub.js"
7
- import {Port} from "../core/hub/port.js"
8
- import {Bindings} from "../core/bindings/types.js"
9
- import {mergeBindings} from "./parts/merge-bindings.js"
10
- import {MetaBindings, metaMode} from "../core/hub/types.js"
11
- import {makeMetaBindings} from "../core/hub/meta-bindings.js"
12
- import {DeviceSkins} from "./parts/device-skins/device-skin.js"
13
- import {OverlayVisibility} from "./parts/overlay-visibility.js"
14
- import {PrimaryDevice} from "../core/devices/standard/primary.js"
15
-
16
- export type DeckOptions<B extends Bindings, MB extends MetaBindings = any> = {
17
- kv: Kv
18
- bindings: B
19
- portCount: number
20
- metaBindings?: MB
21
- }
2
+ import {Cubby, debounce, guarantee} from "@e280/stz"
3
+ import {Port} from "./port.js"
4
+ import {Device} from "../core/types.js"
5
+ import {Runtime} from "./parts/runtime.js"
6
+ import {Controller} from "./controller.js"
7
+ import {Profiles} from "./parts/profiles.js"
8
+ import {Settings} from "./parts/settings.js"
9
+ import {DeckState, Profile, ProfileKey} from "./types.js"
10
+
11
+ export class Deck<StockProfileKey extends ProfileKey = ProfileKey> {
12
+ profiles
13
+ settings
14
+ #runtime = new Runtime()
15
+
16
+ constructor(options: {
17
+ store: Cubby<DeckState>
18
+ stockProfiles: Record<StockProfileKey, Profile>
19
+ }) {
20
+ this.settings = new Settings(options.store)
21
+ this.profiles = new Profiles(options.stockProfiles, this.settings.customProfiles)
22
+ }
22
23
 
23
- export class Deck<B extends Bindings, MB extends MetaBindings = any> {
24
- static async load<B extends Bindings, MB extends MetaBindings = any>(options: DeckOptions<B, MB>) {
25
- const db = await Db.load(options.kv.store("catalog"))
24
+ async load() {
25
+ await this.settings.load()
26
+ for (const controller of this.#runtime.controllers.keys())
27
+ this.#applyControllerProfile(controller)
28
+ }
26
29
 
27
- const ports = range(options.portCount)
28
- .map(index => db.$catalog().getProfileForPort(index))
29
- .map(profile => mergeBindings(options.bindings, profile?.bindings))
30
- .map(bindings => new Port<B>(bindings as B))
30
+ #save = debounce(100, () => this.settings.save())
31
31
 
32
- const hub = new Hub<B>(
33
- ports,
34
- db.$catalog().metaBindings
35
- ?? options.metaBindings
36
- ?? makeMetaBindings(),
37
- )
32
+ get ports() {
33
+ return [...this.#runtime.ports]
34
+ }
38
35
 
39
- return new this(options.bindings, options.metaBindings, hub, db)
36
+ get controllers() {
37
+ return [...this.#runtime.controllers]
40
38
  }
41
39
 
42
- dispose = disposer()
43
- deviceSkins = new DeviceSkins()
44
- primaryDevice = new PrimaryDevice()
45
- overlayVisibility: OverlayVisibility
40
+ get unassignedControllers() {
41
+ return [...this.#runtime.controllers]
42
+ .filter(controller => !this.#runtime.portAssignments.get(controller))
43
+ }
46
44
 
47
- constructor(
48
- public baseBindings: B,
49
- public baseMetaBindings: MB,
50
- public hub: Hub<B, MB>,
51
- public db: Db,
45
+ createPort() {
46
+ const port = new Port(this.#runtime)
47
+ this.#runtime.ports.add(port)
48
+ return port
49
+ }
50
+
51
+ deletePort(port: Port) {
52
+ for (const controller of port.controllers)
53
+ port.unplug(controller)
54
+ this.#runtime.ports.delete(port)
55
+ }
56
+
57
+ createController<D extends Device = Device>(
58
+ handle: string,
59
+ stockProfileKey: StockProfileKey,
60
+ device: D,
52
61
  ) {
62
+ const profileKey = guarantee(this.settings.profileAssignments, handle, () => stockProfileKey)
63
+ const profile = this.profiles.get(profileKey)
64
+ const controller = new Controller(handle, profile.bindings, device)
65
+ this.#runtime.controllers.add(controller)
66
+ return controller
67
+ }
53
68
 
54
- this.overlayVisibility = new OverlayVisibility(hub, this.deviceSkins)
69
+ deleteController(controller: Controller) {
70
+ this.#runtime.controllers.delete(controller)
71
+ this.#runtime.portAssignments.delete(controller)
72
+ }
73
+
74
+ async assignControllerProfile(controller: Controller, profileKey: StockProfileKey | ProfileKey) {
75
+ this.settings.profileAssignments.set(controller.handle, profileKey)
76
+ this.#applyControllerProfile(controller)
77
+ await this.#save()
78
+ }
55
79
 
56
- // meta reveal overlay
57
- this.dispose.schedule(
58
- hub.metaPort.actions[metaMode].revealOverlay.on(action => {
59
- if (action.pressed)
60
- this.overlayVisibility.bump()
61
- })
62
- )
80
+ queryController(controller: Controller) {
81
+ const port = this.#runtime.portAssignments.get(controller)
82
+ const profileKey = this.settings.profileAssignments.get(controller.handle)
83
+ const profile = this.profiles.get(profileKey)
84
+ return {controller, port, profileKey, profile}
63
85
  }
64
86
 
65
- get catalog() {
66
- return this.db.$catalog()
87
+ #applyControllerProfile(controller: Controller) {
88
+ const profileKey = this.settings.profileAssignments.get(controller.handle)
89
+ controller.bindings = this.profiles.get(profileKey).bindings
67
90
  }
68
91
  }
69
92
 
@@ -0,0 +1,17 @@
1
+
2
+ import {html} from "lit"
3
+ import {shadowElement, useCss} from "@e280/sly"
4
+ import styleCss from "./style.css.js"
5
+ import {Deck} from "../../deck/deck.js"
6
+ import {DeskOptions, DeskView} from "../../ui/views/desk/view.js"
7
+
8
+ export const setupDemoApp = (deck: Deck, options: DeskOptions = {}) => shadowElement(() => {
9
+ useCss(styleCss)
10
+
11
+ return html`
12
+ <div class=plate>
13
+ ${DeskView(deck, options)}
14
+ </div>
15
+ `
16
+ })
17
+
@@ -2,5 +2,9 @@
2
2
  import {css} from "lit"
3
3
  export default css`
4
4
 
5
+ .plate {
6
+ background: black;
7
+ }
8
+
5
9
  `
6
10
 
@@ -1,10 +1,71 @@
1
1
 
2
- import {dom} from "@e280/sly"
3
- import {Game} from "./game/game.js"
4
- import {DemoTheater} from "./ui/theater/view.js"
2
+ import {Content, dom} from "@e280/sly"
3
+ import {LocalStore} from "@e280/strata"
5
4
 
6
- const game = await Game.load()
5
+ import {Deck} from "../deck/deck.js"
6
+ import {DeckState} from "../deck/types.js"
7
+ import {asBindings} from "../core/types.js"
8
+ import {Devices} from "../device/devices.js"
9
+ import {onPad} from "../device/pad/on-pad.js"
10
+ import {Controller} from "../deck/controller.js"
11
+ import {PointerDevice} from "../device/pointer.js"
12
+ import {GamepadDevice} from "../device/gamepad.js"
13
+ import {setupDemoApp} from "./demo-app/element.js"
14
+ import {KeyboardDevice} from "../device/keyboard.js"
7
15
 
8
- dom.render(dom("#demo-theater"), DemoTheater(game))
16
+ const bindings = asBindings({
17
+ play: {
18
+ action: ["or", "Space", "pointer.button.left", "gamepad.button.1"],
19
+ up: ["or", "KeyW", "gamepad.axis.2.pos"],
20
+ down: ["or", "KeyS", "gamepad.axis.2.neg"],
21
+ left: ["or", "KeyA", "gamepad.axis.1.pos"],
22
+ right: ["or", "KeyD", "gamepad.axis.1.neg"],
23
+ },
24
+ })
25
+
26
+ const store = new LocalStore<DeckState>("tactDeck")
27
+
28
+ const deck = new Deck({
29
+ store,
30
+ stockProfiles: {
31
+ standard: {label: "📜standard", bindings},
32
+ micro: {label: "🦠micro", bindings: asBindings<typeof bindings>({
33
+ play: {
34
+ action: ["or", "Space", "pointer.button.left", "gamepad.button.1"],
35
+ up: ["or", "KeyW", "gamepad.axis.2.pos"],
36
+ down: ["or", "KeyS", "gamepad.axis.2.neg"],
37
+ left: ["or", "KeyA", "gamepad.axis.1.pos"],
38
+ right: ["or", "KeyD", "gamepad.axis.1.neg"],
39
+ },
40
+ })},
41
+ },
42
+ })
43
+
44
+ await deck.load()
45
+ store.onStorageEvent(() => deck.load())
46
+
47
+ const port = deck.createPort()
48
+ const controller = deck.createController("primary", "standard", new Devices(
49
+ new KeyboardDevice(),
50
+ new PointerDevice(),
51
+ ))
52
+
53
+ port.plug(controller)
54
+
55
+ const labels = new Map<Controller, Content>()
56
+ .set(controller, "⌨️🖱keyboard+mouse")
57
+
58
+ onPad(pad => {
59
+ const handle = `(${pad.gamepad.index + 1}) ${pad.gamepad.id}`
60
+ const controller = deck.createController(handle, "standard", new GamepadDevice(pad))
61
+ labels.set(controller, `🎮${handle}`)
62
+ port.plug(controller)
63
+ return () => deck.deleteController(controller)
64
+ })
65
+
66
+ dom.register({
67
+ DemoApp: setupDemoApp(deck, {
68
+ getControllerLabel: labels.get.bind(labels),
69
+ }),
70
+ })
9
71
 
10
- console.log("🎮 tact")
@@ -1,13 +1,13 @@
1
1
 
2
- @layer vars, core, basics, page;
2
+ @layer vars, core, page;
3
3
 
4
4
  @layer vars {
5
5
  :root {
6
6
  color-scheme: dark;
7
+
7
8
  --link: cyan;
8
- --prime: #ccc;
9
+ --text: #ccc;
9
10
  --bg: #181818;
10
- --bg2: #111111;
11
11
  }
12
12
  }
13
13
 
@@ -42,19 +42,17 @@
42
42
  }
43
43
  }
44
44
 
45
- @layer basics {
45
+ @layer page {
46
46
  html { height: 100%; }
47
47
  body { min-height: 100%; }
48
48
 
49
49
  html, body {
50
50
  font-family: sans-serif;
51
- font-size: 12px;
52
- color: var(--prime);
51
+ font-size: 16px;
52
+ color: var(--text);
53
53
  background: var(--bg);
54
54
  }
55
- }
56
55
 
57
- @layer page {
58
56
  body {
59
57
  display: flex;
60
58
  flex-direction: column;
@@ -0,0 +1,61 @@
1
+
2
+ import {deep} from "@e280/stz"
3
+ import {Sample} from "../sampling/types.js"
4
+ import {IntentResolver} from "./utils/intent-resolver.js"
5
+ import {ActionResolver} from "./utils/action-resolver.js"
6
+ import {investigateBindings} from "./utils/investigate.js"
7
+ import {Actions, Bindings, Rebindings, Intent} from "./types.js"
8
+
9
+ export class Resolver<B extends Bindings> {
10
+ #bindings
11
+ #hash
12
+ #actionlist
13
+ #expressionlist
14
+
15
+ #intentResolver = new IntentResolver()
16
+ #actionResolver = new ActionResolver()
17
+
18
+ readonly actions
19
+
20
+ constructor(bindings: B) {
21
+ const investigation = investigateBindings(bindings)
22
+ this.#bindings = deep.freeze(bindings) as any as Rebindings<B>
23
+ this.#hash = investigation.hash
24
+ this.actions = investigation.actions
25
+ this.#actionlist = investigation.actionlist
26
+ this.#expressionlist = investigation.expressionlist
27
+ }
28
+
29
+ get bindings() {
30
+ return this.#bindings
31
+ }
32
+
33
+ set bindings(bindings: Rebindings<B>) {
34
+ const investigation = investigateBindings(bindings)
35
+
36
+ if (investigation.hash !== this.#hash)
37
+ throw new Error("newly set bindings are not compatible, hash mismatch")
38
+
39
+ this.#bindings = deep.freeze(bindings)
40
+ this.#expressionlist = investigation.expressionlist
41
+ }
42
+
43
+ resolveIntent(samples: Sample[], now = performance.now()): Intent {
44
+ return this.#intentResolver.resolve(
45
+ this.#hash,
46
+ this.#expressionlist,
47
+ samples,
48
+ now,
49
+ )
50
+ }
51
+
52
+ resolveActions(intent: Intent): Actions<B> {
53
+ this.#actionResolver.resolve(
54
+ this.#hash,
55
+ this.#actionlist,
56
+ intent,
57
+ )
58
+ return this.actions
59
+ }
60
+ }
61
+
@@ -0,0 +1,67 @@
1
+
2
+ export type Intent = ArrayBuffer
3
+
4
+ /** schema and dsl for controls and keybinds. */
5
+ export type Bindings = Expression | {
6
+ [key: string]: Bindings
7
+ }
8
+
9
+ export type Rebindings<B extends Bindings> = (
10
+ B extends Expression
11
+ ? Expression
12
+ : B extends {[key: string]: Bindings}
13
+ ? {[K in keyof B]: Rebindings<B[K]>}
14
+ : never
15
+ )
16
+
17
+ export type Expression = (
18
+ | string // a code like "KeyW", "pointer.move.up"
19
+ | number // constants for doing math
20
+
21
+ // combiners
22
+ | ["min", ...Expression[]]
23
+ | ["max", ...Expression[]]
24
+ | ["+", ...(Expression | number)[]]
25
+ | ["*", ...(Expression | number)[]]
26
+
27
+ // comparisons
28
+ | ["==", Expression, Expression]
29
+ | ["!=", Expression, Expression]
30
+ | [">", Expression, Expression]
31
+ | ["<", Expression, Expression]
32
+ | [">=", Expression, Expression]
33
+ | ["<=", Expression, Expression]
34
+
35
+ // transforms
36
+ | ["!", Expression]
37
+ | ["!!", Expression]
38
+ | ["clamp", a: Expression | null, b: Expression | null, Expression]
39
+ | ["remap", [a: Expression, b: Expression], [c: Expression, d: Expression], Expression]
40
+
41
+ // temporal
42
+ | ["dt"] // delta time in seconds since last resolve, used for stick sensitivity
43
+ | ["accumulate", string] // sum all values of this expression since last resolve
44
+ | ["tapped", ms: number, taps: number, Expression]
45
+ | ["held", ms: number, Expression]
46
+ )
47
+
48
+ export type Action = {
49
+ value: number // latest-known value
50
+ previous: number // previously-known value
51
+
52
+ change: number // how many times the value has changed since previous resolve
53
+ up: number // how many times this button has been released since previous resolve
54
+ down: number // how many times this button has been pressed since previous resolve
55
+
56
+ lowest: number // lowest value since we last checked
57
+ highest: number // highest value since we last checked
58
+ }
59
+
60
+ export type Actions<B extends Bindings = any> = (
61
+ B extends Expression
62
+ ? Action
63
+ : B extends {[key: string]: Bindings}
64
+ ? {[K in keyof B]: Actions<B[K]>}
65
+ : never
66
+ )
67
+