@fairyhunter13/opentui-core 0.1.112 → 0.1.114

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 (591) hide show
  1. package/dev/keypress-debug-renderer.ts +148 -0
  2. package/dev/keypress-debug.ts +43 -0
  3. package/dev/print-env-vars.ts +32 -0
  4. package/dev/test-tmux-graphics-334.sh +68 -0
  5. package/dev/thai-debug-test.ts +68 -0
  6. package/docs/development.md +144 -0
  7. package/package.json +63 -51
  8. package/scripts/build.ts +400 -0
  9. package/scripts/publish.ts +60 -0
  10. package/src/3d/SpriteResourceManager.ts +286 -0
  11. package/src/3d/SpriteUtils.ts +70 -0
  12. package/src/3d/TextureUtils.ts +196 -0
  13. package/src/3d/ThreeRenderable.ts +197 -0
  14. package/src/3d/WGPURenderer.ts +294 -0
  15. package/src/3d/animation/ExplodingSpriteEffect.ts +513 -0
  16. package/src/3d/animation/PhysicsExplodingSpriteEffect.ts +429 -0
  17. package/src/3d/animation/SpriteAnimator.ts +633 -0
  18. package/src/3d/animation/SpriteParticleGenerator.ts +435 -0
  19. package/src/3d/canvas.ts +464 -0
  20. package/src/3d/index.ts +12 -0
  21. package/src/3d/physics/PlanckPhysicsAdapter.ts +72 -0
  22. package/src/3d/physics/RapierPhysicsAdapter.ts +66 -0
  23. package/src/3d/physics/physics-interface.ts +31 -0
  24. package/src/3d/shaders/supersampling.wgsl +201 -0
  25. package/src/3d.ts +3 -0
  26. package/src/NativeSpanFeed.ts +300 -0
  27. package/src/Renderable.ts +1704 -0
  28. package/src/__snapshots__/buffer.test.ts.snap +28 -0
  29. package/src/animation/Timeline.test.ts +2709 -0
  30. package/src/animation/Timeline.ts +598 -0
  31. package/src/ansi.ts +18 -0
  32. package/src/benchmark/attenuation-benchmark.ts +81 -0
  33. package/src/benchmark/colormatrix-benchmark.ts +128 -0
  34. package/src/benchmark/gain-benchmark.ts +80 -0
  35. package/src/benchmark/latest-all-bench-run.json +707 -0
  36. package/src/benchmark/latest-async-bench-run.json +336 -0
  37. package/src/benchmark/latest-default-bench-run.json +657 -0
  38. package/src/benchmark/latest-large-bench-run.json +707 -0
  39. package/src/benchmark/latest-quick-bench-run.json +207 -0
  40. package/src/benchmark/markdown-benchmark.ts +1796 -0
  41. package/src/benchmark/native-span-feed-async-benchmark.ts +355 -0
  42. package/src/benchmark/native-span-feed-benchmark.md +56 -0
  43. package/src/benchmark/native-span-feed-benchmark.ts +596 -0
  44. package/src/benchmark/native-span-feed-compare.ts +280 -0
  45. package/src/benchmark/renderer-benchmark.ts +754 -0
  46. package/src/benchmark/text-table-benchmark.ts +948 -0
  47. package/src/buffer.test.ts +291 -0
  48. package/src/buffer.ts +554 -0
  49. package/src/console.test.ts +612 -0
  50. package/src/console.ts +1254 -0
  51. package/src/edit-buffer.test.ts +1769 -0
  52. package/src/edit-buffer.ts +411 -0
  53. package/src/editor-view.test.ts +1032 -0
  54. package/src/editor-view.ts +284 -0
  55. package/src/examples/ascii-font-selection-demo.ts +245 -0
  56. package/src/examples/assets/Water_2_M_Normal.jpg +0 -0
  57. package/src/examples/assets/concrete.png +0 -0
  58. package/src/examples/assets/crate.png +0 -0
  59. package/src/examples/assets/crate_emissive.png +0 -0
  60. package/src/examples/assets/forrest_background.png +0 -0
  61. package/src/examples/assets/hast-example.json +1018 -0
  62. package/src/examples/assets/heart.png +0 -0
  63. package/src/examples/assets/main_char_heavy_attack.png +0 -0
  64. package/src/examples/assets/main_char_idle.png +0 -0
  65. package/src/examples/assets/main_char_jump_end.png +0 -0
  66. package/src/examples/assets/main_char_jump_landing.png +0 -0
  67. package/src/examples/assets/main_char_jump_start.png +0 -0
  68. package/src/examples/assets/main_char_run_loop.png +0 -0
  69. package/src/examples/assets/roughness_map.jpg +0 -0
  70. package/src/examples/build.ts +115 -0
  71. package/src/examples/code-demo.ts +924 -0
  72. package/src/examples/console-demo.ts +358 -0
  73. package/src/examples/core-plugin-slots-demo.ts +759 -0
  74. package/src/examples/diff-demo.ts +701 -0
  75. package/src/examples/draggable-three-demo.ts +259 -0
  76. package/src/examples/editor-demo.ts +322 -0
  77. package/src/examples/extmarks-demo.ts +196 -0
  78. package/src/examples/focus-restore-demo.ts +310 -0
  79. package/src/examples/fonts.ts +245 -0
  80. package/src/examples/fractal-shader-demo.ts +268 -0
  81. package/src/examples/framebuffer-demo.ts +674 -0
  82. package/src/examples/full-unicode-demo.ts +241 -0
  83. package/src/examples/golden-star-demo.ts +933 -0
  84. package/src/examples/grayscale-buffer-demo.ts +249 -0
  85. package/src/examples/hast-syntax-highlighting-demo.ts +129 -0
  86. package/src/examples/index.ts +926 -0
  87. package/src/examples/input-demo.ts +377 -0
  88. package/src/examples/input-select-layout-demo.ts +425 -0
  89. package/src/examples/install.sh +143 -0
  90. package/src/examples/keypress-debug-demo.ts +452 -0
  91. package/src/examples/lib/HexList.ts +122 -0
  92. package/src/examples/lib/PaletteGrid.ts +125 -0
  93. package/src/examples/lib/standalone-keys.ts +25 -0
  94. package/src/examples/lib/tab-controller.ts +243 -0
  95. package/src/examples/lights-phong-demo.ts +290 -0
  96. package/src/examples/link-demo.ts +220 -0
  97. package/src/examples/live-state-demo.ts +480 -0
  98. package/src/examples/markdown-demo.ts +725 -0
  99. package/src/examples/mouse-interaction-demo.ts +428 -0
  100. package/src/examples/nested-zindex-demo.ts +357 -0
  101. package/src/examples/opacity-example.ts +235 -0
  102. package/src/examples/opentui-demo.ts +1057 -0
  103. package/src/examples/physx-planck-2d-demo.ts +623 -0
  104. package/src/examples/physx-rapier-2d-demo.ts +655 -0
  105. package/src/examples/relative-positioning-demo.ts +323 -0
  106. package/src/examples/scroll-example.ts +214 -0
  107. package/src/examples/scrollbox-mouse-test.ts +112 -0
  108. package/src/examples/scrollbox-overlay-hit-test.ts +206 -0
  109. package/src/examples/select-demo.ts +237 -0
  110. package/src/examples/shader-cube-demo.ts +1015 -0
  111. package/src/examples/simple-layout-example.ts +591 -0
  112. package/src/examples/slider-demo.ts +617 -0
  113. package/src/examples/split-mode-demo.ts +453 -0
  114. package/src/examples/sprite-animation-demo.ts +443 -0
  115. package/src/examples/sprite-particle-generator-demo.ts +486 -0
  116. package/src/examples/static-sprite-demo.ts +193 -0
  117. package/src/examples/sticky-scroll-example.ts +308 -0
  118. package/src/examples/styled-text-demo.ts +282 -0
  119. package/src/examples/tab-select-demo.ts +219 -0
  120. package/src/examples/terminal-title.ts +29 -0
  121. package/src/examples/terminal.ts +305 -0
  122. package/src/examples/text-node-demo.ts +416 -0
  123. package/src/examples/text-selection-demo.ts +377 -0
  124. package/src/examples/text-table-demo.ts +503 -0
  125. package/src/examples/text-truncation-demo.ts +481 -0
  126. package/src/examples/text-wrap.ts +757 -0
  127. package/src/examples/texture-loading-demo.ts +259 -0
  128. package/src/examples/timeline-example.ts +670 -0
  129. package/src/examples/transparency-demo.ts +400 -0
  130. package/src/examples/vnode-composition-demo.ts +404 -0
  131. package/src/examples/wide-grapheme-overlay-demo.ts +280 -0
  132. package/src/index.ts +24 -0
  133. package/src/lib/KeyHandler.integration.test.ts +292 -0
  134. package/src/lib/KeyHandler.stopPropagation.test.ts +289 -0
  135. package/src/lib/KeyHandler.test.ts +662 -0
  136. package/src/lib/KeyHandler.ts +222 -0
  137. package/src/lib/RGBA.test.ts +984 -0
  138. package/src/lib/RGBA.ts +204 -0
  139. package/src/lib/ascii.font.ts +330 -0
  140. package/src/lib/border.test.ts +83 -0
  141. package/src/lib/border.ts +170 -0
  142. package/src/lib/bunfs.test.ts +27 -0
  143. package/src/lib/bunfs.ts +18 -0
  144. package/src/lib/clipboard.test.ts +41 -0
  145. package/src/lib/clipboard.ts +47 -0
  146. package/src/lib/clock.ts +35 -0
  147. package/src/lib/data-paths.test.ts +133 -0
  148. package/src/lib/data-paths.ts +109 -0
  149. package/src/lib/debounce.ts +106 -0
  150. package/src/lib/detect-links.test.ts +98 -0
  151. package/src/lib/detect-links.ts +56 -0
  152. package/src/lib/env.test.ts +228 -0
  153. package/src/lib/env.ts +209 -0
  154. package/src/lib/extmarks-history.ts +51 -0
  155. package/src/lib/extmarks-multiwidth.test.ts +322 -0
  156. package/src/lib/extmarks.test.ts +3457 -0
  157. package/src/lib/extmarks.ts +843 -0
  158. package/src/lib/fonts/block.json +405 -0
  159. package/src/lib/fonts/grid.json +265 -0
  160. package/src/lib/fonts/huge.json +741 -0
  161. package/src/lib/fonts/pallet.json +314 -0
  162. package/src/lib/fonts/shade.json +591 -0
  163. package/src/lib/fonts/slick.json +321 -0
  164. package/src/lib/fonts/tiny.json +69 -0
  165. package/src/lib/hast-styled-text.ts +59 -0
  166. package/src/lib/index.ts +21 -0
  167. package/src/lib/keymapping.test.ts +317 -0
  168. package/src/lib/keymapping.ts +115 -0
  169. package/src/lib/objects-in-viewport.test.ts +787 -0
  170. package/src/lib/objects-in-viewport.ts +153 -0
  171. package/src/lib/output.capture.ts +58 -0
  172. package/src/lib/parse.keypress-kitty.protocol.test.ts +340 -0
  173. package/src/lib/parse.keypress-kitty.test.ts +663 -0
  174. package/src/lib/parse.keypress-kitty.ts +439 -0
  175. package/src/lib/parse.keypress.test.ts +1849 -0
  176. package/src/lib/parse.keypress.ts +397 -0
  177. package/src/lib/parse.mouse.test.ts +552 -0
  178. package/src/lib/parse.mouse.ts +232 -0
  179. package/src/lib/paste.ts +16 -0
  180. package/src/lib/queue.ts +65 -0
  181. package/src/lib/renderable.validations.test.ts +87 -0
  182. package/src/lib/renderable.validations.ts +83 -0
  183. package/src/lib/scroll-acceleration.ts +98 -0
  184. package/src/lib/selection.ts +240 -0
  185. package/src/lib/singleton.ts +28 -0
  186. package/src/lib/stdin-parser.test.ts +2290 -0
  187. package/src/lib/stdin-parser.ts +1810 -0
  188. package/src/lib/styled-text.ts +178 -0
  189. package/src/lib/terminal-capability-detection.test.ts +202 -0
  190. package/src/lib/terminal-capability-detection.ts +79 -0
  191. package/src/lib/terminal-palette.test.ts +878 -0
  192. package/src/lib/terminal-palette.ts +383 -0
  193. package/src/lib/tree-sitter/assets/README.md +118 -0
  194. package/src/lib/tree-sitter/assets/update.ts +334 -0
  195. package/src/lib/tree-sitter/assets.d.ts +9 -0
  196. package/src/lib/tree-sitter/cache.test.ts +273 -0
  197. package/src/lib/tree-sitter/client.test.ts +1165 -0
  198. package/src/lib/tree-sitter/client.ts +607 -0
  199. package/src/lib/tree-sitter/default-parsers.ts +86 -0
  200. package/src/lib/tree-sitter/download-utils.ts +148 -0
  201. package/src/lib/tree-sitter/index.ts +28 -0
  202. package/src/lib/tree-sitter/parser.worker.ts +1042 -0
  203. package/src/lib/tree-sitter/parsers-config.ts +81 -0
  204. package/src/lib/tree-sitter/resolve-ft.test.ts +55 -0
  205. package/src/lib/tree-sitter/resolve-ft.ts +189 -0
  206. package/src/lib/tree-sitter/types.ts +82 -0
  207. package/src/lib/tree-sitter-styled-text.test.ts +1253 -0
  208. package/src/lib/tree-sitter-styled-text.ts +306 -0
  209. package/src/lib/validate-dir-name.ts +55 -0
  210. package/src/lib/yoga.options.test.ts +628 -0
  211. package/src/lib/yoga.options.ts +346 -0
  212. package/src/plugins/core-slot.ts +579 -0
  213. package/src/plugins/registry.ts +402 -0
  214. package/src/plugins/types.ts +46 -0
  215. package/src/post/effects.ts +930 -0
  216. package/src/post/filters.ts +489 -0
  217. package/src/post/matrices.ts +288 -0
  218. package/src/renderables/ASCIIFont.ts +219 -0
  219. package/src/renderables/Box.test.ts +205 -0
  220. package/src/renderables/Box.ts +326 -0
  221. package/src/renderables/Code.test.ts +2062 -0
  222. package/src/renderables/Code.ts +357 -0
  223. package/src/renderables/Diff.regression.test.ts +226 -0
  224. package/src/renderables/Diff.test.ts +3101 -0
  225. package/src/renderables/Diff.ts +1211 -0
  226. package/src/renderables/EditBufferRenderable.test.ts +288 -0
  227. package/src/renderables/EditBufferRenderable.ts +1166 -0
  228. package/src/renderables/FrameBuffer.ts +47 -0
  229. package/src/renderables/Input.test.ts +1228 -0
  230. package/src/renderables/Input.ts +247 -0
  231. package/src/renderables/LineNumberRenderable.ts +724 -0
  232. package/src/renderables/Markdown.ts +1393 -0
  233. package/src/renderables/ScrollBar.ts +422 -0
  234. package/src/renderables/ScrollBox.ts +883 -0
  235. package/src/renderables/Select.test.ts +1033 -0
  236. package/src/renderables/Select.ts +524 -0
  237. package/src/renderables/Slider.test.ts +456 -0
  238. package/src/renderables/Slider.ts +342 -0
  239. package/src/renderables/TabSelect.test.ts +197 -0
  240. package/src/renderables/TabSelect.ts +455 -0
  241. package/src/renderables/Text.selection-buffer.test.ts +123 -0
  242. package/src/renderables/Text.test.ts +2660 -0
  243. package/src/renderables/Text.ts +147 -0
  244. package/src/renderables/TextBufferRenderable.ts +518 -0
  245. package/src/renderables/TextNode.test.ts +1058 -0
  246. package/src/renderables/TextNode.ts +325 -0
  247. package/src/renderables/TextTable.test.ts +1421 -0
  248. package/src/renderables/TextTable.ts +1344 -0
  249. package/src/renderables/Textarea.ts +430 -0
  250. package/src/renderables/TimeToFirstDraw.ts +89 -0
  251. package/src/renderables/__snapshots__/Code.test.ts.snap +13 -0
  252. package/src/renderables/__snapshots__/Diff.test.ts.snap +785 -0
  253. package/src/renderables/__snapshots__/Text.test.ts.snap +421 -0
  254. package/src/renderables/__snapshots__/TextTable.test.ts.snap +215 -0
  255. package/src/renderables/__tests__/LineNumberRenderable.scrollbox-simple.test.ts +144 -0
  256. package/src/renderables/__tests__/LineNumberRenderable.scrollbox.test.ts +816 -0
  257. package/src/renderables/__tests__/LineNumberRenderable.test.ts +1865 -0
  258. package/src/renderables/__tests__/LineNumberRenderable.wrapping.test.ts +85 -0
  259. package/src/renderables/__tests__/Markdown.code-colors.test.ts +242 -0
  260. package/src/renderables/__tests__/Markdown.test.ts +2518 -0
  261. package/src/renderables/__tests__/MultiRenderable.selection.test.ts +87 -0
  262. package/src/renderables/__tests__/Textarea.buffer.test.ts +682 -0
  263. package/src/renderables/__tests__/Textarea.destroyed-events.test.ts +675 -0
  264. package/src/renderables/__tests__/Textarea.editing.test.ts +2041 -0
  265. package/src/renderables/__tests__/Textarea.error-handling.test.ts +35 -0
  266. package/src/renderables/__tests__/Textarea.events.test.ts +738 -0
  267. package/src/renderables/__tests__/Textarea.highlights.test.ts +590 -0
  268. package/src/renderables/__tests__/Textarea.keybinding.test.ts +3149 -0
  269. package/src/renderables/__tests__/Textarea.paste.test.ts +357 -0
  270. package/src/renderables/__tests__/Textarea.rendering.test.ts +1866 -0
  271. package/src/renderables/__tests__/Textarea.scroll.test.ts +733 -0
  272. package/src/renderables/__tests__/Textarea.selection.test.ts +1590 -0
  273. package/src/renderables/__tests__/Textarea.stress.test.ts +670 -0
  274. package/src/renderables/__tests__/Textarea.undo-redo.test.ts +383 -0
  275. package/src/renderables/__tests__/Textarea.visual-lines.test.ts +310 -0
  276. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.code.test.ts.snap +221 -0
  277. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox-simple.test.ts.snap +89 -0
  278. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.scrollbox.test.ts.snap +457 -0
  279. package/src/renderables/__tests__/__snapshots__/LineNumberRenderable.test.ts.snap +158 -0
  280. package/src/renderables/__tests__/__snapshots__/Textarea.rendering.test.ts.snap +387 -0
  281. package/src/renderables/__tests__/markdown-parser.test.ts +217 -0
  282. package/src/renderables/__tests__/renderable-test-utils.ts +60 -0
  283. package/src/renderables/composition/README.md +8 -0
  284. package/src/renderables/composition/VRenderable.ts +32 -0
  285. package/src/renderables/composition/constructs.ts +127 -0
  286. package/src/renderables/composition/vnode.ts +289 -0
  287. package/src/renderables/index.ts +23 -0
  288. package/src/renderables/markdown-parser.ts +66 -0
  289. package/src/renderer.ts +2681 -0
  290. package/src/runtime-plugin-support.ts +39 -0
  291. package/src/runtime-plugin.ts +615 -0
  292. package/src/syntax-style.test.ts +841 -0
  293. package/src/syntax-style.ts +257 -0
  294. package/src/testing/README.md +210 -0
  295. package/src/testing/capture-spans.test.ts +194 -0
  296. package/src/testing/integration.test.ts +276 -0
  297. package/src/testing/manual-clock.ts +117 -0
  298. package/src/testing/mock-keys.test.ts +1378 -0
  299. package/src/testing/mock-keys.ts +457 -0
  300. package/src/testing/mock-mouse.test.ts +218 -0
  301. package/src/testing/mock-mouse.ts +247 -0
  302. package/src/testing/mock-tree-sitter-client.ts +73 -0
  303. package/src/testing/spy.ts +13 -0
  304. package/src/testing/test-recorder.test.ts +415 -0
  305. package/src/testing/test-recorder.ts +145 -0
  306. package/src/testing/test-renderer.ts +132 -0
  307. package/src/testing.ts +7 -0
  308. package/src/tests/__snapshots__/absolute-positioning.snapshot.test.ts.snap +481 -0
  309. package/src/tests/__snapshots__/renderable.snapshot.test.ts.snap +19 -0
  310. package/src/tests/__snapshots__/scrollbox.test.ts.snap +29 -0
  311. package/src/tests/absolute-positioning.snapshot.test.ts +638 -0
  312. package/src/tests/allocator-stats.test.ts +38 -0
  313. package/src/tests/destroy-during-render.test.ts +200 -0
  314. package/src/tests/destroy-on-exit.fixture.ts +36 -0
  315. package/src/tests/destroy-on-exit.test.ts +41 -0
  316. package/src/tests/hover-cursor.test.ts +98 -0
  317. package/src/tests/native-span-feed-async.test.ts +173 -0
  318. package/src/tests/native-span-feed-close.test.ts +120 -0
  319. package/src/tests/native-span-feed-coverage.test.ts +227 -0
  320. package/src/tests/native-span-feed-edge-cases.test.ts +352 -0
  321. package/src/tests/native-span-feed-use-after-free.test.ts +45 -0
  322. package/src/tests/opacity.test.ts +123 -0
  323. package/src/tests/renderable.snapshot.test.ts +524 -0
  324. package/src/tests/renderable.test.ts +1281 -0
  325. package/src/tests/renderer.clock.test.ts +158 -0
  326. package/src/tests/renderer.console-startup.test.ts +185 -0
  327. package/src/tests/renderer.control.test.ts +425 -0
  328. package/src/tests/renderer.core-slot-binding.test.ts +952 -0
  329. package/src/tests/renderer.cursor.test.ts +26 -0
  330. package/src/tests/renderer.destroy-during-render.test.ts +147 -0
  331. package/src/tests/renderer.focus-restore.test.ts +257 -0
  332. package/src/tests/renderer.focus.test.ts +294 -0
  333. package/src/tests/renderer.idle.test.ts +219 -0
  334. package/src/tests/renderer.input.test.ts +2237 -0
  335. package/src/tests/renderer.kitty-flags.test.ts +195 -0
  336. package/src/tests/renderer.mouse.test.ts +1274 -0
  337. package/src/tests/renderer.palette.test.ts +629 -0
  338. package/src/tests/renderer.selection.test.ts +49 -0
  339. package/src/tests/renderer.slot-registry.test.ts +684 -0
  340. package/src/tests/renderer.useMouse.test.ts +47 -0
  341. package/src/tests/runtime-plugin-node-modules-cycle.fixture.ts +76 -0
  342. package/src/tests/runtime-plugin-node-modules-mjs.fixture.ts +43 -0
  343. package/src/tests/runtime-plugin-node-modules-no-bare-rewrite.fixture.ts +67 -0
  344. package/src/tests/runtime-plugin-node-modules-package-type-cache.fixture.ts +72 -0
  345. package/src/tests/runtime-plugin-node-modules-runtime-specifier.fixture.ts +44 -0
  346. package/src/tests/runtime-plugin-node-modules-scoped-package-bare-rewrite.fixture.ts +85 -0
  347. package/src/tests/runtime-plugin-path-alias.fixture.ts +43 -0
  348. package/src/tests/runtime-plugin-resolve-roots.fixture.ts +65 -0
  349. package/src/tests/runtime-plugin-support.fixture.ts +11 -0
  350. package/src/tests/runtime-plugin-support.test.ts +19 -0
  351. package/src/tests/runtime-plugin-windows-file-url.fixture.ts +30 -0
  352. package/src/tests/runtime-plugin.fixture.ts +40 -0
  353. package/src/tests/runtime-plugin.test.ts +354 -0
  354. package/src/tests/scrollbox-culling-bug.test.ts +114 -0
  355. package/src/tests/scrollbox-hitgrid-resize.test.ts +136 -0
  356. package/src/tests/scrollbox-hitgrid.test.ts +909 -0
  357. package/src/tests/scrollbox.test.ts +1530 -0
  358. package/src/tests/wrap-resize-perf.test.ts +276 -0
  359. package/src/tests/yoga-setters.test.ts +921 -0
  360. package/src/text-buffer-view.test.ts +705 -0
  361. package/src/text-buffer-view.ts +189 -0
  362. package/src/text-buffer.test.ts +347 -0
  363. package/src/text-buffer.ts +250 -0
  364. package/src/types.ts +161 -0
  365. package/src/utils.ts +88 -0
  366. package/src/zig/ansi.zig +268 -0
  367. package/src/zig/bench/README.md +50 -0
  368. package/src/zig/bench/buffer-draw-text-buffer_bench.zig +887 -0
  369. package/src/zig/bench/edit-buffer_bench.zig +476 -0
  370. package/src/zig/bench/native-span-feed_bench.zig +100 -0
  371. package/src/zig/bench/rope-markers_bench.zig +713 -0
  372. package/src/zig/bench/rope_bench.zig +514 -0
  373. package/src/zig/bench/styled-text_bench.zig +470 -0
  374. package/src/zig/bench/text-buffer-coords_bench.zig +362 -0
  375. package/src/zig/bench/text-buffer-view_bench.zig +459 -0
  376. package/src/zig/bench/text-chunk-graphemes_bench.zig +273 -0
  377. package/src/zig/bench/utf8_bench.zig +799 -0
  378. package/src/zig/bench-utils.zig +431 -0
  379. package/src/zig/bench.zig +217 -0
  380. package/src/zig/buffer-methods.zig +211 -0
  381. package/src/zig/buffer.zig +2281 -0
  382. package/src/zig/build.zig +289 -0
  383. package/src/zig/build.zig.zon +16 -0
  384. package/src/zig/edit-buffer.zig +825 -0
  385. package/src/zig/editor-view.zig +802 -0
  386. package/src/zig/event-bus.zig +13 -0
  387. package/src/zig/event-emitter.zig +65 -0
  388. package/src/zig/file-logger.zig +92 -0
  389. package/src/zig/grapheme.zig +599 -0
  390. package/src/zig/lib.zig +1854 -0
  391. package/src/zig/link.zig +333 -0
  392. package/src/zig/logger.zig +43 -0
  393. package/src/zig/mem-registry.zig +125 -0
  394. package/src/zig/native-span-feed-bench-lib.zig +7 -0
  395. package/src/zig/native-span-feed.zig +708 -0
  396. package/src/zig/renderer.zig +1393 -0
  397. package/src/zig/rope.zig +1220 -0
  398. package/src/zig/syntax-style.zig +161 -0
  399. package/src/zig/terminal.zig +987 -0
  400. package/src/zig/test.zig +72 -0
  401. package/src/zig/tests/README.md +18 -0
  402. package/src/zig/tests/buffer-methods_test.zig +1109 -0
  403. package/src/zig/tests/buffer_test.zig +2557 -0
  404. package/src/zig/tests/edit-buffer-history_test.zig +271 -0
  405. package/src/zig/tests/edit-buffer_test.zig +1689 -0
  406. package/src/zig/tests/editor-view_test.zig +3299 -0
  407. package/src/zig/tests/event-emitter_test.zig +249 -0
  408. package/src/zig/tests/grapheme_test.zig +1304 -0
  409. package/src/zig/tests/link_test.zig +190 -0
  410. package/src/zig/tests/mem-registry_test.zig +473 -0
  411. package/src/zig/tests/memory_leak_regression_test.zig +159 -0
  412. package/src/zig/tests/native-span-feed_test.zig +1264 -0
  413. package/src/zig/tests/renderer_test.zig +1017 -0
  414. package/src/zig/tests/rope-nested_test.zig +712 -0
  415. package/src/zig/tests/rope_fuzz_test.zig +238 -0
  416. package/src/zig/tests/rope_test.zig +2362 -0
  417. package/src/zig/tests/segment-merge.test.zig +148 -0
  418. package/src/zig/tests/syntax-style_test.zig +557 -0
  419. package/src/zig/tests/terminal_test.zig +754 -0
  420. package/src/zig/tests/text-buffer-drawing_test.zig +3237 -0
  421. package/src/zig/tests/text-buffer-highlights_test.zig +666 -0
  422. package/src/zig/tests/text-buffer-iterators_test.zig +776 -0
  423. package/src/zig/tests/text-buffer-segment_test.zig +320 -0
  424. package/src/zig/tests/text-buffer-selection_test.zig +1035 -0
  425. package/src/zig/tests/text-buffer-selection_viewport_test.zig +358 -0
  426. package/src/zig/tests/text-buffer-view_test.zig +3649 -0
  427. package/src/zig/tests/text-buffer_test.zig +2191 -0
  428. package/src/zig/tests/unicode-width-map.zon +3909 -0
  429. package/src/zig/tests/utf8_no_zwj_test.zig +260 -0
  430. package/src/zig/tests/utf8_test.zig +4057 -0
  431. package/src/zig/tests/utf8_wcwidth_cursor_test.zig +267 -0
  432. package/src/zig/tests/utf8_wcwidth_test.zig +357 -0
  433. package/src/zig/tests/word-wrap-editing_test.zig +498 -0
  434. package/src/zig/tests/wrap-cache-perf_test.zig +113 -0
  435. package/src/zig/text-buffer-iterators.zig +499 -0
  436. package/src/zig/text-buffer-segment.zig +404 -0
  437. package/src/zig/text-buffer-view.zig +1371 -0
  438. package/src/zig/text-buffer.zig +1180 -0
  439. package/src/zig/utf8.zig +1948 -0
  440. package/src/zig/utils.zig +9 -0
  441. package/src/zig-structs.ts +261 -0
  442. package/src/zig.ts +3884 -0
  443. package/tsconfig.build.json +24 -0
  444. package/tsconfig.json +27 -0
  445. package/3d/SpriteResourceManager.d.ts +0 -74
  446. package/3d/SpriteUtils.d.ts +0 -13
  447. package/3d/TextureUtils.d.ts +0 -24
  448. package/3d/ThreeRenderable.d.ts +0 -40
  449. package/3d/WGPURenderer.d.ts +0 -61
  450. package/3d/animation/ExplodingSpriteEffect.d.ts +0 -71
  451. package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +0 -76
  452. package/3d/animation/SpriteAnimator.d.ts +0 -124
  453. package/3d/animation/SpriteParticleGenerator.d.ts +0 -62
  454. package/3d/canvas.d.ts +0 -44
  455. package/3d/index.d.ts +0 -12
  456. package/3d/physics/PlanckPhysicsAdapter.d.ts +0 -19
  457. package/3d/physics/RapierPhysicsAdapter.d.ts +0 -19
  458. package/3d/physics/physics-interface.d.ts +0 -27
  459. package/3d.d.ts +0 -2
  460. package/3d.js +0 -34041
  461. package/3d.js.map +0 -155
  462. package/LICENSE +0 -21
  463. package/NativeSpanFeed.d.ts +0 -41
  464. package/Renderable.d.ts +0 -334
  465. package/animation/Timeline.d.ts +0 -126
  466. package/ansi.d.ts +0 -13
  467. package/buffer.d.ts +0 -111
  468. package/console.d.ts +0 -144
  469. package/edit-buffer.d.ts +0 -98
  470. package/editor-view.d.ts +0 -73
  471. package/index-8fks7yv1.js +0 -411
  472. package/index-8fks7yv1.js.map +0 -10
  473. package/index-egy5e2rs.js +0 -12267
  474. package/index-egy5e2rs.js.map +0 -42
  475. package/index-tse8gzh0.js +0 -20614
  476. package/index-tse8gzh0.js.map +0 -67
  477. package/index.d.ts +0 -23
  478. package/index.js +0 -478
  479. package/index.js.map +0 -9
  480. package/lib/KeyHandler.d.ts +0 -61
  481. package/lib/RGBA.d.ts +0 -25
  482. package/lib/ascii.font.d.ts +0 -508
  483. package/lib/border.d.ts +0 -51
  484. package/lib/bunfs.d.ts +0 -7
  485. package/lib/clipboard.d.ts +0 -17
  486. package/lib/clock.d.ts +0 -15
  487. package/lib/data-paths.d.ts +0 -26
  488. package/lib/debounce.d.ts +0 -42
  489. package/lib/detect-links.d.ts +0 -6
  490. package/lib/env.d.ts +0 -42
  491. package/lib/extmarks-history.d.ts +0 -17
  492. package/lib/extmarks.d.ts +0 -89
  493. package/lib/hast-styled-text.d.ts +0 -17
  494. package/lib/index.d.ts +0 -21
  495. package/lib/keymapping.d.ts +0 -25
  496. package/lib/objects-in-viewport.d.ts +0 -24
  497. package/lib/output.capture.d.ts +0 -24
  498. package/lib/parse.keypress-kitty.d.ts +0 -2
  499. package/lib/parse.keypress.d.ts +0 -26
  500. package/lib/parse.mouse.d.ts +0 -30
  501. package/lib/paste.d.ts +0 -7
  502. package/lib/queue.d.ts +0 -15
  503. package/lib/renderable.validations.d.ts +0 -12
  504. package/lib/scroll-acceleration.d.ts +0 -43
  505. package/lib/selection.d.ts +0 -63
  506. package/lib/singleton.d.ts +0 -7
  507. package/lib/stdin-parser.d.ts +0 -87
  508. package/lib/styled-text.d.ts +0 -63
  509. package/lib/terminal-capability-detection.d.ts +0 -30
  510. package/lib/terminal-palette.d.ts +0 -50
  511. package/lib/tree-sitter/assets/update.d.ts +0 -11
  512. package/lib/tree-sitter/client.d.ts +0 -47
  513. package/lib/tree-sitter/default-parsers.d.ts +0 -2
  514. package/lib/tree-sitter/download-utils.d.ts +0 -21
  515. package/lib/tree-sitter/index.d.ts +0 -8
  516. package/lib/tree-sitter/parser.worker.d.ts +0 -1
  517. package/lib/tree-sitter/parsers-config.d.ts +0 -53
  518. package/lib/tree-sitter/resolve-ft.d.ts +0 -5
  519. package/lib/tree-sitter/types.d.ts +0 -82
  520. package/lib/tree-sitter-styled-text.d.ts +0 -14
  521. package/lib/validate-dir-name.d.ts +0 -1
  522. package/lib/yoga.options.d.ts +0 -32
  523. package/parser.worker.js +0 -899
  524. package/parser.worker.js.map +0 -12
  525. package/plugins/core-slot.d.ts +0 -72
  526. package/plugins/registry.d.ts +0 -42
  527. package/plugins/types.d.ts +0 -34
  528. package/post/effects.d.ts +0 -147
  529. package/post/filters.d.ts +0 -65
  530. package/post/matrices.d.ts +0 -20
  531. package/renderables/ASCIIFont.d.ts +0 -52
  532. package/renderables/Box.d.ts +0 -81
  533. package/renderables/Code.d.ts +0 -78
  534. package/renderables/Diff.d.ts +0 -142
  535. package/renderables/EditBufferRenderable.d.ts +0 -237
  536. package/renderables/FrameBuffer.d.ts +0 -16
  537. package/renderables/Input.d.ts +0 -67
  538. package/renderables/LineNumberRenderable.d.ts +0 -78
  539. package/renderables/Markdown.d.ts +0 -185
  540. package/renderables/ScrollBar.d.ts +0 -77
  541. package/renderables/ScrollBox.d.ts +0 -124
  542. package/renderables/Select.d.ts +0 -115
  543. package/renderables/Slider.d.ts +0 -47
  544. package/renderables/TabSelect.d.ts +0 -96
  545. package/renderables/Text.d.ts +0 -36
  546. package/renderables/TextBufferRenderable.d.ts +0 -105
  547. package/renderables/TextNode.d.ts +0 -91
  548. package/renderables/TextTable.d.ts +0 -140
  549. package/renderables/Textarea.d.ts +0 -63
  550. package/renderables/TimeToFirstDraw.d.ts +0 -24
  551. package/renderables/__tests__/renderable-test-utils.d.ts +0 -12
  552. package/renderables/composition/VRenderable.d.ts +0 -16
  553. package/renderables/composition/constructs.d.ts +0 -35
  554. package/renderables/composition/vnode.d.ts +0 -46
  555. package/renderables/index.d.ts +0 -23
  556. package/renderables/markdown-parser.d.ts +0 -10
  557. package/renderer.d.ts +0 -419
  558. package/runtime-plugin-support.d.ts +0 -3
  559. package/runtime-plugin-support.js +0 -29
  560. package/runtime-plugin-support.js.map +0 -10
  561. package/runtime-plugin.d.ts +0 -16
  562. package/runtime-plugin.js +0 -16
  563. package/runtime-plugin.js.map +0 -9
  564. package/syntax-style.d.ts +0 -54
  565. package/testing/manual-clock.d.ts +0 -17
  566. package/testing/mock-keys.d.ts +0 -81
  567. package/testing/mock-mouse.d.ts +0 -38
  568. package/testing/mock-tree-sitter-client.d.ts +0 -23
  569. package/testing/spy.d.ts +0 -7
  570. package/testing/test-recorder.d.ts +0 -61
  571. package/testing/test-renderer.d.ts +0 -23
  572. package/testing.d.ts +0 -6
  573. package/testing.js +0 -697
  574. package/testing.js.map +0 -15
  575. package/text-buffer-view.d.ts +0 -42
  576. package/text-buffer.d.ts +0 -67
  577. package/types.d.ts +0 -139
  578. package/utils.d.ts +0 -14
  579. package/zig-structs.d.ts +0 -155
  580. package/zig.d.ts +0 -353
  581. /package/{assets → src/lib/tree-sitter/assets}/javascript/highlights.scm +0 -0
  582. /package/{assets → src/lib/tree-sitter/assets}/javascript/tree-sitter-javascript.wasm +0 -0
  583. /package/{assets → src/lib/tree-sitter/assets}/markdown/highlights.scm +0 -0
  584. /package/{assets → src/lib/tree-sitter/assets}/markdown/injections.scm +0 -0
  585. /package/{assets → src/lib/tree-sitter/assets}/markdown/tree-sitter-markdown.wasm +0 -0
  586. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/highlights.scm +0 -0
  587. /package/{assets → src/lib/tree-sitter/assets}/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
  588. /package/{assets → src/lib/tree-sitter/assets}/typescript/highlights.scm +0 -0
  589. /package/{assets → src/lib/tree-sitter/assets}/typescript/tree-sitter-typescript.wasm +0 -0
  590. /package/{assets → src/lib/tree-sitter/assets}/zig/highlights.scm +0 -0
  591. /package/{assets → src/lib/tree-sitter/assets}/zig/tree-sitter-zig.wasm +0 -0
@@ -0,0 +1,633 @@
1
+ import * as THREE from "three"
2
+ import { uniform, texture as tslTexture, uv, float, vec2, bufferAttribute, mix } from "three/tsl"
3
+ import { MeshBasicNodeMaterial, NodeMaterial } from "three/webgpu"
4
+ import type { Scene } from "three"
5
+ import { type SpriteResource, InstanceManager } from "../SpriteResourceManager.js"
6
+
7
+ export interface AnimationStateConfig {
8
+ imagePath: string
9
+ sheetNumFrames: number
10
+
11
+ animNumFrames: number
12
+ animFrameOffset: number
13
+
14
+ frameDuration?: number
15
+ loop?: boolean
16
+ initialFrame?: number
17
+ flipX?: boolean
18
+ flipY?: boolean
19
+ }
20
+
21
+ export type ResolvedAnimationState = Required<AnimationStateConfig> & {
22
+ sheetTilesetWidth: number
23
+ sheetTilesetHeight: number
24
+ texture: THREE.DataTexture
25
+ }
26
+
27
+ export interface AnimationDefinition {
28
+ resource: SpriteResource
29
+ animNumFrames?: number
30
+ animFrameOffset?: number
31
+ frameDuration?: number
32
+ loop?: boolean
33
+ initialFrame?: number
34
+ flipX?: boolean
35
+ flipY?: boolean
36
+ }
37
+
38
+ export interface SpriteDefinition {
39
+ id?: string
40
+ renderOrder?: number
41
+ depthWrite?: boolean
42
+ maxInstances?: number
43
+ scale?: number
44
+ initialAnimation: string
45
+ animations: Record<string, AnimationDefinition>
46
+ }
47
+
48
+ const HIDDEN_MATRIX = new THREE.Matrix4().scale(new THREE.Vector3(0, 0, 0))
49
+
50
+ const DEFAULT_FRAME_DURATION = 100
51
+ const DEFAULT_INITIAL_FRAME = 0
52
+ const DEFAULT_SCALE = 1.0
53
+ const DEFAULT_FLIP_X = false
54
+ const DEFAULT_FLIP_Y = false
55
+
56
+ class Animation {
57
+ public readonly name: string
58
+ public state: ResolvedAnimationState
59
+ private resource: SpriteResource
60
+ public instanceIndex: number
61
+ private instanceManager: InstanceManager
62
+ private frameAttribute: THREE.InstancedBufferAttribute
63
+ private flipAttribute: THREE.InstancedBufferAttribute
64
+
65
+ public currentLocalFrame: number
66
+ public timeAccumulator: number
67
+ public isPlaying: boolean
68
+ private _isActive: boolean = false
69
+
70
+ constructor(
71
+ name: string,
72
+ state: ResolvedAnimationState,
73
+ resource: SpriteResource,
74
+ instanceIndex: number,
75
+ instanceManager: InstanceManager,
76
+ frameAttribute: THREE.InstancedBufferAttribute,
77
+ flipAttribute: THREE.InstancedBufferAttribute,
78
+ ) {
79
+ this.name = name
80
+ this.state = state
81
+ this.resource = resource
82
+ this.instanceIndex = instanceIndex
83
+ this.instanceManager = instanceManager
84
+ this.frameAttribute = frameAttribute
85
+ this.flipAttribute = flipAttribute
86
+
87
+ this.currentLocalFrame = state.initialFrame
88
+ this.timeAccumulator = 0
89
+ this.isPlaying = true
90
+
91
+ this.instanceManager.mesh.setMatrixAt(this.instanceIndex, HIDDEN_MATRIX)
92
+ const absoluteFrame = this.state.animFrameOffset + this.currentLocalFrame
93
+ this.frameAttribute.setX(this.instanceIndex, absoluteFrame)
94
+ this.flipAttribute.setXY(this.instanceIndex, this.state.flipX ? 1.0 : 0.0, this.state.flipY ? 1.0 : 0.0)
95
+ }
96
+
97
+ activate(worldTransform: THREE.Matrix4): void {
98
+ this._isActive = true
99
+ this.isPlaying = true // Start playing when activated
100
+ this.currentLocalFrame = this.state.initialFrame // Reset to initial frame
101
+ this.timeAccumulator = 0
102
+ this.updateVisuals(worldTransform) // Apply transform and set frame
103
+ // Ensure frame attribute is updated upon activation
104
+ const absoluteFrame = this.state.animFrameOffset + this.currentLocalFrame
105
+ this.frameAttribute.setX(this.instanceIndex, absoluteFrame)
106
+ this.frameAttribute.needsUpdate = true // Mark manager for update
107
+ this.flipAttribute.setXY(this.instanceIndex, this.state.flipX ? 1.0 : 0.0, this.state.flipY ? 1.0 : 0.0)
108
+ this.flipAttribute.needsUpdate = true
109
+ }
110
+
111
+ deactivate(): void {
112
+ this._isActive = false
113
+ this.isPlaying = false
114
+ this.instanceManager.mesh.setMatrixAt(this.instanceIndex, HIDDEN_MATRIX)
115
+ }
116
+
117
+ updateVisuals(worldTransform: THREE.Matrix4): void {
118
+ if (!this._isActive) return
119
+ this.instanceManager.mesh.setMatrixAt(this.instanceIndex, worldTransform)
120
+ }
121
+
122
+ updateTime(deltaTimeMs: number): boolean {
123
+ // Returns true if frame attribute was updated
124
+ if (!this.isPlaying || !this._isActive) return false
125
+
126
+ this.timeAccumulator += deltaTimeMs
127
+ let needsFrameAttributeUpdate = false
128
+
129
+ if (this.timeAccumulator >= this.state.frameDuration) {
130
+ const framesToAdvance = Math.floor(this.timeAccumulator / this.state.frameDuration)
131
+ this.timeAccumulator %= this.state.frameDuration
132
+
133
+ const oldLocalFrame = this.currentLocalFrame
134
+ let nextLocalFrame = this.currentLocalFrame + framesToAdvance
135
+
136
+ if (nextLocalFrame >= this.state.animNumFrames) {
137
+ if (this.state.loop) {
138
+ this.currentLocalFrame = nextLocalFrame % this.state.animNumFrames
139
+ } else {
140
+ this.currentLocalFrame = this.state.animNumFrames - 1
141
+ this.isPlaying = false
142
+ }
143
+ } else {
144
+ this.currentLocalFrame = nextLocalFrame
145
+ }
146
+
147
+ if (this.currentLocalFrame !== oldLocalFrame || !this.isPlaying) {
148
+ const absoluteFrame = this.state.animFrameOffset + this.currentLocalFrame
149
+ this.frameAttribute.setX(this.instanceIndex, absoluteFrame)
150
+ this.frameAttribute.needsUpdate = true
151
+ needsFrameAttributeUpdate = true
152
+ }
153
+ }
154
+ return needsFrameAttributeUpdate
155
+ }
156
+
157
+ play(): void {
158
+ if (!this._isActive) return
159
+ this.isPlaying = true
160
+ }
161
+
162
+ stop(): void {
163
+ this.isPlaying = false
164
+ }
165
+
166
+ goToFrame(localFrame: number): void {
167
+ if (!this._isActive) return
168
+ const targetLocalFrame = Math.max(0, Math.min(localFrame, this.state.animNumFrames - 1))
169
+ if (this.currentLocalFrame !== targetLocalFrame) {
170
+ this.currentLocalFrame = targetLocalFrame
171
+ this.timeAccumulator = 0
172
+ const absoluteFrame = this.state.animFrameOffset + this.currentLocalFrame
173
+ this.frameAttribute.setX(this.instanceIndex, absoluteFrame)
174
+ this.frameAttribute.needsUpdate = true // Mark manager for update
175
+ }
176
+ }
177
+
178
+ setFrameDuration(newFrameDuration: number): void {
179
+ if (newFrameDuration > 0) {
180
+ this.state = { ...this.state, frameDuration: newFrameDuration }
181
+ }
182
+ }
183
+
184
+ getResource(): SpriteResource {
185
+ return this.resource
186
+ }
187
+
188
+ releaseInstanceSlot(): void {
189
+ this.instanceManager.releaseInstanceSlot(this.instanceIndex)
190
+ }
191
+ }
192
+
193
+ export class TiledSprite {
194
+ public readonly id: string
195
+ private animator: SpriteAnimator
196
+ private _animations: Map<string, Animation>
197
+ private _currentAnimation: Animation
198
+ private _transformObject: THREE.Object3D
199
+
200
+ private _reusableMatrix: THREE.Matrix4
201
+ private _reusableAnimGeomScale: THREE.Vector3
202
+ private _isVisibleState: boolean = true
203
+ private originalDefinition: SpriteDefinition
204
+
205
+ constructor(
206
+ id: string,
207
+ userSpriteDefinition: SpriteDefinition,
208
+ animator: SpriteAnimator,
209
+ animationInstanceParams: Array<{
210
+ name: string
211
+ state: ResolvedAnimationState
212
+ resource: SpriteResource
213
+ index: number
214
+ instanceManager: InstanceManager
215
+ frameAttribute: THREE.InstancedBufferAttribute
216
+ flipAttribute: THREE.InstancedBufferAttribute
217
+ }>,
218
+ ) {
219
+ this.id = id
220
+ this.originalDefinition = userSpriteDefinition
221
+ this.animator = animator
222
+ this._transformObject = new THREE.Object3D()
223
+ this._reusableMatrix = new THREE.Matrix4()
224
+ this._reusableAnimGeomScale = new THREE.Vector3()
225
+
226
+ const initialScale = userSpriteDefinition.scale ?? DEFAULT_SCALE
227
+ this._transformObject.scale.set(initialScale, initialScale, initialScale)
228
+
229
+ this._animations = new Map()
230
+ for (const params of animationInstanceParams) {
231
+ const anim = new Animation(
232
+ params.name,
233
+ params.state,
234
+ params.resource,
235
+ params.index,
236
+ params.instanceManager,
237
+ params.frameAttribute,
238
+ params.flipAttribute,
239
+ )
240
+ this._animations.set(params.name, anim)
241
+ }
242
+
243
+ const initialAnim = this._animations.get(userSpriteDefinition.initialAnimation)
244
+ if (!initialAnim) {
245
+ throw new Error(
246
+ `[TiledSprite] Initial animation "${userSpriteDefinition.initialAnimation}" not found for sprite "${this.id}".`,
247
+ )
248
+ }
249
+ this._currentAnimation = initialAnim
250
+ const initialWorldMatrix = this._calculateAnimationWorldMatrix(this._currentAnimation.state)
251
+ this._currentAnimation.activate(initialWorldMatrix)
252
+ this._isVisibleState = true
253
+ }
254
+
255
+ private _calculateAnimationWorldMatrix(animState: ResolvedAnimationState): THREE.Matrix4 {
256
+ const matrix = this._reusableMatrix
257
+ const animGeomScale = this._reusableAnimGeomScale
258
+ const worldHeight = this._transformObject.scale.y
259
+ const frameAspectRatio = animState.sheetTilesetWidth / animState.sheetNumFrames / animState.sheetTilesetHeight
260
+ const worldWidth = worldHeight * frameAspectRatio
261
+ animGeomScale.set(worldWidth, worldHeight, this._transformObject.scale.z)
262
+ matrix.compose(this._transformObject.position, this._transformObject.quaternion, animGeomScale)
263
+ return matrix
264
+ }
265
+
266
+ public get currentAnimation(): Animation {
267
+ return this._currentAnimation
268
+ }
269
+
270
+ private updateCurrentAnimationVisuals(): void {
271
+ if (this._isVisibleState) {
272
+ const currentAnim = this.currentAnimation
273
+ if (currentAnim) {
274
+ const finalMatrix = this._calculateAnimationWorldMatrix(currentAnim.state)
275
+ currentAnim.updateVisuals(finalMatrix)
276
+ }
277
+ }
278
+ }
279
+
280
+ setPosition(position: THREE.Vector3): void {
281
+ this._transformObject.position.copy(position)
282
+ this.updateCurrentAnimationVisuals()
283
+ }
284
+
285
+ setRotation(rotation: THREE.Quaternion): void {
286
+ this._transformObject.quaternion.copy(rotation)
287
+ this.updateCurrentAnimationVisuals()
288
+ }
289
+
290
+ setScale(scale: THREE.Vector3): void {
291
+ this._transformObject.scale.copy(scale)
292
+ this.updateCurrentAnimationVisuals()
293
+ }
294
+
295
+ getScale(): THREE.Vector3 {
296
+ return this._transformObject.scale.clone()
297
+ }
298
+
299
+ setTransform(position: THREE.Vector3, rotation: THREE.Quaternion, newScale: THREE.Vector3): void {
300
+ this._transformObject.position.copy(position)
301
+ this._transformObject.quaternion.copy(rotation)
302
+ this._transformObject.scale.copy(newScale)
303
+ this.updateCurrentAnimationVisuals()
304
+ }
305
+
306
+ play(): void {
307
+ this.currentAnimation.play()
308
+ }
309
+ stop(): void {
310
+ this.currentAnimation.stop()
311
+ }
312
+ goToFrame(frame: number): void {
313
+ this.currentAnimation.goToFrame(frame)
314
+ }
315
+ setFrameDuration(newFrameDuration: number): void {
316
+ this.currentAnimation.setFrameDuration(newFrameDuration)
317
+ }
318
+
319
+ isPlaying(): boolean {
320
+ return this.currentAnimation.isPlaying
321
+ }
322
+
323
+ async setAnimation(animationName: string): Promise<void> {
324
+ const newAnim = this._animations.get(animationName)
325
+ if (!newAnim) {
326
+ throw new Error(`[TiledSprite] Animation "${animationName}" not found for sprite "${this.id}".`)
327
+ }
328
+
329
+ const switchingToSameAnimation = this._currentAnimation.name === animationName
330
+ const oldAnim = this._currentAnimation
331
+
332
+ if (!switchingToSameAnimation || !this._isVisibleState) {
333
+ oldAnim?.deactivate()
334
+ }
335
+
336
+ this._currentAnimation = newAnim
337
+
338
+ if (this._isVisibleState) {
339
+ const finalMatrix = this._calculateAnimationWorldMatrix(newAnim.state)
340
+ newAnim.activate(finalMatrix)
341
+ } else {
342
+ newAnim.deactivate()
343
+ }
344
+ }
345
+
346
+ update(deltaTime: number): void {
347
+ if (this.visible) {
348
+ this.currentAnimation.updateTime(deltaTime)
349
+ }
350
+ }
351
+
352
+ destroy(): void {
353
+ this._animations.forEach((anim) => {
354
+ anim.deactivate()
355
+ anim.releaseInstanceSlot()
356
+ })
357
+ this._animations.clear()
358
+ this._isVisibleState = false
359
+ }
360
+
361
+ getCurrentAnimationName(): string {
362
+ return this._currentAnimation.name
363
+ }
364
+
365
+ getWorldTransform(): THREE.Matrix4 {
366
+ return this._calculateAnimationWorldMatrix(this._currentAnimation.state)
367
+ }
368
+
369
+ getWorldPlaneSize(): THREE.Vector2 {
370
+ const animState = this._currentAnimation.state
371
+ const worldHeight = this._transformObject.scale.y
372
+ const frameActualWidthPx = animState.sheetTilesetWidth / animState.sheetNumFrames
373
+ const frameAspectRatio = frameActualWidthPx / animState.sheetTilesetHeight
374
+ const worldWidth = worldHeight * frameAspectRatio
375
+ return new THREE.Vector2(worldWidth, worldHeight)
376
+ }
377
+
378
+ get visible(): boolean {
379
+ return this._isVisibleState
380
+ }
381
+
382
+ set visible(value: boolean) {
383
+ if (this._isVisibleState === value) {
384
+ return
385
+ }
386
+ this._isVisibleState = value
387
+ if (value) {
388
+ const finalMatrix = this._calculateAnimationWorldMatrix(this._currentAnimation.state)
389
+ this._currentAnimation.activate(finalMatrix)
390
+ } else {
391
+ this._currentAnimation.deactivate()
392
+ }
393
+ }
394
+
395
+ public get definition(): SpriteDefinition {
396
+ return this.originalDefinition
397
+ }
398
+
399
+ public get currentTransform(): {
400
+ position: THREE.Vector3
401
+ quaternion: THREE.Quaternion
402
+ scale: THREE.Vector3
403
+ } {
404
+ return {
405
+ position: this._transformObject.position.clone(),
406
+ quaternion: this._transformObject.quaternion.clone(),
407
+ scale: this._transformObject.scale.clone(),
408
+ }
409
+ }
410
+ }
411
+
412
+ interface SpriteAnimatorInstanceManager {
413
+ instanceManager: InstanceManager
414
+ frameAttribute: THREE.InstancedBufferAttribute
415
+ flipAttribute: THREE.InstancedBufferAttribute
416
+ uvTileSize: THREE.Vector2
417
+ }
418
+
419
+ export class SpriteAnimator {
420
+ private instances: Map<string, TiledSprite> = new Map()
421
+ private _idCounter = 0
422
+ private instanceManagers: Map<string, SpriteAnimatorInstanceManager> = new Map()
423
+
424
+ constructor(private scene: Scene) {}
425
+
426
+ private createSpriteAnimationMaterial(
427
+ resource: SpriteResource,
428
+ frameAttribute: THREE.InstancedBufferAttribute,
429
+ flipAttribute: THREE.InstancedBufferAttribute,
430
+ materialFactory: () => NodeMaterial,
431
+ ): NodeMaterial {
432
+ const texture = resource.texture
433
+ const sheetProps = resource.sheetProperties
434
+
435
+ const uvTileWidth = 1.0 / sheetProps.sheetNumFrames
436
+ const uvTileHeight = 1.0
437
+ const uvTileSize = new THREE.Vector2(uvTileWidth, uvTileHeight)
438
+
439
+ const tileSizeUniform = uniform(uvTileSize)
440
+ const epsilon = float(0.000001)
441
+
442
+ const baseUV = uv()
443
+ const oneFloat = float(1.0)
444
+
445
+ const a_frameIndex = bufferAttribute(frameAttribute)
446
+ const a_flip = bufferAttribute(flipAttribute)
447
+
448
+ const calculatedTileCoordX = a_frameIndex.mul(tileSizeUniform.x)
449
+ const calculatedTileCoord = vec2(calculatedTileCoordX, float(0))
450
+
451
+ const flippedX = mix(baseUV.x, oneFloat.sub(baseUV.x), a_flip.x)
452
+ const flippedY = mix(baseUV.y, oneFloat.sub(baseUV.y), a_flip.y)
453
+ const finalLocalUV = vec2(flippedX, flippedY)
454
+
455
+ const mapNode = tslTexture(texture)
456
+ const finalUV = finalLocalUV.mul(tileSizeUniform).min(tileSizeUniform.sub(epsilon)).add(calculatedTileCoord)
457
+ const sampledColor = mapNode.sample(finalUV)
458
+
459
+ const material = materialFactory()
460
+ material.colorNode = sampledColor
461
+
462
+ return material
463
+ }
464
+
465
+ private getOrCreateInstanceManager(
466
+ resource: SpriteResource,
467
+ maxInstances: number,
468
+ renderOrder: number,
469
+ depthWrite: boolean,
470
+ materialFactory: () => NodeMaterial,
471
+ ): SpriteAnimatorInstanceManager {
472
+ const key = `${resource.sheetProperties.imagePath}_${maxInstances}_${renderOrder}_${depthWrite}`
473
+ let manager = this.instanceManagers.get(key)
474
+
475
+ if (!manager) {
476
+ const geometry = new THREE.PlaneGeometry(1, 1)
477
+ const frameArray = new Float32Array(maxInstances)
478
+ const frameAttribute = new THREE.InstancedBufferAttribute(frameArray, 1)
479
+ frameAttribute.setUsage(THREE.DynamicDrawUsage)
480
+
481
+ const flipArray = new Float32Array(maxInstances * 2)
482
+ const flipAttribute = new THREE.InstancedBufferAttribute(flipArray, 2)
483
+ flipAttribute.setUsage(THREE.DynamicDrawUsage)
484
+
485
+ const material = this.createSpriteAnimationMaterial(resource, frameAttribute, flipAttribute, materialFactory)
486
+
487
+ geometry.setAttribute("a_frameIndexInstanced", frameAttribute)
488
+ geometry.setAttribute("a_flipInstanced", flipAttribute)
489
+
490
+ for (let i = 0; i < maxInstances; i++) {
491
+ flipAttribute.setXY(i, 0.0, 0.0)
492
+ }
493
+ flipAttribute.needsUpdate = true
494
+
495
+ const instanceManager = resource.createInstanceManager(geometry, material, {
496
+ maxInstances,
497
+ renderOrder,
498
+ depthWrite,
499
+ name: `SpriteAnimator_${key}`,
500
+ })
501
+
502
+ const uvTileWidth = 1.0 / resource.sheetProperties.sheetNumFrames
503
+ const uvTileSize = new THREE.Vector2(uvTileWidth, 1.0)
504
+
505
+ manager = {
506
+ instanceManager,
507
+ frameAttribute,
508
+ flipAttribute,
509
+ uvTileSize,
510
+ }
511
+
512
+ this.instanceManagers.set(key, manager)
513
+ }
514
+
515
+ return manager
516
+ }
517
+
518
+ async createSprite(
519
+ userSpriteDefinition: SpriteDefinition,
520
+ materialFactory?: () => NodeMaterial,
521
+ ): Promise<TiledSprite> {
522
+ const id = userSpriteDefinition.id ?? `sprite_${this._idCounter++}`
523
+ const animationInstanceParams: Array<{
524
+ name: string
525
+ state: ResolvedAnimationState
526
+ resource: SpriteResource
527
+ index: number
528
+ instanceManager: InstanceManager
529
+ frameAttribute: THREE.InstancedBufferAttribute
530
+ flipAttribute: THREE.InstancedBufferAttribute
531
+ }> = []
532
+
533
+ const resolvedMaterialFactory =
534
+ materialFactory ??
535
+ (() =>
536
+ new MeshBasicNodeMaterial({
537
+ transparent: true,
538
+ alphaTest: 0.1,
539
+ depthWrite: true,
540
+ }))
541
+
542
+ // Track instance managers as we encounter resources
543
+ const resourceManagers = new Map<SpriteResource, SpriteAnimatorInstanceManager>()
544
+
545
+ for (const animName in userSpriteDefinition.animations) {
546
+ const animDef = userSpriteDefinition.animations[animName]
547
+ const resource = animDef.resource
548
+
549
+ // Get or create instance manager for this resource
550
+ let managerInfo = resourceManagers.get(resource)
551
+ if (!managerInfo) {
552
+ const maxInstances = userSpriteDefinition.maxInstances ?? 1024
553
+ const renderOrder = userSpriteDefinition.renderOrder ?? 0
554
+ const depthWrite = userSpriteDefinition.depthWrite ?? true
555
+ managerInfo = this.getOrCreateInstanceManager(
556
+ resource,
557
+ maxInstances,
558
+ renderOrder,
559
+ depthWrite,
560
+ resolvedMaterialFactory,
561
+ )
562
+ resourceManagers.set(resource, managerInfo)
563
+ }
564
+
565
+ const instanceIndex = managerInfo.instanceManager.acquireInstanceSlot()
566
+
567
+ const resolvedState: ResolvedAnimationState = {
568
+ imagePath: resource.sheetProperties.imagePath,
569
+ sheetTilesetWidth: resource.sheetProperties.sheetTilesetWidth,
570
+ sheetTilesetHeight: resource.sheetProperties.sheetTilesetHeight,
571
+ sheetNumFrames: resource.sheetProperties.sheetNumFrames,
572
+ animNumFrames: animDef.animNumFrames ?? resource.sheetProperties.sheetNumFrames,
573
+ animFrameOffset: animDef.animFrameOffset ?? 0,
574
+ frameDuration: animDef.frameDuration ?? DEFAULT_FRAME_DURATION,
575
+ loop: animDef.loop ?? true,
576
+ initialFrame: animDef.initialFrame ?? DEFAULT_INITIAL_FRAME,
577
+ flipX: animDef.flipX ?? DEFAULT_FLIP_X,
578
+ flipY: animDef.flipY ?? DEFAULT_FLIP_Y,
579
+ texture: resource.texture,
580
+ }
581
+
582
+ animationInstanceParams.push({
583
+ name: animName,
584
+ state: resolvedState,
585
+ resource,
586
+ index: instanceIndex,
587
+ instanceManager: managerInfo.instanceManager,
588
+ frameAttribute: managerInfo.frameAttribute,
589
+ flipAttribute: managerInfo.flipAttribute,
590
+ })
591
+ }
592
+
593
+ if (
594
+ !userSpriteDefinition.initialAnimation ||
595
+ !userSpriteDefinition.animations[userSpriteDefinition.initialAnimation]
596
+ ) {
597
+ let found = false
598
+ for (const p of animationInstanceParams) if (p.name === userSpriteDefinition.initialAnimation) found = true
599
+ if (!found) {
600
+ for (const params of animationInstanceParams) {
601
+ params.instanceManager.releaseInstanceSlot(params.index)
602
+ }
603
+ throw new Error(
604
+ `[SpriteAnimator] initialAnimation "${userSpriteDefinition.initialAnimation}" not found or invalid for sprite "${id}".`,
605
+ )
606
+ }
607
+ }
608
+ const tiledSprite = new TiledSprite(id, userSpriteDefinition, this, animationInstanceParams)
609
+ this.instances.set(id, tiledSprite)
610
+ return tiledSprite
611
+ }
612
+
613
+ update(deltaTime: number): void {
614
+ for (const sprite of this.instances.values()) {
615
+ sprite.update(deltaTime)
616
+ }
617
+ }
618
+
619
+ removeSprite(id: string): void {
620
+ const sprite = this.instances.get(id)
621
+ if (sprite) {
622
+ sprite.destroy()
623
+ this.instances.delete(id)
624
+ }
625
+ }
626
+
627
+ removeAllSprites(): void {
628
+ const ids = Array.from(this.instances.keys())
629
+ for (const id of ids) {
630
+ this.removeSprite(id)
631
+ }
632
+ }
633
+ }