@benev/tact 0.2.0-0 → 0.3.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/README.md +48 -390
  2. package/package.json +25 -27
  3. package/s/_archive/README.md +435 -0
  4. package/s/_archive/deck/deck.ts +69 -0
  5. package/s/_archive/demo/main.bundle.ts +10 -0
  6. package/s/_archive/demo/main.css +85 -0
  7. package/s/_archive/index.html.ts +61 -0
  8. package/s/_archive/index.ts +8 -0
  9. package/s/_archive/tests.test.ts +6 -0
  10. package/s/_archive/utils/circular-clamp.ts +14 -0
  11. package/s/_archive/utils/evergreen.ts +10 -0
  12. package/s/_archive/utils/split-axis.ts +15 -0
  13. package/s/assets/b.png +0 -0
  14. package/s/core/atom/defaults.ts +32 -0
  15. package/s/core/atom/lens-algo.ts +84 -0
  16. package/s/core/atom/types.ts +44 -0
  17. package/s/core/bindings/normalize.ts +27 -0
  18. package/s/core/bindings/shape.ts +15 -0
  19. package/s/core/bindings/table.ts +22 -0
  20. package/s/core/intent/bucket.ts +28 -0
  21. package/s/core/intent/consts.ts +4 -0
  22. package/s/core/intent/decode.ts +23 -0
  23. package/s/core/intent/encode.ts +20 -0
  24. package/s/core/intent/merge.ts +15 -0
  25. package/s/core/parts/action.ts +36 -0
  26. package/s/core/parts/sample-map.ts +24 -0
  27. package/s/core/resolvers/actions.ts +30 -0
  28. package/s/core/resolvers/intents.ts +106 -0
  29. package/s/core/types.ts +40 -0
  30. package/s/deck/controller.ts +35 -0
  31. package/s/deck/deck.ts +76 -53
  32. package/s/deck/parts/profiles.ts +39 -0
  33. package/s/deck/parts/runtime.ts +11 -0
  34. package/s/deck/parts/settings.ts +30 -0
  35. package/s/deck/port.ts +35 -0
  36. package/s/deck/types.ts +16 -0
  37. package/s/demo/demo-app/element.ts +17 -0
  38. package/s/demo/demo-app/style.css.ts +10 -0
  39. package/s/demo/main.bundle.ts +67 -6
  40. package/s/demo/main.css +6 -8
  41. package/s/device/devices.ts +24 -0
  42. package/s/device/gamepad.ts +42 -0
  43. package/s/device/keyboard.ts +33 -0
  44. package/s/device/pad/on-pad.ts +50 -0
  45. package/s/device/pad/pad.ts +10 -0
  46. package/s/device/pointer.ts +97 -0
  47. package/s/device/sampler.ts +25 -0
  48. package/s/device/stick.ts +24 -0
  49. package/s/gamepad/gamepad-app/element.ts +65 -0
  50. package/s/gamepad/gamepad-app/style.css.ts +73 -0
  51. package/s/gamepad/index.html.ts +44 -0
  52. package/s/gamepad/main.bundle.ts +6 -0
  53. package/s/gamepad/main.css +60 -0
  54. package/s/index-ui.ts +3 -0
  55. package/s/index.html.ts +10 -17
  56. package/s/index.ts +28 -5
  57. package/s/test.ts +339 -0
  58. package/s/ui/views/desk/style.css.ts +70 -0
  59. package/s/ui/views/desk/view.ts +122 -0
  60. package/s/utils/circular-clamp.ts +2 -2
  61. package/s/utils/do-async.ts +5 -0
  62. package/s/utils/freeze-clone.ts +7 -0
  63. package/s/utils/identifier.ts +30 -0
  64. package/s/utils/insert.ts +6 -0
  65. package/s/utils/is-down.ts +5 -0
  66. package/s/utils/make-id.ts +7 -0
  67. package/s/utils/remap.ts +7 -0
  68. package/s/utils/shift-limit.ts +9 -0
  69. package/s/utils/sort-by-key.ts +7 -0
  70. package/s/utils/tmax.ts +7 -0
  71. package/s/utils/tmin.ts +7 -0
  72. package/x/_archive/demo/main.css +85 -0
  73. package/x/assets/b.png +0 -0
  74. package/x/core/{bindings/parts → atom}/defaults.d.ts +1 -1
  75. package/x/core/atom/defaults.js.map +1 -0
  76. package/x/core/{bindings/parts → atom}/lens-algo.d.ts +1 -1
  77. package/x/core/{bindings/parts → atom}/lens-algo.js +8 -8
  78. package/x/core/atom/lens-algo.js.map +1 -0
  79. package/x/core/{bindings → atom}/types.d.ts +1 -15
  80. package/x/core/{devices → atom}/types.js.map +1 -1
  81. package/x/core/bindings/normalize.d.ts +2 -0
  82. package/x/core/bindings/normalize.js +17 -0
  83. package/x/core/bindings/normalize.js.map +1 -0
  84. package/x/core/bindings/shape.d.ts +2 -0
  85. package/x/core/bindings/shape.js +10 -0
  86. package/x/core/bindings/shape.js.map +1 -0
  87. package/x/core/bindings/table.d.ts +2 -0
  88. package/x/core/bindings/table.js +15 -0
  89. package/x/core/bindings/table.js.map +1 -0
  90. package/x/core/intent/bucket.d.ts +7 -0
  91. package/x/core/intent/bucket.js +21 -0
  92. package/x/core/intent/bucket.js.map +1 -0
  93. package/x/core/intent/consts.d.ts +2 -0
  94. package/x/core/intent/consts.js +3 -0
  95. package/x/core/intent/consts.js.map +1 -0
  96. package/x/core/intent/decode.d.ts +3 -0
  97. package/x/core/intent/decode.js +18 -0
  98. package/x/core/intent/decode.js.map +1 -0
  99. package/x/core/intent/encode.d.ts +3 -0
  100. package/x/core/intent/encode.js +15 -0
  101. package/x/core/intent/encode.js.map +1 -0
  102. package/x/core/intent/merge.d.ts +3 -0
  103. package/x/core/intent/merge.js +10 -0
  104. package/x/core/intent/merge.js.map +1 -0
  105. package/x/core/{bindings → parts}/action.d.ts +5 -3
  106. package/x/core/parts/action.js +30 -0
  107. package/x/core/parts/action.js.map +1 -0
  108. package/x/core/parts/sample-map.d.ts +6 -0
  109. package/x/core/{bindings → parts}/sample-map.js +2 -3
  110. package/x/core/parts/sample-map.js.map +1 -0
  111. package/x/core/resolvers/actions.d.ts +2 -0
  112. package/x/core/resolvers/actions.js +23 -0
  113. package/x/core/resolvers/actions.js.map +1 -0
  114. package/x/core/resolvers/intents.d.ts +2 -0
  115. package/x/core/{bindings/resolver.js → resolvers/intents.js} +39 -43
  116. package/x/core/resolvers/intents.js.map +1 -0
  117. package/x/core/types.d.ts +43 -0
  118. package/x/core/types.js +2 -0
  119. package/x/core/types.js.map +1 -0
  120. package/x/deck/controller.d.ts +11 -0
  121. package/x/deck/controller.js +28 -0
  122. package/x/deck/controller.js.map +1 -0
  123. package/x/deck/deck.d.ts +30 -26
  124. package/x/deck/deck.js +64 -43
  125. package/x/deck/deck.js.map +1 -1
  126. package/x/deck/parts/profiles.d.ts +12 -0
  127. package/x/deck/parts/profiles.js +31 -0
  128. package/x/deck/parts/profiles.js.map +1 -0
  129. package/x/deck/parts/runtime.d.ts +8 -0
  130. package/x/deck/parts/runtime.js +7 -0
  131. package/x/deck/parts/runtime.js.map +1 -0
  132. package/x/deck/parts/settings.d.ts +11 -0
  133. package/x/deck/parts/settings.js +26 -0
  134. package/x/deck/parts/settings.js.map +1 -0
  135. package/x/deck/port.d.ts +10 -0
  136. package/x/deck/port.js +24 -0
  137. package/x/deck/port.js.map +1 -0
  138. package/x/deck/types.d.ts +11 -0
  139. package/x/deck/types.js +2 -0
  140. package/x/deck/types.js.map +1 -0
  141. package/x/demo/demo-app/element.d.ts +3 -0
  142. package/x/demo/demo-app/element.js +13 -0
  143. package/x/demo/demo-app/element.js.map +1 -0
  144. package/x/demo/demo-app/style.css.js +9 -0
  145. package/x/demo/demo-app/style.css.js.map +1 -0
  146. package/x/demo/main.bundle.js +53 -5
  147. package/x/demo/main.bundle.js.map +1 -1
  148. package/x/demo/main.bundle.min.js +107 -385
  149. package/x/demo/main.bundle.min.js.LEGAL.txt +33 -0
  150. package/x/demo/main.bundle.min.js.map +4 -4
  151. package/x/demo/main.css +6 -8
  152. package/x/device/devices.d.ts +7 -0
  153. package/x/device/devices.js +17 -0
  154. package/x/device/devices.js.map +1 -0
  155. package/x/device/gamepad.d.ts +9 -0
  156. package/x/device/gamepad.js +37 -0
  157. package/x/device/gamepad.js.map +1 -0
  158. package/x/{core/devices/standard → device}/keyboard.d.ts +1 -1
  159. package/x/{core/devices/standard → device}/keyboard.js +4 -2
  160. package/x/device/keyboard.js.map +1 -0
  161. package/x/device/pad/on-pad.d.ts +3 -0
  162. package/x/device/pad/on-pad.js +42 -0
  163. package/x/device/pad/on-pad.js.map +1 -0
  164. package/x/device/pad/pad.d.ts +6 -0
  165. package/x/device/pad/pad.js +11 -0
  166. package/x/device/pad/pad.js.map +1 -0
  167. package/x/{core/devices/standard → device}/pointer.d.ts +2 -2
  168. package/x/{core/devices/standard → device}/pointer.js +4 -4
  169. package/x/device/pointer.js.map +1 -0
  170. package/x/device/sampler.d.ts +9 -0
  171. package/x/device/sampler.js +19 -0
  172. package/x/device/sampler.js.map +1 -0
  173. package/x/{core/devices/standard → device}/stick.d.ts +2 -3
  174. package/x/{core/devices/standard → device}/stick.js +4 -6
  175. package/x/device/stick.js.map +1 -0
  176. package/x/gamepad/gamepad-app/element.d.ts +1 -0
  177. package/x/gamepad/gamepad-app/element.js +54 -0
  178. package/x/gamepad/gamepad-app/element.js.map +1 -0
  179. package/x/gamepad/gamepad-app/style.css.js +72 -0
  180. package/x/gamepad/gamepad-app/style.css.js.map +1 -0
  181. package/x/gamepad/index.html +35 -0
  182. package/x/gamepad/index.html.d.ts +2 -0
  183. package/x/gamepad/index.html.js +41 -0
  184. package/x/gamepad/index.html.js.map +1 -0
  185. package/x/gamepad/main.bundle.js +4 -0
  186. package/x/gamepad/main.bundle.js.map +1 -0
  187. package/x/gamepad/main.bundle.min.js +126 -0
  188. package/x/gamepad/main.bundle.min.js.LEGAL.txt +33 -0
  189. package/x/gamepad/main.bundle.min.js.map +7 -0
  190. package/x/gamepad/main.css +60 -0
  191. package/x/index-ui.d.ts +1 -0
  192. package/x/index-ui.js +2 -0
  193. package/x/index-ui.js.map +1 -0
  194. package/x/index.d.ts +27 -5
  195. package/x/index.html +17 -24
  196. package/x/index.html.js +10 -17
  197. package/x/index.html.js.map +1 -1
  198. package/x/index.js +27 -5
  199. package/x/index.js.map +1 -1
  200. package/x/test.d.ts +9 -0
  201. package/x/test.js +307 -0
  202. package/x/test.js.map +1 -0
  203. package/x/ui/views/desk/style.css.js +69 -0
  204. package/x/ui/views/desk/style.css.js.map +1 -0
  205. package/x/ui/views/desk/view.d.ts +7 -0
  206. package/x/ui/views/desk/view.js +102 -0
  207. package/x/ui/views/desk/view.js.map +1 -0
  208. package/x/utils/circular-clamp.js +2 -2
  209. package/x/utils/circular-clamp.js.map +1 -1
  210. package/x/utils/do-async.d.ts +1 -0
  211. package/x/utils/do-async.js +4 -0
  212. package/x/utils/do-async.js.map +1 -0
  213. package/x/utils/freeze-clone.d.ts +1 -0
  214. package/x/utils/freeze-clone.js +5 -0
  215. package/x/utils/freeze-clone.js.map +1 -0
  216. package/x/utils/identifier.d.ts +6 -0
  217. package/x/utils/identifier.js +25 -0
  218. package/x/utils/identifier.js.map +1 -0
  219. package/x/utils/insert.d.ts +1 -0
  220. package/x/utils/insert.js +5 -0
  221. package/x/utils/insert.js.map +1 -0
  222. package/x/utils/is-down.d.ts +1 -0
  223. package/x/utils/is-down.js +4 -0
  224. package/x/utils/is-down.js.map +1 -0
  225. package/x/utils/make-id.d.ts +1 -0
  226. package/x/utils/make-id.js +5 -0
  227. package/x/utils/make-id.js.map +1 -0
  228. package/x/utils/remap.d.ts +1 -0
  229. package/x/utils/remap.js +6 -0
  230. package/x/utils/remap.js.map +1 -0
  231. package/x/utils/shift-limit.d.ts +2 -0
  232. package/x/utils/shift-limit.js +7 -0
  233. package/x/utils/shift-limit.js.map +1 -0
  234. package/x/utils/sort-by-key.d.ts +1 -0
  235. package/x/utils/sort-by-key.js +6 -0
  236. package/x/utils/sort-by-key.js.map +1 -0
  237. package/x/utils/{quick-math.d.ts → tmax.d.ts} +0 -1
  238. package/x/utils/tmax.js +6 -0
  239. package/x/utils/tmax.js.map +1 -0
  240. package/x/utils/tmin.d.ts +1 -0
  241. package/x/utils/tmin.js +6 -0
  242. package/x/utils/tmin.js.map +1 -0
  243. package/s/tests.test.ts +0 -6
  244. package/x/core/bindings/action.js +0 -24
  245. package/x/core/bindings/action.js.map +0 -1
  246. package/x/core/bindings/parts/defaults.js.map +0 -1
  247. package/x/core/bindings/parts/is-pressed.d.ts +0 -1
  248. package/x/core/bindings/parts/is-pressed.js +0 -4
  249. package/x/core/bindings/parts/is-pressed.js.map +0 -1
  250. package/x/core/bindings/parts/lens-algo.js.map +0 -1
  251. package/x/core/bindings/parts/lookup-proxies.js +0 -19
  252. package/x/core/bindings/parts/lookup-proxies.js.map +0 -1
  253. package/x/core/bindings/resolver.d.ts +0 -9
  254. package/x/core/bindings/resolver.js.map +0 -1
  255. package/x/core/bindings/sample-map.d.ts +0 -7
  256. package/x/core/bindings/sample-map.js.map +0 -1
  257. package/x/core/bindings/types.js +0 -4
  258. package/x/core/bindings/types.js.map +0 -1
  259. package/x/core/core.test.d.ts +0 -13
  260. package/x/core/core.test.js +0 -138
  261. package/x/core/core.test.js.map +0 -1
  262. package/x/core/devices/auto-gamepads.d.ts +0 -2
  263. package/x/core/devices/auto-gamepads.js +0 -6
  264. package/x/core/devices/auto-gamepads.js.map +0 -1
  265. package/x/core/devices/device.d.ts +0 -5
  266. package/x/core/devices/device.js +0 -7
  267. package/x/core/devices/device.js.map +0 -1
  268. package/x/core/devices/infra/group.d.ts +0 -7
  269. package/x/core/devices/infra/group.js +0 -21
  270. package/x/core/devices/infra/group.js.map +0 -1
  271. package/x/core/devices/infra/sampler.d.ts +0 -9
  272. package/x/core/devices/infra/sampler.js +0 -18
  273. package/x/core/devices/infra/sampler.js.map +0 -1
  274. package/x/core/devices/standard/gamepad.d.ts +0 -11
  275. package/x/core/devices/standard/gamepad.js +0 -65
  276. package/x/core/devices/standard/gamepad.js.map +0 -1
  277. package/x/core/devices/standard/index.d.ts +0 -6
  278. package/x/core/devices/standard/index.js +0 -7
  279. package/x/core/devices/standard/index.js.map +0 -1
  280. package/x/core/devices/standard/keyboard.js.map +0 -1
  281. package/x/core/devices/standard/pointer.js.map +0 -1
  282. package/x/core/devices/standard/primary.d.ts +0 -10
  283. package/x/core/devices/standard/primary.js +0 -17
  284. package/x/core/devices/standard/primary.js.map +0 -1
  285. package/x/core/devices/standard/stick.js.map +0 -1
  286. package/x/core/devices/standard/vpad.d.ts +0 -7
  287. package/x/core/devices/standard/vpad.js +0 -20
  288. package/x/core/devices/standard/vpad.js.map +0 -1
  289. package/x/core/devices/types.d.ts +0 -1
  290. package/x/core/hub/hub.d.ts +0 -32
  291. package/x/core/hub/hub.js +0 -101
  292. package/x/core/hub/hub.js.map +0 -1
  293. package/x/core/hub/meta-bindings.d.ts +0 -2
  294. package/x/core/hub/meta-bindings.js +0 -21
  295. package/x/core/hub/meta-bindings.js.map +0 -1
  296. package/x/core/hub/parts/connected.d.ts +0 -14
  297. package/x/core/hub/parts/connected.js +0 -12
  298. package/x/core/hub/parts/connected.js.map +0 -1
  299. package/x/core/hub/port.d.ts +0 -9
  300. package/x/core/hub/port.js +0 -19
  301. package/x/core/hub/port.js.map +0 -1
  302. package/x/core/hub/types.d.ts +0 -9
  303. package/x/core/hub/types.js +0 -2
  304. package/x/core/hub/types.js.map +0 -1
  305. package/x/core/index.d.ts +0 -15
  306. package/x/core/index.js +0 -16
  307. package/x/core/index.js.map +0 -1
  308. package/x/core/testing/testing.d.ts +0 -52
  309. package/x/core/testing/testing.js +0 -45
  310. package/x/core/testing/testing.js.map +0 -1
  311. package/x/deck/index.d.ts +0 -9
  312. package/x/deck/index.js +0 -10
  313. package/x/deck/index.js.map +0 -1
  314. package/x/deck/parts/catalog.d.ts +0 -22
  315. package/x/deck/parts/catalog.js +0 -35
  316. package/x/deck/parts/catalog.js.map +0 -1
  317. package/x/deck/parts/db.d.ts +0 -17
  318. package/x/deck/parts/db.js +0 -52
  319. package/x/deck/parts/db.js.map +0 -1
  320. package/x/deck/parts/device-skins/device-icons.d.ts +0 -12
  321. package/x/deck/parts/device-skins/device-icons.js +0 -27
  322. package/x/deck/parts/device-skins/device-icons.js.map +0 -1
  323. package/x/deck/parts/device-skins/device-skin.d.ts +0 -14
  324. package/x/deck/parts/device-skins/device-skin.js +0 -22
  325. package/x/deck/parts/device-skins/device-skin.js.map +0 -1
  326. package/x/deck/parts/local-storage-kv.d.ts +0 -2
  327. package/x/deck/parts/local-storage-kv.js +0 -6
  328. package/x/deck/parts/local-storage-kv.js.map +0 -1
  329. package/x/deck/parts/merge-bindings.d.ts +0 -2
  330. package/x/deck/parts/merge-bindings.js +0 -15
  331. package/x/deck/parts/merge-bindings.js.map +0 -1
  332. package/x/deck/parts/overlay-visibility.d.ts +0 -18
  333. package/x/deck/parts/overlay-visibility.js +0 -35
  334. package/x/deck/parts/overlay-visibility.js.map +0 -1
  335. package/x/deck/views/bindings/style.css.js +0 -5
  336. package/x/deck/views/bindings/style.css.js.map +0 -1
  337. package/x/deck/views/bindings/view.d.ts +0 -2
  338. package/x/deck/views/bindings/view.js +0 -80
  339. package/x/deck/views/bindings/view.js.map +0 -1
  340. package/x/deck/views/overlay/style.css.js +0 -109
  341. package/x/deck/views/overlay/style.css.js.map +0 -1
  342. package/x/deck/views/overlay/view.d.ts +0 -2
  343. package/x/deck/views/overlay/view.js +0 -40
  344. package/x/deck/views/overlay/view.js.map +0 -1
  345. package/x/demo/game/game.d.ts +0 -17
  346. package/x/demo/game/game.js +0 -63
  347. package/x/demo/game/game.js.map +0 -1
  348. package/x/demo/game/parts/agent.d.ts +0 -7
  349. package/x/demo/game/parts/agent.js +0 -8
  350. package/x/demo/game/parts/agent.js.map +0 -1
  351. package/x/demo/game/parts/game-bindings.d.ts +0 -15
  352. package/x/demo/game/parts/game-bindings.js +0 -10
  353. package/x/demo/game/parts/game-bindings.js.map +0 -1
  354. package/x/demo/game/parts/logic.d.ts +0 -8
  355. package/x/demo/game/parts/logic.js +0 -21
  356. package/x/demo/game/parts/logic.js.map +0 -1
  357. package/x/demo/game/parts/player.d.ts +0 -14
  358. package/x/demo/game/parts/player.js +0 -26
  359. package/x/demo/game/parts/player.js.map +0 -1
  360. package/x/demo/game/parts/renderer.d.ts +0 -13
  361. package/x/demo/game/parts/renderer.js +0 -91
  362. package/x/demo/game/parts/renderer.js.map +0 -1
  363. package/x/demo/game/parts/state.d.ts +0 -8
  364. package/x/demo/game/parts/state.js +0 -20
  365. package/x/demo/game/parts/state.js.map +0 -1
  366. package/x/demo/game/parts/virtual-device.d.ts +0 -8
  367. package/x/demo/game/parts/virtual-device.js +0 -11
  368. package/x/demo/game/parts/virtual-device.js.map +0 -1
  369. package/x/demo/ui/theater/styles.css.d.ts +0 -1
  370. package/x/demo/ui/theater/styles.css.js +0 -57
  371. package/x/demo/ui/theater/styles.css.js.map +0 -1
  372. package/x/demo/ui/theater/view.d.ts +0 -2
  373. package/x/demo/ui/theater/view.js +0 -45
  374. package/x/demo/ui/theater/view.js.map +0 -1
  375. package/x/demo/ui/theater/virtual/style.css.js +0 -42
  376. package/x/demo/ui/theater/virtual/style.css.js.map +0 -1
  377. package/x/demo/ui/theater/virtual/view.d.ts +0 -4
  378. package/x/demo/ui/theater/virtual/view.js +0 -19
  379. package/x/demo/ui/theater/virtual/view.js.map +0 -1
  380. package/x/demo/ui/utils/loader.d.ts +0 -2
  381. package/x/demo/ui/utils/loader.js +0 -3
  382. package/x/demo/ui/utils/loader.js.map +0 -1
  383. package/x/nubs/index.d.ts +0 -3
  384. package/x/nubs/index.js +0 -4
  385. package/x/nubs/index.js.map +0 -1
  386. package/x/nubs/lookpad/styles.d.ts +0 -1
  387. package/x/nubs/lookpad/styles.js +0 -21
  388. package/x/nubs/lookpad/styles.js.map +0 -1
  389. package/x/nubs/lookpad/view.d.ts +0 -1
  390. package/x/nubs/lookpad/view.js +0 -33
  391. package/x/nubs/lookpad/view.js.map +0 -1
  392. package/x/nubs/stick/style.css.d.ts +0 -2
  393. package/x/nubs/stick/style.css.js +0 -69
  394. package/x/nubs/stick/style.css.js.map +0 -1
  395. package/x/nubs/stick/view.d.ts +0 -2
  396. package/x/nubs/stick/view.js +0 -95
  397. package/x/nubs/stick/view.js.map +0 -1
  398. package/x/nubs/vpad/styles.css.d.ts +0 -2
  399. package/x/nubs/vpad/styles.css.js +0 -133
  400. package/x/nubs/vpad/styles.css.js.map +0 -1
  401. package/x/nubs/vpad/utils/gamepad-inputs.d.ts +0 -29
  402. package/x/nubs/vpad/utils/gamepad-inputs.js +0 -31
  403. package/x/nubs/vpad/utils/gamepad-inputs.js.map +0 -1
  404. package/x/nubs/vpad/utils/prevent-default-touch-shenanigans.d.ts +0 -1
  405. package/x/nubs/vpad/utils/prevent-default-touch-shenanigans.js +0 -9
  406. package/x/nubs/vpad/utils/prevent-default-touch-shenanigans.js.map +0 -1
  407. package/x/nubs/vpad/utils/touch-tracking.d.ts +0 -6
  408. package/x/nubs/vpad/utils/touch-tracking.js +0 -55
  409. package/x/nubs/vpad/utils/touch-tracking.js.map +0 -1
  410. package/x/nubs/vpad/view.d.ts +0 -2
  411. package/x/nubs/vpad/view.js +0 -123
  412. package/x/nubs/vpad/view.js.map +0 -1
  413. package/x/tests.test.d.ts +0 -1
  414. package/x/tests.test.js +0 -4
  415. package/x/tests.test.js.map +0 -1
  416. package/x/utils/dispensers.d.ts +0 -7
  417. package/x/utils/dispensers.js +0 -16
  418. package/x/utils/dispensers.js.map +0 -1
  419. package/x/utils/gamepads.d.ts +0 -14
  420. package/x/utils/gamepads.js +0 -40
  421. package/x/utils/gamepads.js.map +0 -1
  422. package/x/utils/quick-math.js +0 -11
  423. package/x/utils/quick-math.js.map +0 -1
  424. /package/s/{core → _archive/core}/bindings/action.ts +0 -0
  425. /package/s/{core → _archive/core}/bindings/parts/defaults.ts +0 -0
  426. /package/s/{core → _archive/core}/bindings/parts/is-pressed.ts +0 -0
  427. /package/s/{core → _archive/core}/bindings/parts/lens-algo.ts +0 -0
  428. /package/s/{core → _archive/core}/bindings/parts/lookup-proxies.ts +0 -0
  429. /package/s/{core → _archive/core}/bindings/resolver.ts +0 -0
  430. /package/s/{core → _archive/core}/bindings/sample-map.ts +0 -0
  431. /package/s/{core → _archive/core}/bindings/types.ts +0 -0
  432. /package/s/{core → _archive/core}/core.test.ts +0 -0
  433. /package/s/{core → _archive/core}/devices/auto-gamepads.ts +0 -0
  434. /package/s/{core → _archive/core}/devices/device.ts +0 -0
  435. /package/s/{core → _archive/core}/devices/infra/group.ts +0 -0
  436. /package/s/{core → _archive/core}/devices/infra/sampler.ts +0 -0
  437. /package/s/{core → _archive/core}/devices/standard/gamepad.ts +0 -0
  438. /package/s/{core → _archive/core}/devices/standard/index.ts +0 -0
  439. /package/s/{core → _archive/core}/devices/standard/keyboard.ts +0 -0
  440. /package/s/{core → _archive/core}/devices/standard/pointer.ts +0 -0
  441. /package/s/{core → _archive/core}/devices/standard/primary.ts +0 -0
  442. /package/s/{core → _archive/core}/devices/standard/stick.ts +0 -0
  443. /package/s/{core → _archive/core}/devices/standard/vpad.ts +0 -0
  444. /package/s/{core → _archive/core}/devices/types.ts +0 -0
  445. /package/s/{core → _archive/core}/hub/hub.ts +0 -0
  446. /package/s/{core → _archive/core}/hub/meta-bindings.ts +0 -0
  447. /package/s/{core → _archive/core}/hub/parts/connected.ts +0 -0
  448. /package/s/{core → _archive/core}/hub/port.ts +0 -0
  449. /package/s/{core → _archive/core}/hub/types.ts +0 -0
  450. /package/s/{core → _archive/core}/index.ts +0 -0
  451. /package/s/{core → _archive/core}/testing/testing.ts +0 -0
  452. /package/s/{deck → _archive/deck}/index.ts +0 -0
  453. /package/s/{deck → _archive/deck}/parts/catalog.ts +0 -0
  454. /package/s/{deck → _archive/deck}/parts/db.ts +0 -0
  455. /package/s/{deck → _archive/deck}/parts/device-skins/device-icons.ts +0 -0
  456. /package/s/{deck → _archive/deck}/parts/device-skins/device-skin.ts +0 -0
  457. /package/s/{deck → _archive/deck}/parts/local-storage-kv.ts +0 -0
  458. /package/s/{deck → _archive/deck}/parts/merge-bindings.ts +0 -0
  459. /package/s/{deck → _archive/deck}/parts/overlay-visibility.ts +0 -0
  460. /package/s/{deck → _archive/deck}/views/bindings/style.css.ts +0 -0
  461. /package/s/{deck → _archive/deck}/views/bindings/view.ts +0 -0
  462. /package/s/{deck → _archive/deck}/views/overlay/style.css.ts +0 -0
  463. /package/s/{deck → _archive/deck}/views/overlay/view.ts +0 -0
  464. /package/s/{demo → _archive/demo}/game/game.ts +0 -0
  465. /package/s/{demo → _archive/demo}/game/parts/agent.ts +0 -0
  466. /package/s/{demo → _archive/demo}/game/parts/game-bindings.ts +0 -0
  467. /package/s/{demo → _archive/demo}/game/parts/logic.ts +0 -0
  468. /package/s/{demo → _archive/demo}/game/parts/player.ts +0 -0
  469. /package/s/{demo → _archive/demo}/game/parts/renderer.ts +0 -0
  470. /package/s/{demo → _archive/demo}/game/parts/state.ts +0 -0
  471. /package/s/{demo → _archive/demo}/game/parts/virtual-device.ts +0 -0
  472. /package/s/{demo → _archive/demo}/ui/theater/styles.css.ts +0 -0
  473. /package/s/{demo → _archive/demo}/ui/theater/view.ts +0 -0
  474. /package/s/{demo → _archive/demo}/ui/theater/virtual/style.css.ts +0 -0
  475. /package/s/{demo → _archive/demo}/ui/theater/virtual/view.ts +0 -0
  476. /package/s/{demo → _archive/demo}/ui/utils/loader.ts +0 -0
  477. /package/s/{nubs → _archive/nubs}/index.ts +0 -0
  478. /package/s/{nubs → _archive/nubs}/lookpad/styles.ts +0 -0
  479. /package/s/{nubs → _archive/nubs}/lookpad/view.ts +0 -0
  480. /package/s/{nubs → _archive/nubs}/stick/style.css.ts +0 -0
  481. /package/s/{nubs → _archive/nubs}/stick/view.ts +0 -0
  482. /package/s/{nubs → _archive/nubs}/vpad/styles.css.ts +0 -0
  483. /package/s/{nubs → _archive/nubs}/vpad/utils/gamepad-inputs.ts +0 -0
  484. /package/s/{nubs → _archive/nubs}/vpad/utils/prevent-default-touch-shenanigans.ts +0 -0
  485. /package/s/{nubs → _archive/nubs}/vpad/utils/touch-tracking.ts +0 -0
  486. /package/s/{nubs → _archive/nubs}/vpad/view.ts +0 -0
  487. /package/s/{utils → _archive/utils}/dispensers.ts +0 -0
  488. /package/s/{utils → _archive/utils}/gamepads.ts +0 -0
  489. /package/s/{utils → _archive/utils}/quick-math.ts +0 -0
  490. /package/x/core/{bindings/parts → atom}/defaults.js +0 -0
  491. /package/x/core/{devices → atom}/types.js +0 -0
  492. /package/x/{deck/views/bindings → demo/demo-app}/style.css.d.ts +0 -0
  493. /package/x/{deck/views/overlay → gamepad/gamepad-app}/style.css.d.ts +0 -0
  494. /package/x/{core/bindings/parts/lookup-proxies.d.ts → gamepad/main.bundle.d.ts} +0 -0
  495. /package/x/{demo/ui/theater/virtual → ui/views/desk}/style.css.d.ts +0 -0
@@ -0,0 +1,15 @@
1
+
2
+ import {Xy} from "@benev/math"
3
+
4
+ export function splitAxis(n: number) {
5
+ return (n >= 0)
6
+ ? [n, 0]
7
+ : [0, Math.abs(n)]
8
+ }
9
+
10
+ export function splitVector(vector: Xy) {
11
+ const [right, left] = splitAxis(vector.x)
12
+ const [down, up] = splitAxis(vector.y)
13
+ return {up, down, left, right}
14
+ }
15
+
package/s/assets/b.png ADDED
Binary file
@@ -0,0 +1,32 @@
1
+
2
+ import {Code, CodeSettings, CodeState} from "./types.js"
3
+
4
+ export const defaultHoldTime = 250
5
+
6
+ export function defaultCodeState([,,settings]: Code, now: number): CodeState {
7
+ return {
8
+ lastValue: 0,
9
+ holdStart: now,
10
+ settings: defaultifyCodeSettings(settings),
11
+ }
12
+ }
13
+
14
+ function defaultCodeSettings(): CodeSettings {
15
+ return {
16
+ scale: 1,
17
+ invert: false,
18
+ clamp: null,
19
+ range: null,
20
+ bottom: null,
21
+ top: null,
22
+ timing: ["direct"],
23
+ }
24
+ }
25
+
26
+ function defaultifyCodeSettings(partial: Partial<CodeSettings> = {}): CodeSettings {
27
+ return {
28
+ ...defaultCodeSettings(),
29
+ ...partial,
30
+ }
31
+ }
32
+
@@ -0,0 +1,84 @@
1
+
2
+ import {pipe} from "@e280/stz"
3
+ import {CodeState} from "./types.js"
4
+ import {defaultHoldTime} from "./defaults.js"
5
+ import {isDown} from "../../utils/is-down.js"
6
+ import {between, clamp, remap} from "@benev/math"
7
+
8
+ export const lensAlgo = (
9
+ now: number,
10
+ state: CodeState,
11
+ v: number,
12
+ ) => pipe(v).line(
13
+
14
+ function clippings(value) {
15
+ const {settings} = state
16
+ if (settings.clamp) {
17
+ const [bottom, top] = settings.clamp
18
+ value = clamp(value, bottom, top)
19
+ }
20
+ if (settings.range) {
21
+ const [bottom, top] = settings.range
22
+ value = between(value, bottom, top)
23
+ ? remap(
24
+ value,
25
+ bottom, top,
26
+ 0, 1,
27
+ true,
28
+ )
29
+ : 0
30
+ }
31
+ if (settings.bottom) value = (value < settings.bottom) ? 0 : value
32
+ if (settings.top) value = Math.min(settings.top, value)
33
+ return value
34
+ },
35
+
36
+ function inversion(value) {
37
+ return state.settings.invert
38
+ ? 1 - value
39
+ : value
40
+ },
41
+
42
+ function scaling(value) {
43
+ return state.settings.scale * value
44
+ },
45
+
46
+ function timing(value) {
47
+ const {settings} = state
48
+
49
+ const holdTime = (
50
+ settings.timing[0] === "direct"
51
+ ? undefined
52
+ : settings.timing[1]
53
+ ) ?? defaultHoldTime
54
+
55
+ const isFreshlyPressed = !isDown(state.lastValue) && isDown(value)
56
+ const isFreshlyReleased = isDown(state.lastValue) && !isDown(value)
57
+
58
+ if (isFreshlyPressed)
59
+ state.holdStart = now
60
+
61
+ const isHolding = (now - state.holdStart) >= holdTime
62
+
63
+ state.lastValue = value
64
+
65
+ switch (settings.timing[0]) {
66
+ case "direct":
67
+ return value
68
+
69
+ case "tap":
70
+ return (isFreshlyReleased && !isHolding)
71
+ ? 1
72
+ : 0
73
+
74
+ case "hold":
75
+ return (isDown(value) && isHolding)
76
+ ? value
77
+ : 0
78
+
79
+ default:
80
+ throw new Error(`unknown bindings timing`)
81
+ }
82
+ },
83
+ )
84
+
@@ -0,0 +1,44 @@
1
+
2
+ export type Atom = string | (
3
+ | Code
4
+ | And
5
+ | Or
6
+ | Not
7
+ | Cond
8
+ | Mods
9
+ )
10
+
11
+ export type Code = ["code", string, settings?: Partial<CodeSettings>]
12
+ export type And = ["and", ...Atom[]]
13
+ export type Or = ["or", ...Atom[]]
14
+ export type Not = ["not", Atom]
15
+ export type Cond = ["cond", Atom, guard: Atom]
16
+ export type Mods = ["mods", Atom, modifiers: Partial<Modifiers>]
17
+
18
+ export type CodeSettings = {
19
+ scale: number
20
+ invert: boolean
21
+ clamp: null | [number, number]
22
+ range: null | [number, number]
23
+ bottom: null | number
24
+ top: null | number
25
+ timing: (
26
+ | ["direct"]
27
+ | ["tap", holdTime?: number]
28
+ | ["hold", holdTime?: number]
29
+ )
30
+ }
31
+
32
+ export type CodeState = {
33
+ settings: CodeSettings
34
+ lastValue: number
35
+ holdStart: number
36
+ }
37
+
38
+ export type Modifiers = {
39
+ ctrl: boolean
40
+ alt: boolean
41
+ shift: boolean
42
+ meta: boolean
43
+ }
44
+
@@ -0,0 +1,27 @@
1
+
2
+ import {deep, is} from "@e280/stz"
3
+ import {Bindings} from "../types.js"
4
+
5
+ export function normalizeBindings<B extends Bindings>(
6
+ standard: B,
7
+ suspect: any,
8
+ ): B {
9
+
10
+ const fresh = deep.clone(standard)
11
+
12
+ if (!is.object(suspect))
13
+ return fresh
14
+
15
+ for (const [modeName, freshBracket] of Object.entries(fresh)) {
16
+ const suspectBracket = suspect[modeName]
17
+ if (!is.object(suspectBracket)) continue
18
+
19
+ for (const [actionName, freshAtom] of Object.entries(freshBracket)) {
20
+ const suspectAtom = suspectBracket[actionName]
21
+ freshBracket[actionName] = suspectAtom ?? freshAtom
22
+ }
23
+ }
24
+
25
+ return fresh
26
+ }
27
+
@@ -0,0 +1,15 @@
1
+
2
+ import {obMap} from "@e280/stz"
3
+ import {bindingsTable} from "./table.js"
4
+ import {Bindings, BindingsShape} from "../types.js"
5
+
6
+ export function bindingsShape<B extends Bindings>(data: B) {
7
+ const table = bindingsTable(data)
8
+ const shape = obMap(data, bracket => obMap(bracket, () => 0)) as any
9
+
10
+ for (const [id, {mode, action}] of table)
11
+ shape[mode][action] = id
12
+
13
+ return shape as BindingsShape<B>
14
+ }
15
+
@@ -0,0 +1,22 @@
1
+
2
+ import {Bindings, BindingsRow} from "../types.js"
3
+ import {sortByKey} from "../../utils/sort-by-key.js"
4
+
5
+ export function bindingsTable<B extends Bindings>(data: B) {
6
+ data = structuredClone(data)
7
+ const table = new Map<number, BindingsRow<B>>()
8
+
9
+ Object.entries(data)
10
+ .sort(sortByKey)
11
+ .flatMap(([mode, bracket]) =>
12
+ Object.entries(bracket)
13
+ .sort(sortByKey)
14
+ .map(([action, atom]) => ({mode, action, atom}))
15
+ )
16
+ .forEach((bind, id) => {
17
+ table.set(id, {...bind, id})
18
+ })
19
+
20
+ return table
21
+ }
22
+
@@ -0,0 +1,28 @@
1
+
2
+ import {Intent} from "../types.js"
3
+
4
+ /** merge/accumulate intents together */
5
+ export class IntentBucket {
6
+ #state = new Map<number, number>()
7
+ #changes = new Map<number, number>()
8
+
9
+ accumulate(intents: Intent[]) {
10
+ for (const [id, value] of intents) {
11
+ const previous = this.#state.get(id)
12
+
13
+ if (previous !== value) {
14
+ this.#state.set(id, value)
15
+ this.#changes.set(id, value)
16
+ }
17
+ }
18
+
19
+ return this
20
+ }
21
+
22
+ take() {
23
+ const intents = [...this.#changes.entries()]
24
+ this.#changes.clear()
25
+ return intents
26
+ }
27
+ }
28
+
@@ -0,0 +1,4 @@
1
+
2
+ export const size = 6
3
+ export const littleEndian = true
4
+
@@ -0,0 +1,23 @@
1
+
2
+ import {dataViewFrom} from "@e280/stz"
3
+ import {Intent} from "../types.js"
4
+ import {littleEndian, size} from "./consts.js"
5
+
6
+ /** decode intents from compact binary format */
7
+ export function decodeIntents(bytes: Uint8Array) {
8
+ const n = bytes.byteLength / size
9
+ if (!Number.isInteger(n)) throw new Error("invalid bytes length")
10
+
11
+ const data = dataViewFrom(bytes)
12
+ const intents: Intent[] = new Array<Intent>(n)
13
+
14
+ for (let i = 0; i < n; i++) {
15
+ const offset = i * size
16
+ const index = data.getUint16(offset, littleEndian)
17
+ const value = data.getFloat32(offset + 2, littleEndian)
18
+ intents[i] = [index, value]
19
+ }
20
+
21
+ return intents
22
+ }
23
+
@@ -0,0 +1,20 @@
1
+
2
+ import {Intent} from "../types.js"
3
+ import {littleEndian, size} from "./consts.js"
4
+
5
+ /** encode intents into compact binary format (good for networking) */
6
+ export function encodeIntents(intents: Intent[]) {
7
+ const length = intents.length * size
8
+ const buffer = new ArrayBuffer(length)
9
+ const view = new DataView(buffer)
10
+
11
+ for (let i = 0; i < intents.length; i++) {
12
+ const [index, value] = intents[i]
13
+ const offset = i * size
14
+ view.setUint16(offset, index, littleEndian)
15
+ view.setFloat32(offset + 2, value, littleEndian)
16
+ }
17
+
18
+ return new Uint8Array(buffer)
19
+ }
20
+
@@ -0,0 +1,15 @@
1
+
2
+ import {Intent} from "../types.js"
3
+
4
+ /** merge multiple sources of intents together */
5
+ export function mergeIntents(intents: Intent[]): Intent[] {
6
+ const map = new Map<number, number>()
7
+
8
+ for (const [id, value] of intents) {
9
+ const previous = map.get(id) ?? 0
10
+ map.set(id, Math.max(previous, value))
11
+ }
12
+
13
+ return [...map.entries()]
14
+ }
15
+
@@ -0,0 +1,36 @@
1
+
2
+ import {sub} from "@e280/stz"
3
+ import {isDown} from "../../utils/is-down.js"
4
+
5
+ export class Action {
6
+ on = sub<[Action]>()
7
+ onUp = sub<[Action]>()
8
+ onDown = sub<[Action]>()
9
+
10
+ #value = 0
11
+ #previous = 0
12
+
13
+ changed = false
14
+
15
+ get value() {
16
+ return this.#value
17
+ }
18
+
19
+ set value(v: number) {
20
+ this.#previous = this.#value
21
+ this.#value = v
22
+
23
+ if (this.changed) {
24
+ this.on.publish(this)
25
+ if (this.up) this.onUp.publish(this)
26
+ else this.onDown.publish(this)
27
+ }
28
+ }
29
+
30
+ get previous() { return this.#previous }
31
+ get up() { return !isDown(this.#value) }
32
+ get down() { return isDown(this.#value) }
33
+ get changedUp() { return this.changed && this.up }
34
+ get changedDown() { return this.changed && this.down }
35
+ }
36
+
@@ -0,0 +1,24 @@
1
+
2
+ import {Sample} from "../types.js"
3
+
4
+ export class SampleMap extends Map<string, number> {
5
+ constructor(samples?: Iterable<Sample>) {
6
+ super()
7
+ if (samples) {
8
+ for (const [code, value] of samples)
9
+ this.set(code, value)
10
+ }
11
+ }
12
+
13
+ zero() {
14
+ for (const code of this.keys()) this.set(code, 0)
15
+ return this
16
+ }
17
+
18
+ merge([code, value]: Sample) {
19
+ const previous = this.get(code) ?? 0
20
+ if (value > previous) this.set(code, value)
21
+ return this
22
+ }
23
+ }
24
+
@@ -0,0 +1,30 @@
1
+
2
+ import {need, obMap} from "@e280/stz"
3
+ import {Action} from "../parts/action.js"
4
+ import {bindingsShape} from "../bindings/shape.js"
5
+ import {Actions, Bindings, Intent} from "../types.js"
6
+
7
+ export function makeActionsResolver<B extends Bindings>(bindings: B) {
8
+ const shape = bindingsShape(bindings)
9
+ const map = new Map<number, Action>()
10
+
11
+ const actions = obMap(shape, bracket => obMap(bracket, id => {
12
+ const action = new Action()
13
+ map.set(id, action)
14
+ return action
15
+ })) as Actions<B>
16
+
17
+ return (intents: Intent[]) => {
18
+ for (const action of map.values())
19
+ action.changed = false
20
+
21
+ for (const [id, value] of intents) {
22
+ const action = need(map, id)
23
+ action.changed = action.value !== value
24
+ action.value = value
25
+ }
26
+
27
+ return actions
28
+ }
29
+ }
30
+
@@ -0,0 +1,106 @@
1
+
2
+ import {guarantee} from "@e280/stz"
3
+ import {tmax} from "../../utils/tmax.js"
4
+ import {tmin} from "../../utils/tmin.js"
5
+ import {lensAlgo} from "../atom/lens-algo.js"
6
+ import {SampleMap} from "../parts/sample-map.js"
7
+ import {bindingsTable} from "../bindings/table.js"
8
+ import {defaultCodeState} from "../atom/defaults.js"
9
+ import {Bindings, Sample, Intent} from "../types.js"
10
+ import {Atom, CodeSettings, CodeState} from "../atom/types.js"
11
+
12
+ export function makeIntentsResolver<B extends Bindings>(bindings: B) {
13
+ const table = bindingsTable(bindings)
14
+ const sampleMap = new SampleMap()
15
+ const codeStates = new Map<string, CodeState>()
16
+ const intentMap = new Map<number, number>()
17
+
18
+ for (const bind of table.values())
19
+ intentMap.set(bind.id, 0)
20
+
21
+ const resolveCode = (now: number, path: string[], code: string, settings?: Partial<CodeSettings>) => {
22
+ const state = guarantee(
23
+ codeStates,
24
+ path.join("/"),
25
+ () => defaultCodeState(["code", code, settings], now),
26
+ )
27
+ const value = sampleMap.get(code) ?? 0
28
+ return lensAlgo(now, state, value)
29
+ }
30
+
31
+ const resolveAtomForPath = (now: number, path: string[]) => (atom: Atom, zone: string | number): number => {
32
+ const nextPath = [
33
+ ...path,
34
+ String(zone),
35
+ typeof atom === "string" ? atom : atom[0],
36
+ ]
37
+
38
+ const resolveAtom = resolveAtomForPath(now, nextPath)
39
+
40
+ if (typeof atom === "string")
41
+ return resolveCode(now, nextPath, atom)
42
+
43
+ else switch (atom[0]) {
44
+ case "code": {
45
+ const [, code, settings] = atom
46
+ return resolveCode(now, nextPath, code, settings)
47
+ }
48
+ case "and": {
49
+ const [,...atoms] = atom
50
+ const values = atoms.map(resolveAtom)
51
+ return tmin(values)
52
+ }
53
+ case "or": {
54
+ const [,...atoms] = atom
55
+ const values = atoms.map(resolveAtom)
56
+ return tmax(values)
57
+ }
58
+ case "not": {
59
+ const [, subject] = atom
60
+ const value = resolveAtom(subject, "subject")
61
+ return (value > 0) ? 0 : 1
62
+ }
63
+ case "cond": {
64
+ const [, subject, guard] = atom
65
+ return (resolveAtom(guard, "guard") > 0)
66
+ ? resolveAtom(subject, "subject")
67
+ : 0
68
+ }
69
+ case "mods": {
70
+ const [, subject, modifiers] = atom
71
+ const maybe = (x: boolean, ...codes: Atom[]): Atom => x
72
+ ? ["or", ...codes]
73
+ : ["not", ["or", ...codes]]
74
+ const guard = resolveAtom(["cond", subject, ["and",
75
+ maybe(modifiers.ctrl ?? false, "ControlLeft", "ControlRight"),
76
+ maybe(modifiers.alt ?? false, "AltLeft", "AltRight"),
77
+ maybe(modifiers.meta ?? false, "MetaLeft", "MetaRight"),
78
+ maybe(modifiers.shift ?? false, "ShiftLeft", "ShiftRight"),
79
+ ]], "guard")
80
+ return (guard > 0)
81
+ ? resolveAtom(subject, "subject")
82
+ : 0
83
+ }
84
+ }
85
+ }
86
+
87
+ return (now: number, samples: Iterable<Sample>) => {
88
+ sampleMap.zero()
89
+ const intents: Intent[] = []
90
+
91
+ for (const sample of samples)
92
+ sampleMap.merge(sample)
93
+
94
+ for (const bind of table.values()) {
95
+ const value = resolveAtomForPath(now, [])(bind.atom, bind.mode as string)
96
+ const previous = intentMap.get(bind.id)
97
+ if (value !== previous) {
98
+ intentMap.set(bind.id, value)
99
+ intents.push([bind.id, value])
100
+ }
101
+ }
102
+
103
+ return intents
104
+ }
105
+ }
106
+
@@ -0,0 +1,40 @@
1
+
2
+ import {Atom} from "./atom/types.js"
3
+ import {Action} from "./parts/action.js"
4
+
5
+ /** json-friendly description of how samples are interpreted */
6
+ export type Bindings = {[mode: string]: {[action: string]: Atom}}
7
+
8
+ /** describes the shape of how bindings relate to the binds index (useful on serverside) */
9
+ export type BindingsShape<B extends Bindings> = {[MK in keyof B]: {[AK in keyof B[MK]]: number}}
10
+
11
+ /** integer-indexed flat map of bindings info (for efficient networking) */
12
+ export type BindingsTable<B extends Bindings> = Map<number, BindingsRow<B>>
13
+
14
+ /** the binding for a single action */
15
+ export type BindingsRow<B extends Bindings> = {
16
+ id: number
17
+ mode: keyof B
18
+ action: keyof B[keyof B]
19
+ atom: Atom
20
+ }
21
+
22
+ /** produces user input samples (eg, a keyboard produces samples) */
23
+ export type Device = {samples(): Iterable<Sample>}
24
+
25
+ /** raw user input, eg, `["KeyW", 1]` */
26
+ export type Sample = [code: string, value: number]
27
+
28
+ /** efficiently express resolved values */
29
+ export type Intent = [id: number, value: number]
30
+
31
+ /** ergonomic access to user inputs (your app logic should read from this) */
32
+ export type Actions<B extends Bindings> = {
33
+ [M in keyof B]: {
34
+ [A in keyof B[M]]: Action
35
+ }
36
+ }
37
+
38
+ export type AsBindings<B extends Bindings> = {[MK in keyof B]: {[AK in keyof B[MK]]: Atom}}
39
+ export const asBindings = <B extends Bindings>(b: B) => (b as AsBindings<B>)
40
+
@@ -0,0 +1,35 @@
1
+
2
+ import {deep} from "@e280/stz"
3
+ import {Bindings, Device} from "../core/types.js"
4
+ import {makeIntentsResolver} from "../core/resolvers/intents.js"
5
+
6
+ /** associate a device with particular bindings */
7
+ export class Controller<B extends Bindings = Bindings, D extends Device = Device> {
8
+ #bindings: B
9
+ #resolveIntents
10
+
11
+ constructor(
12
+ readonly handle: string,
13
+ bindings: B,
14
+ public device: D,
15
+ ) {
16
+ this.#bindings = bindings
17
+ this.#resolveIntents = makeIntentsResolver(bindings)
18
+ }
19
+
20
+ get bindings() {
21
+ return this.#bindings
22
+ }
23
+
24
+ set bindings(bindings: B) {
25
+ if (!deep.equal(this.#bindings, bindings)) {
26
+ this.#bindings = bindings
27
+ this.#resolveIntents = makeIntentsResolver(bindings)
28
+ }
29
+ }
30
+
31
+ resolveIntents(now: number) {
32
+ return this.#resolveIntents(now, this.device.samples())
33
+ }
34
+ }
35
+