@benev/tact 0.3.0-4 → 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/{deck → _archive/deck}/parts/profiles.ts +2 -2
  5. package/s/{deck → _archive/deck}/parts/settings.ts +3 -3
  6. package/s/_archive/demo/demo-app/element.ts +17 -0
  7. package/s/_archive/{deck/views/bindings → demo/demo-app}/style.css.ts +4 -0
  8. package/s/_archive/demo/main.bundle.ts +67 -6
  9. package/s/_archive/demo/main.css +6 -8
  10. package/s/{device → _archive/device}/pointer.ts +8 -16
  11. package/s/_archive/lib/bindings/resolver.ts +61 -0
  12. package/s/_archive/lib/bindings/types.ts +67 -0
  13. package/s/_archive/lib/bindings/utils/action-resolver.ts +51 -0
  14. package/s/_archive/lib/bindings/utils/evaluator.ts +162 -0
  15. package/s/_archive/lib/bindings/utils/hash-bindings.ts +22 -0
  16. package/s/_archive/lib/bindings/utils/intent-coding.ts +50 -0
  17. package/s/_archive/lib/bindings/utils/intent-resolver.ts +52 -0
  18. package/s/_archive/lib/bindings/utils/investigate.ts +47 -0
  19. package/s/_archive/lib/bindings/utils/is-expression.ts +11 -0
  20. package/s/_archive/lib/index.ts +12 -0
  21. package/s/_archive/lib/sampling/sources/example.ts +7 -0
  22. package/s/_archive/lib/sampling/sources/gamepad.ts +63 -0
  23. package/s/_archive/lib/sampling/sources/keyboard.ts +52 -0
  24. package/s/_archive/lib/sampling/sources/pointer.ts +56 -0
  25. package/s/_archive/lib/sampling/sources/sources.ts +13 -0
  26. package/s/_archive/lib/sampling/sources/stick.ts +27 -0
  27. package/s/_archive/lib/sampling/types.ts +11 -0
  28. package/s/_archive/lib/sampling/utils/add-sample.ts +12 -0
  29. package/s/_archive/lib/test.ts +57 -0
  30. package/s/_archive/lib/utils/backwards.ts +6 -0
  31. package/s/_archive/lib/utils/mouse-button.ts +10 -0
  32. package/s/_archive/lib/utils/pad/on-pad.ts +50 -0
  33. package/s/_archive/lib/utils/pad/pad.ts +10 -0
  34. package/s/_archive/lib2/core/decoder/decoder.ts +34 -0
  35. package/s/_archive/lib2/core/decoder/utils/update-input.ts +21 -0
  36. package/s/_archive/lib2/core/encoder/encoder.ts +60 -0
  37. package/s/_archive/lib2/core/encoder/evaluate/context.ts +22 -0
  38. package/s/_archive/lib2/core/encoder/evaluate/evaluate.ts +144 -0
  39. package/s/_archive/lib2/core/encoder/parts/expression-index.ts +27 -0
  40. package/s/_archive/lib2/core/encoder/parts/hash-bindings.ts +22 -0
  41. package/s/_archive/lib2/core/encoder/parts/investigate.ts +50 -0
  42. package/s/_archive/lib2/core/encoder/parts/sampler.ts +22 -0
  43. package/s/_archive/lib2/core/sources/example.ts +9 -0
  44. package/s/_archive/lib2/core/sources/sources.ts +16 -0
  45. package/s/_archive/lib2/core/types.ts +78 -0
  46. package/s/_archive/lib2/core/utils/data.ts +50 -0
  47. package/s/_archive/lib2/core/utils/is-down.ts +5 -0
  48. package/s/_archive/lib2/core/utils/is-expression.ts +11 -0
  49. package/s/_archive/lib3/input/data/decode.ts +25 -0
  50. package/s/_archive/lib3/input/data/encode.ts +24 -0
  51. package/s/_archive/lib3/input/data/params.ts +7 -0
  52. package/s/_archive/lib3/input/decoder.ts +56 -0
  53. package/s/_archive/lib3/input/encoder.ts +99 -0
  54. package/s/_archive/lib3/input/evaluate/context.ts +15 -0
  55. package/s/_archive/lib3/input/evaluate/evaluate.ts +142 -0
  56. package/s/_archive/lib3/input/evaluate/utils/clock.ts +14 -0
  57. package/s/_archive/lib3/input/investigate/hash-bindings.ts +22 -0
  58. package/s/_archive/lib3/input/investigate/investigate.ts +42 -0
  59. package/s/_archive/lib3/input/investigate/is-expression.ts +11 -0
  60. package/s/_archive/lib3/input/investigate/make-input.ts +18 -0
  61. package/s/_archive/lib3/input/investigate/root-index.ts +26 -0
  62. package/s/_archive/lib3/input/mixer.ts +20 -0
  63. package/s/_archive/lib3/input/sources/gamepad.ts +58 -0
  64. package/s/_archive/lib3/input/sources/keyboard.ts +49 -0
  65. package/s/_archive/lib3/input/sources/plain.ts +9 -0
  66. package/s/_archive/lib3/input/sources/pointer.ts +58 -0
  67. package/s/_archive/lib3/input/sources/sources.ts +24 -0
  68. package/s/_archive/lib3/input/sources/stick.ts +29 -0
  69. package/s/_archive/lib3/input/testing/quickbind.ts +20 -0
  70. package/s/_archive/lib3/input/types.ts +96 -0
  71. package/s/_archive/lib3/input/utils/evergreen.ts +10 -0
  72. package/s/_archive/lib3/input/utils/is-down.ts +5 -0
  73. package/s/_archive/lib3/input/utils/mouse-button.ts +10 -0
  74. package/s/_archive/lib3/input/utils/pad/on-pad.ts +50 -0
  75. package/s/_archive/lib3/input/utils/pad/pad.ts +10 -0
  76. package/s/_archive/lib3/input/utils/sampler.ts +28 -0
  77. package/s/_archive/lib3/input/utils/split-axis.ts +15 -0
  78. package/s/_archive/lib3/test.ts +100 -0
  79. package/s/_archive/lib4/input/data/decode.ts +25 -0
  80. package/s/_archive/lib4/input/data/encode.ts +24 -0
  81. package/s/_archive/lib4/input/data/params.ts +7 -0
  82. package/s/_archive/lib4/input/encoder.ts +100 -0
  83. package/s/_archive/lib4/input/evaluate/context.ts +16 -0
  84. package/s/_archive/lib4/input/evaluate/evaluate.ts +157 -0
  85. package/s/_archive/lib4/input/evaluate/utils/clock.ts +14 -0
  86. package/s/_archive/lib4/input/investigate/hash-bindings.ts +22 -0
  87. package/s/_archive/lib4/input/investigate/investigate.ts +37 -0
  88. package/s/_archive/lib4/input/investigate/is.ts +19 -0
  89. package/s/_archive/lib4/input/investigate/make-input.ts +18 -0
  90. package/s/_archive/lib4/input/investigate/root-index.ts +26 -0
  91. package/s/_archive/lib4/input/sources/gamepad.ts +58 -0
  92. package/s/_archive/lib4/input/sources/keyboard.ts +46 -0
  93. package/s/_archive/lib4/input/sources/plain.ts +9 -0
  94. package/s/_archive/lib4/input/sources/pointer.ts +50 -0
  95. package/s/_archive/lib4/input/sources/sources.ts +24 -0
  96. package/s/_archive/lib4/input/sources/stick.ts +25 -0
  97. package/s/_archive/lib4/input/types.ts +102 -0
  98. package/s/_archive/lib4/input/utils/evergreen.ts +10 -0
  99. package/s/_archive/lib4/input/utils/is-down.ts +5 -0
  100. package/s/_archive/lib4/input/utils/mouse-button.ts +10 -0
  101. package/s/_archive/lib4/input/utils/pad/on-pad.ts +50 -0
  102. package/s/_archive/lib4/input/utils/pad/pad.ts +10 -0
  103. package/s/_archive/lib4/input/utils/sampler.ts +28 -0
  104. package/s/_archive/lib4/input/utils/split-axis.ts +15 -0
  105. package/s/_archive/lib4/test.ts +12 -0
  106. package/s/_archive/utils/circular-clamp.ts +2 -2
  107. package/s/_archive/utils/is-down.ts +5 -0
  108. package/s/demo/demo-app/element.ts +2 -4
  109. package/s/demo/main.bundle.ts +2 -65
  110. package/s/gamepad/gamepad-app/element.ts +14 -11
  111. package/s/lib/index.ts +18 -0
  112. package/s/lib/input/data/decode.ts +25 -0
  113. package/s/lib/input/data/encode.ts +24 -0
  114. package/s/lib/input/data/params.ts +7 -0
  115. package/s/lib/input/decoder.ts +40 -0
  116. package/s/lib/input/encoder.ts +64 -0
  117. package/s/lib/input/evaluate/context.ts +17 -0
  118. package/s/lib/input/evaluate/evaluate.ts +199 -0
  119. package/s/lib/input/expression.ts +44 -0
  120. package/s/lib/input/investigate/hash-bindings.ts +22 -0
  121. package/s/lib/input/investigate/investigate.ts +35 -0
  122. package/s/lib/input/investigate/is-compatible.ts +8 -0
  123. package/s/lib/input/investigate/is-expression.ts +12 -0
  124. package/s/lib/input/investigate/make-input.ts +11 -0
  125. package/s/lib/input/sources/gamepad.ts +55 -0
  126. package/s/lib/input/sources/keyboard.ts +46 -0
  127. package/s/lib/input/sources/plain.ts +9 -0
  128. package/s/lib/input/sources/pointer.ts +56 -0
  129. package/s/lib/input/sources/sources.ts +24 -0
  130. package/s/lib/input/sources/stick.ts +32 -0
  131. package/s/lib/input/testing/quickbind.ts +20 -0
  132. package/s/lib/input/types.ts +52 -0
  133. package/s/lib/input/utils/clock.ts +14 -0
  134. package/s/lib/input/utils/evergreen.ts +10 -0
  135. package/s/lib/input/utils/is-down.ts +5 -0
  136. package/s/lib/input/utils/mouse-button.ts +10 -0
  137. package/s/lib/input/utils/pad/on-pad.ts +50 -0
  138. package/s/lib/input/utils/pad/pad.ts +10 -0
  139. package/s/lib/input/utils/sampler.ts +28 -0
  140. package/s/lib/input/utils/split-axis.ts +15 -0
  141. package/s/lib/test.ts +180 -0
  142. package/x/_archive/demo/main.css +6 -8
  143. package/x/demo/demo-app/element.d.ts +1 -3
  144. package/x/demo/demo-app/element.js +2 -3
  145. package/x/demo/demo-app/element.js.map +1 -1
  146. package/x/demo/main.bundle.js +1 -50
  147. package/x/demo/main.bundle.js.map +1 -1
  148. package/x/demo/main.bundle.min.js +9 -134
  149. package/x/demo/main.bundle.min.js.map +4 -4
  150. package/x/gamepad/gamepad-app/element.js +12 -10
  151. package/x/gamepad/gamepad-app/element.js.map +1 -1
  152. package/x/gamepad/index.html +2 -2
  153. package/x/gamepad/main.bundle.min.js +9 -9
  154. package/x/gamepad/main.bundle.min.js.map +4 -4
  155. package/x/index.html +2 -2
  156. package/x/lib/index.d.ts +13 -0
  157. package/x/lib/index.js +14 -0
  158. package/x/lib/index.js.map +1 -0
  159. package/x/lib/input/data/decode.d.ts +5 -0
  160. package/x/lib/input/data/decode.js +17 -0
  161. package/x/lib/input/data/decode.js.map +1 -0
  162. package/x/lib/input/data/encode.d.ts +2 -0
  163. package/x/lib/input/data/encode.js +17 -0
  164. package/x/lib/input/data/encode.js.map +1 -0
  165. package/x/lib/input/data/params.d.ts +5 -0
  166. package/x/lib/input/data/params.js +6 -0
  167. package/x/lib/input/data/params.js.map +1 -0
  168. package/x/lib/input/decoder.d.ts +7 -0
  169. package/x/lib/input/decoder.js +31 -0
  170. package/x/lib/input/decoder.js.map +1 -0
  171. package/x/lib/input/encoder.d.ts +10 -0
  172. package/x/lib/input/encoder.js +49 -0
  173. package/x/lib/input/encoder.js.map +1 -0
  174. package/x/lib/input/evaluate/context.d.ts +16 -0
  175. package/x/lib/input/evaluate/context.js +12 -0
  176. package/x/lib/input/evaluate/context.js.map +1 -0
  177. package/x/lib/input/evaluate/evaluate.d.ts +3 -0
  178. package/x/lib/input/evaluate/evaluate.js +147 -0
  179. package/x/lib/input/evaluate/evaluate.js.map +1 -0
  180. package/x/lib/input/expression.d.ts +1 -0
  181. package/x/lib/input/expression.js +2 -0
  182. package/x/lib/input/expression.js.map +1 -0
  183. package/x/lib/input/investigate/hash-bindings.d.ts +2 -0
  184. package/x/lib/input/investigate/hash-bindings.js +17 -0
  185. package/x/lib/input/investigate/hash-bindings.js.map +1 -0
  186. package/x/lib/input/investigate/investigate.d.ts +8 -0
  187. package/x/lib/input/investigate/investigate.js +28 -0
  188. package/x/lib/input/investigate/investigate.js.map +1 -0
  189. package/x/lib/input/investigate/is-compatible.d.ts +2 -0
  190. package/x/lib/input/investigate/is-compatible.js +5 -0
  191. package/x/lib/input/investigate/is-compatible.js.map +1 -0
  192. package/x/lib/input/investigate/is-expression.d.ts +3 -0
  193. package/x/lib/input/investigate/is-expression.js +11 -0
  194. package/x/lib/input/investigate/is-expression.js.map +1 -0
  195. package/x/lib/input/investigate/make-input.d.ts +2 -0
  196. package/x/lib/input/investigate/make-input.js +8 -0
  197. package/x/lib/input/investigate/make-input.js.map +1 -0
  198. package/x/lib/input/sources/gamepad.d.ts +9 -0
  199. package/x/lib/input/sources/gamepad.js +45 -0
  200. package/x/lib/input/sources/gamepad.js.map +1 -0
  201. package/x/lib/input/sources/keyboard.d.ts +5 -0
  202. package/x/lib/input/sources/keyboard.js +36 -0
  203. package/x/lib/input/sources/keyboard.js.map +1 -0
  204. package/x/lib/input/sources/plain.d.ts +5 -0
  205. package/x/lib/input/sources/plain.js +6 -0
  206. package/x/lib/input/sources/plain.js.map +1 -0
  207. package/x/lib/input/sources/pointer.d.ts +7 -0
  208. package/x/lib/input/sources/pointer.js +54 -0
  209. package/x/lib/input/sources/pointer.js.map +1 -0
  210. package/x/lib/input/sources/sources.d.ts +7 -0
  211. package/x/lib/input/sources/sources.js +15 -0
  212. package/x/lib/input/sources/sources.js.map +1 -0
  213. package/x/lib/input/sources/stick.d.ts +10 -0
  214. package/x/lib/input/sources/stick.js +25 -0
  215. package/x/lib/input/sources/stick.js.map +1 -0
  216. package/x/lib/input/testing/quickbind.d.ts +11 -0
  217. package/x/lib/input/testing/quickbind.js +12 -0
  218. package/x/lib/input/testing/quickbind.js.map +1 -0
  219. package/x/lib/input/types.d.ts +37 -0
  220. package/x/lib/input/types.js +2 -0
  221. package/x/lib/input/types.js.map +1 -0
  222. package/x/lib/input/utils/clock.d.ts +7 -0
  223. package/x/lib/input/utils/clock.js +14 -0
  224. package/x/lib/input/utils/clock.js.map +1 -0
  225. package/x/lib/input/utils/evergreen.js.map +1 -0
  226. package/x/lib/input/utils/is-down.js.map +1 -0
  227. package/x/lib/input/utils/mouse-button.d.ts +1 -0
  228. package/x/lib/input/utils/mouse-button.js +9 -0
  229. package/x/lib/input/utils/mouse-button.js.map +1 -0
  230. package/x/lib/input/utils/pad/on-pad.js.map +1 -0
  231. package/x/lib/input/utils/pad/pad.js.map +1 -0
  232. package/x/lib/input/utils/sampler.d.ts +7 -0
  233. package/x/lib/input/utils/sampler.js +23 -0
  234. package/x/lib/input/utils/sampler.js.map +1 -0
  235. package/x/lib/input/utils/split-axis.js.map +1 -0
  236. package/x/lib/test.d.ts +1 -0
  237. package/x/lib/test.js +134 -0
  238. package/x/lib/test.js.map +1 -0
  239. package/s/_archive/README.md +0 -435
  240. package/s/_archive/core/bindings/action.ts +0 -30
  241. package/s/_archive/core/bindings/parts/defaults.ts +0 -32
  242. package/s/_archive/core/bindings/parts/is-pressed.ts +0 -5
  243. package/s/_archive/core/bindings/parts/lens-algo.ts +0 -84
  244. package/s/_archive/core/bindings/parts/lookup-proxies.ts +0 -17
  245. package/s/_archive/core/bindings/resolver.ts +0 -103
  246. package/s/_archive/core/bindings/sample-map.ts +0 -25
  247. package/s/_archive/core/bindings/types.ts +0 -60
  248. package/s/_archive/core/core.test.ts +0 -155
  249. package/s/_archive/core/devices/auto-gamepads.ts +0 -8
  250. package/s/_archive/core/devices/device.ts +0 -12
  251. package/s/_archive/core/devices/infra/group.ts +0 -24
  252. package/s/_archive/core/devices/infra/sampler.ts +0 -22
  253. package/s/_archive/core/devices/standard/gamepad.ts +0 -83
  254. package/s/_archive/core/devices/standard/index.ts +0 -8
  255. package/s/_archive/core/devices/standard/keyboard.ts +0 -31
  256. package/s/_archive/core/devices/standard/pointer.ts +0 -97
  257. package/s/_archive/core/devices/standard/primary.ts +0 -20
  258. package/s/_archive/core/devices/standard/stick.ts +0 -27
  259. package/s/_archive/core/devices/standard/vpad.ts +0 -25
  260. package/s/_archive/core/devices/types.ts +0 -3
  261. package/s/_archive/core/hub/hub.ts +0 -118
  262. package/s/_archive/core/hub/meta-bindings.ts +0 -23
  263. package/s/_archive/core/hub/parts/connected.ts +0 -15
  264. package/s/_archive/core/hub/port.ts +0 -26
  265. package/s/_archive/core/hub/types.ts +0 -13
  266. package/s/_archive/core/index.ts +0 -19
  267. package/s/_archive/core/testing/testing.ts +0 -57
  268. package/s/_archive/deck/index.ts +0 -13
  269. package/s/_archive/deck/parts/catalog.ts +0 -58
  270. package/s/_archive/deck/parts/db.ts +0 -65
  271. package/s/_archive/deck/parts/device-skins/device-icons.ts +0 -38
  272. package/s/_archive/deck/parts/device-skins/device-skin.ts +0 -29
  273. package/s/_archive/deck/parts/local-storage-kv.ts +0 -8
  274. package/s/_archive/deck/parts/merge-bindings.ts +0 -21
  275. package/s/_archive/deck/parts/overlay-visibility.ts +0 -49
  276. package/s/_archive/deck/views/bindings/view.ts +0 -95
  277. package/s/_archive/deck/views/overlay/style.css.ts +0 -110
  278. package/s/_archive/deck/views/overlay/view.ts +0 -46
  279. package/s/_archive/demo/game/game.ts +0 -85
  280. package/s/_archive/demo/game/parts/agent.ts +0 -10
  281. package/s/_archive/demo/game/parts/game-bindings.ts +0 -20
  282. package/s/_archive/demo/game/parts/logic.ts +0 -24
  283. package/s/_archive/demo/game/parts/player.ts +0 -32
  284. package/s/_archive/demo/game/parts/renderer.ts +0 -112
  285. package/s/_archive/demo/game/parts/state.ts +0 -23
  286. package/s/_archive/demo/game/parts/virtual-device.ts +0 -13
  287. package/s/_archive/demo/ui/theater/styles.css.ts +0 -57
  288. package/s/_archive/demo/ui/theater/view.ts +0 -55
  289. package/s/_archive/demo/ui/theater/virtual/style.css.ts +0 -43
  290. package/s/_archive/demo/ui/theater/virtual/view.ts +0 -29
  291. package/s/_archive/demo/ui/utils/loader.ts +0 -5
  292. package/s/_archive/index.html.ts +0 -61
  293. package/s/_archive/index.ts +0 -8
  294. package/s/_archive/nubs/index.ts +0 -5
  295. package/s/_archive/nubs/lookpad/styles.ts +0 -21
  296. package/s/_archive/nubs/lookpad/view.ts +0 -39
  297. package/s/_archive/nubs/stick/style.css.ts +0 -70
  298. package/s/_archive/nubs/stick/view.ts +0 -108
  299. package/s/_archive/nubs/vpad/styles.css.ts +0 -134
  300. package/s/_archive/nubs/vpad/utils/gamepad-inputs.ts +0 -42
  301. package/s/_archive/nubs/vpad/utils/prevent-default-touch-shenanigans.ts +0 -12
  302. package/s/_archive/nubs/vpad/utils/touch-tracking.ts +0 -75
  303. package/s/_archive/nubs/vpad/view.ts +0 -141
  304. package/s/_archive/tests.test.ts +0 -6
  305. package/s/_archive/utils/dispensers.ts +0 -20
  306. package/s/_archive/utils/gamepads.ts +0 -41
  307. package/s/_archive/utils/quick-math.ts +0 -13
  308. package/s/deck/deck.ts +0 -92
  309. package/s/index.ts +0 -31
  310. package/s/utils/circular-clamp.ts +0 -14
  311. package/x/core/atom/defaults.d.ts +0 -3
  312. package/x/core/atom/defaults.js +0 -26
  313. package/x/core/atom/defaults.js.map +0 -1
  314. package/x/core/atom/lens-algo.d.ts +0 -2
  315. package/x/core/atom/lens-algo.js +0 -54
  316. package/x/core/atom/lens-algo.js.map +0 -1
  317. package/x/core/atom/types.d.ts +0 -27
  318. package/x/core/atom/types.js +0 -2
  319. package/x/core/atom/types.js.map +0 -1
  320. package/x/core/bindings/normalize.d.ts +0 -2
  321. package/x/core/bindings/normalize.js +0 -17
  322. package/x/core/bindings/normalize.js.map +0 -1
  323. package/x/core/bindings/shape.d.ts +0 -2
  324. package/x/core/bindings/shape.js +0 -10
  325. package/x/core/bindings/shape.js.map +0 -1
  326. package/x/core/bindings/table.d.ts +0 -2
  327. package/x/core/bindings/table.js +0 -15
  328. package/x/core/bindings/table.js.map +0 -1
  329. package/x/core/intent/bucket.d.ts +0 -7
  330. package/x/core/intent/bucket.js +0 -21
  331. package/x/core/intent/bucket.js.map +0 -1
  332. package/x/core/intent/consts.d.ts +0 -2
  333. package/x/core/intent/consts.js +0 -3
  334. package/x/core/intent/consts.js.map +0 -1
  335. package/x/core/intent/decode.d.ts +0 -3
  336. package/x/core/intent/decode.js +0 -18
  337. package/x/core/intent/decode.js.map +0 -1
  338. package/x/core/intent/encode.d.ts +0 -3
  339. package/x/core/intent/encode.js +0 -15
  340. package/x/core/intent/encode.js.map +0 -1
  341. package/x/core/intent/merge.d.ts +0 -3
  342. package/x/core/intent/merge.js +0 -10
  343. package/x/core/intent/merge.js.map +0 -1
  344. package/x/core/parts/action.d.ts +0 -14
  345. package/x/core/parts/action.js +0 -30
  346. package/x/core/parts/action.js.map +0 -1
  347. package/x/core/parts/sample-map.d.ts +0 -6
  348. package/x/core/parts/sample-map.js +0 -21
  349. package/x/core/parts/sample-map.js.map +0 -1
  350. package/x/core/resolvers/actions.d.ts +0 -2
  351. package/x/core/resolvers/actions.js +0 -23
  352. package/x/core/resolvers/actions.js.map +0 -1
  353. package/x/core/resolvers/intents.d.ts +0 -2
  354. package/x/core/resolvers/intents.js +0 -89
  355. package/x/core/resolvers/intents.js.map +0 -1
  356. package/x/core/types.d.ts +0 -43
  357. package/x/core/types.js +0 -2
  358. package/x/core/types.js.map +0 -1
  359. package/x/deck/controller.d.ts +0 -11
  360. package/x/deck/controller.js +0 -28
  361. package/x/deck/controller.js.map +0 -1
  362. package/x/deck/deck.d.ts +0 -31
  363. package/x/deck/deck.js +0 -68
  364. package/x/deck/deck.js.map +0 -1
  365. package/x/deck/parts/profiles.d.ts +0 -12
  366. package/x/deck/parts/profiles.js +0 -31
  367. package/x/deck/parts/profiles.js.map +0 -1
  368. package/x/deck/parts/runtime.d.ts +0 -8
  369. package/x/deck/parts/runtime.js +0 -7
  370. package/x/deck/parts/runtime.js.map +0 -1
  371. package/x/deck/parts/settings.d.ts +0 -11
  372. package/x/deck/parts/settings.js +0 -26
  373. package/x/deck/parts/settings.js.map +0 -1
  374. package/x/deck/port.d.ts +0 -10
  375. package/x/deck/port.js +0 -24
  376. package/x/deck/port.js.map +0 -1
  377. package/x/deck/types.d.ts +0 -11
  378. package/x/deck/types.js +0 -2
  379. package/x/deck/types.js.map +0 -1
  380. package/x/device/devices.d.ts +0 -7
  381. package/x/device/devices.js +0 -17
  382. package/x/device/devices.js.map +0 -1
  383. package/x/device/gamepad.d.ts +0 -9
  384. package/x/device/gamepad.js +0 -37
  385. package/x/device/gamepad.js.map +0 -1
  386. package/x/device/keyboard.d.ts +0 -6
  387. package/x/device/keyboard.js +0 -30
  388. package/x/device/keyboard.js.map +0 -1
  389. package/x/device/pad/on-pad.js.map +0 -1
  390. package/x/device/pad/pad.js.map +0 -1
  391. package/x/device/pointer.d.ts +0 -12
  392. package/x/device/pointer.js +0 -81
  393. package/x/device/pointer.js.map +0 -1
  394. package/x/device/sampler.d.ts +0 -9
  395. package/x/device/sampler.js +0 -19
  396. package/x/device/sampler.js.map +0 -1
  397. package/x/device/stick.d.ts +0 -14
  398. package/x/device/stick.js +0 -22
  399. package/x/device/stick.js.map +0 -1
  400. package/x/index-ui.d.ts +0 -1
  401. package/x/index-ui.js +0 -2
  402. package/x/index-ui.js.map +0 -1
  403. package/x/index.d.ts +0 -27
  404. package/x/index.js +0 -28
  405. package/x/index.js.map +0 -1
  406. package/x/test.d.ts +0 -9
  407. package/x/test.js +0 -307
  408. package/x/test.js.map +0 -1
  409. package/x/ui/views/desk/style.css.d.ts +0 -2
  410. package/x/ui/views/desk/style.css.js +0 -69
  411. package/x/ui/views/desk/style.css.js.map +0 -1
  412. package/x/ui/views/desk/view.d.ts +0 -7
  413. package/x/ui/views/desk/view.js +0 -102
  414. package/x/ui/views/desk/view.js.map +0 -1
  415. package/x/utils/circular-clamp.d.ts +0 -2
  416. package/x/utils/circular-clamp.js +0 -8
  417. package/x/utils/circular-clamp.js.map +0 -1
  418. package/x/utils/do-async.d.ts +0 -1
  419. package/x/utils/do-async.js +0 -4
  420. package/x/utils/do-async.js.map +0 -1
  421. package/x/utils/evergreen.js.map +0 -1
  422. package/x/utils/freeze-clone.d.ts +0 -1
  423. package/x/utils/freeze-clone.js +0 -5
  424. package/x/utils/freeze-clone.js.map +0 -1
  425. package/x/utils/identifier.d.ts +0 -6
  426. package/x/utils/identifier.js +0 -25
  427. package/x/utils/identifier.js.map +0 -1
  428. package/x/utils/insert.d.ts +0 -1
  429. package/x/utils/insert.js +0 -5
  430. package/x/utils/insert.js.map +0 -1
  431. package/x/utils/is-down.js.map +0 -1
  432. package/x/utils/make-id.d.ts +0 -1
  433. package/x/utils/make-id.js +0 -5
  434. package/x/utils/make-id.js.map +0 -1
  435. package/x/utils/remap.d.ts +0 -1
  436. package/x/utils/remap.js +0 -6
  437. package/x/utils/remap.js.map +0 -1
  438. package/x/utils/shift-limit.d.ts +0 -2
  439. package/x/utils/shift-limit.js +0 -7
  440. package/x/utils/shift-limit.js.map +0 -1
  441. package/x/utils/sort-by-key.d.ts +0 -1
  442. package/x/utils/sort-by-key.js +0 -6
  443. package/x/utils/sort-by-key.js.map +0 -1
  444. package/x/utils/split-axis.js.map +0 -1
  445. package/x/utils/tmax.d.ts +0 -1
  446. package/x/utils/tmax.js +0 -6
  447. package/x/utils/tmax.js.map +0 -1
  448. package/x/utils/tmin.d.ts +0 -1
  449. package/x/utils/tmin.js +0 -6
  450. package/x/utils/tmin.js.map +0 -1
  451. /package/s/{core → _archive/core}/atom/defaults.ts +0 -0
  452. /package/s/{core → _archive/core}/atom/lens-algo.ts +0 -0
  453. /package/s/{core → _archive/core}/atom/types.ts +0 -0
  454. /package/s/{core → _archive/core}/bindings/normalize.ts +0 -0
  455. /package/s/{core → _archive/core}/bindings/shape.ts +0 -0
  456. /package/s/{core → _archive/core}/bindings/table.ts +0 -0
  457. /package/s/{core → _archive/core}/intent/bucket.ts +0 -0
  458. /package/s/{core → _archive/core}/intent/consts.ts +0 -0
  459. /package/s/{core → _archive/core}/intent/decode.ts +0 -0
  460. /package/s/{core → _archive/core}/intent/encode.ts +0 -0
  461. /package/s/{core → _archive/core}/intent/merge.ts +0 -0
  462. /package/s/{core → _archive/core}/parts/action.ts +0 -0
  463. /package/s/{core → _archive/core}/parts/sample-map.ts +0 -0
  464. /package/s/{core → _archive/core}/resolvers/actions.ts +0 -0
  465. /package/s/{core → _archive/core}/resolvers/intents.ts +0 -0
  466. /package/s/{core → _archive/core}/types.ts +0 -0
  467. /package/s/{deck → _archive/deck}/controller.ts +0 -0
  468. /package/s/{deck → _archive/deck}/parts/runtime.ts +0 -0
  469. /package/s/{deck → _archive/deck}/port.ts +0 -0
  470. /package/s/{deck → _archive/deck}/types.ts +0 -0
  471. /package/s/{device → _archive/device}/devices.ts +0 -0
  472. /package/s/{device → _archive/device}/gamepad.ts +0 -0
  473. /package/s/{device → _archive/device}/keyboard.ts +0 -0
  474. /package/s/{device → _archive/device}/pad/on-pad.ts +0 -0
  475. /package/s/{device → _archive/device}/pad/pad.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-4",
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.1",
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-4",
31
- "@e280/kv": "^0.2.1",
32
- "@e280/stz": "^0.3.13"
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
 
@@ -1,6 +1,6 @@
1
1
 
2
2
  import {RMap} from "@e280/strata"
3
- import {inserts, need} from "@e280/stz"
3
+ import {need, setEntries} from "@e280/stz"
4
4
  import {Profile, ProfileKey} from "../types.js"
5
5
 
6
6
  export class Profiles {
@@ -8,7 +8,7 @@ export class Profiles {
8
8
 
9
9
  constructor(stock: Record<ProfileKey, Profile>, public custom: RMap<ProfileKey, Profile>) {
10
10
  this.stock = new RMap<ProfileKey, Profile>()
11
- inserts(this.stock, Object.entries(stock))
11
+ setEntries(this.stock, Object.entries(stock))
12
12
 
13
13
  if (this.stock.size === 0)
14
14
  throw new Error("must be at least one stock profile")
@@ -1,6 +1,6 @@
1
1
 
2
2
  import {RMap} from "@e280/strata"
3
- import {Cubby, inserts} from "@e280/stz"
3
+ import {Cubby, setEntries} from "@e280/stz"
4
4
  import {shiftLimit} from "../../utils/shift-limit.js"
5
5
  import {ControllerHandle, DeckState, Profile, ProfileKey} from "../types.js"
6
6
 
@@ -23,8 +23,8 @@ export class Settings {
23
23
  const state = await this.store.get()
24
24
  this.customProfiles.clear()
25
25
  this.profileAssignments.clear()
26
- inserts(this.customProfiles, state?.customProfiles ?? [])
27
- inserts(this.profileAssignments, state?.profileAssignments ?? [])
26
+ setEntries(this.customProfiles, state?.customProfiles ?? [])
27
+ setEntries(this.profileAssignments, state?.profileAssignments ?? [])
28
28
  }
29
29
  }
30
30
 
@@ -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;
@@ -5,8 +5,8 @@ import {SamplerDevice} from "./sampler.js"
5
5
  import {splitAxis} from "../utils/split-axis.js"
6
6
 
7
7
  export class PointerDevice extends SamplerDevice {
8
- client = new Vec2(0, 0)
9
- movement = new Vec2(0, 0)
8
+ client = new Vec2()
9
+ movement = new Vec2()
10
10
  dispose = disposer()
11
11
 
12
12
  constructor(target: EventTarget = window) {
@@ -74,22 +74,14 @@ export class PointerDevice extends SamplerDevice {
74
74
  }
75
75
 
76
76
  #specialPreProcessing() {
77
- const [x, y] = this.movement
78
- const [left, right] = splitAxis(x)
77
+ const {x, y} = this.movement
78
+ const [right, left] = splitAxis(x)
79
79
  const [down, up] = splitAxis(y)
80
80
 
81
- if (x) {
82
- if (x >= 0)
83
- this.setSample(`pointer.move.right`, Math.abs(right))
84
- else
85
- this.setSample(`pointer.move.left`, Math.abs(left))
86
- }
87
- if (y) {
88
- if (y >= 0)
89
- this.setSample(`pointer.move.up`, Math.abs(up))
90
- else
91
- this.setSample(`pointer.move.down`, Math.abs(down))
92
- }
81
+ this.setSample("pointer.move.left", left)
82
+ this.setSample("pointer.move.right", right)
83
+ this.setSample("pointer.move.up", up)
84
+ this.setSample("pointer.move.down", down)
93
85
 
94
86
  this.movement.set_(0, 0)
95
87
  }
@@ -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
+