@multiplekex/shallot 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/dist/core/builder.d.ts +25 -0
  2. package/dist/core/builder.d.ts.map +1 -0
  3. package/dist/core/builder.js +88 -0
  4. package/dist/core/builder.js.map +1 -0
  5. package/dist/core/component.d.ts +29 -0
  6. package/dist/core/component.d.ts.map +1 -0
  7. package/dist/core/component.js +36 -0
  8. package/dist/core/component.js.map +1 -0
  9. package/dist/core/index.d.ts +13 -0
  10. package/dist/core/index.d.ts.map +1 -0
  11. package/dist/core/math.d.ts +32 -0
  12. package/dist/core/math.d.ts.map +1 -0
  13. package/dist/core/math.js +39 -0
  14. package/dist/core/math.js.map +1 -0
  15. package/dist/core/relation.d.ts +16 -0
  16. package/dist/core/relation.d.ts.map +1 -0
  17. package/dist/core/relation.js +32 -0
  18. package/dist/core/relation.js.map +1 -0
  19. package/dist/core/resource.d.ts +9 -0
  20. package/dist/core/resource.d.ts.map +1 -0
  21. package/dist/core/resource.js +12 -0
  22. package/dist/core/resource.js.map +1 -0
  23. package/dist/core/runtime.d.ts +13 -0
  24. package/dist/core/runtime.d.ts.map +1 -0
  25. package/dist/core/runtime.js +118 -0
  26. package/dist/core/runtime.js.map +1 -0
  27. package/dist/core/scheduler.d.ts +47 -0
  28. package/dist/core/scheduler.d.ts.map +1 -0
  29. package/dist/core/scheduler.js +138 -0
  30. package/dist/core/scheduler.js.map +1 -0
  31. package/dist/core/state.d.ts +62 -0
  32. package/dist/core/state.d.ts.map +1 -0
  33. package/dist/core/state.js +185 -0
  34. package/dist/core/state.js.map +1 -0
  35. package/dist/core/strings.d.ts +3 -0
  36. package/dist/core/strings.d.ts.map +1 -0
  37. package/dist/core/strings.js +11 -0
  38. package/dist/core/strings.js.map +1 -0
  39. package/dist/core/types.d.ts +33 -0
  40. package/dist/core/types.d.ts.map +1 -0
  41. package/dist/core/xml.d.ts +42 -0
  42. package/dist/core/xml.d.ts.map +1 -0
  43. package/dist/core/xml.js +349 -0
  44. package/dist/core/xml.js.map +1 -0
  45. package/dist/extras/arrows/index.d.ts +33 -0
  46. package/dist/extras/arrows/index.d.ts.map +1 -0
  47. package/dist/extras/arrows/index.js +288 -0
  48. package/dist/extras/arrows/index.js.map +1 -0
  49. package/dist/extras/index.d.ts +5 -0
  50. package/dist/extras/index.d.ts.map +1 -0
  51. package/dist/extras/index.js +31 -0
  52. package/dist/extras/index.js.map +1 -0
  53. package/dist/extras/lines/index.d.ts +36 -0
  54. package/dist/extras/lines/index.d.ts.map +1 -0
  55. package/dist/extras/lines/index.js +288 -0
  56. package/dist/extras/lines/index.js.map +1 -0
  57. package/dist/extras/orbit/index.d.ts +20 -0
  58. package/dist/extras/orbit/index.d.ts.map +1 -0
  59. package/dist/extras/orbit/index.js +93 -0
  60. package/dist/extras/orbit/index.js.map +1 -0
  61. package/dist/extras/text/index.d.ts +64 -0
  62. package/dist/extras/text/index.d.ts.map +1 -0
  63. package/dist/extras/text/index.js +423 -0
  64. package/dist/extras/text/index.js.map +1 -0
  65. package/dist/index.d.ts +4 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +187 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/rust/transforms/pkg/shallot_transforms.js +107 -0
  70. package/dist/rust/transforms/pkg/shallot_transforms.js.map +1 -0
  71. package/dist/standard/compute/graph.d.ts +37 -0
  72. package/dist/standard/compute/graph.d.ts.map +1 -0
  73. package/dist/standard/compute/graph.js +85 -0
  74. package/dist/standard/compute/graph.js.map +1 -0
  75. package/dist/standard/compute/index.d.ts +21 -0
  76. package/dist/standard/compute/index.d.ts.map +1 -0
  77. package/dist/standard/compute/index.js +81 -0
  78. package/dist/standard/compute/index.js.map +1 -0
  79. package/dist/standard/defaults.d.ts +3 -0
  80. package/dist/standard/defaults.d.ts.map +1 -0
  81. package/dist/standard/defaults.js +18 -0
  82. package/dist/standard/defaults.js.map +1 -0
  83. package/dist/standard/index.d.ts +8 -0
  84. package/dist/standard/index.d.ts.map +1 -0
  85. package/dist/standard/input/index.d.ts +5 -0
  86. package/dist/standard/input/index.d.ts.map +1 -0
  87. package/dist/standard/input/index.js +70 -0
  88. package/dist/standard/input/index.js.map +1 -0
  89. package/dist/standard/loading/index.d.ts +7 -0
  90. package/dist/standard/loading/index.d.ts.map +1 -0
  91. package/dist/standard/loading/index.js +91 -0
  92. package/dist/standard/loading/index.js.map +1 -0
  93. package/dist/standard/render/camera.d.ts +36 -0
  94. package/dist/standard/render/camera.d.ts.map +1 -0
  95. package/dist/standard/render/camera.js +71 -0
  96. package/dist/standard/render/camera.js.map +1 -0
  97. package/dist/standard/render/forward.d.ts +30 -0
  98. package/dist/standard/render/forward.d.ts.map +1 -0
  99. package/dist/standard/render/forward.js +158 -0
  100. package/dist/standard/render/forward.js.map +1 -0
  101. package/dist/standard/render/index.d.ts +22 -0
  102. package/dist/standard/render/index.d.ts.map +1 -0
  103. package/dist/standard/render/index.js +153 -0
  104. package/dist/standard/render/index.js.map +1 -0
  105. package/dist/standard/render/light.d.ts +25 -0
  106. package/dist/standard/render/light.d.ts.map +1 -0
  107. package/dist/standard/render/light.js +48 -0
  108. package/dist/standard/render/light.js.map +1 -0
  109. package/dist/standard/render/mesh/box.d.ts +3 -0
  110. package/dist/standard/render/mesh/box.d.ts.map +1 -0
  111. package/dist/standard/render/mesh/box.js +190 -0
  112. package/dist/standard/render/mesh/box.js.map +1 -0
  113. package/dist/standard/render/mesh/index.d.ts +52 -0
  114. package/dist/standard/render/mesh/index.d.ts.map +1 -0
  115. package/dist/standard/render/mesh/index.js +158 -0
  116. package/dist/standard/render/mesh/index.js.map +1 -0
  117. package/dist/standard/render/mesh/plane.d.ts +3 -0
  118. package/dist/standard/render/mesh/plane.d.ts.map +1 -0
  119. package/dist/standard/render/mesh/plane.js +33 -0
  120. package/dist/standard/render/mesh/plane.js.map +1 -0
  121. package/dist/standard/render/mesh/sphere.d.ts +3 -0
  122. package/dist/standard/render/mesh/sphere.d.ts.map +1 -0
  123. package/dist/standard/render/mesh/sphere.js +25 -0
  124. package/dist/standard/render/mesh/sphere.js.map +1 -0
  125. package/dist/standard/render/postprocess.d.ts +11 -0
  126. package/dist/standard/render/postprocess.d.ts.map +1 -0
  127. package/dist/standard/render/postprocess.js +190 -0
  128. package/dist/standard/render/postprocess.js.map +1 -0
  129. package/dist/standard/render/scene.d.ts +8 -0
  130. package/dist/standard/render/scene.d.ts.map +1 -0
  131. package/dist/standard/render/scene.js +67 -0
  132. package/dist/standard/render/scene.js.map +1 -0
  133. package/dist/standard/transforms/index.d.ts +27 -0
  134. package/dist/standard/transforms/index.d.ts.map +1 -0
  135. package/dist/standard/transforms/index.js +122 -0
  136. package/dist/standard/transforms/index.js.map +1 -0
  137. package/dist/standard/transforms/wasm.d.ts +17 -0
  138. package/dist/standard/transforms/wasm.d.ts.map +1 -0
  139. package/dist/standard/transforms/wasm.js +31 -0
  140. package/dist/standard/transforms/wasm.js.map +1 -0
  141. package/dist/standard/tween/easing.d.ts +5 -0
  142. package/dist/standard/tween/easing.d.ts.map +1 -0
  143. package/dist/standard/tween/easing.js +80 -0
  144. package/dist/standard/tween/easing.js.map +1 -0
  145. package/dist/standard/tween/index.d.ts +4 -0
  146. package/dist/standard/tween/index.d.ts.map +1 -0
  147. package/dist/standard/tween/sequence.d.ts +20 -0
  148. package/dist/standard/tween/sequence.d.ts.map +1 -0
  149. package/dist/standard/tween/sequence.js +95 -0
  150. package/dist/standard/tween/sequence.js.map +1 -0
  151. package/dist/standard/tween/tween.d.ts +28 -0
  152. package/dist/standard/tween/tween.d.ts.map +1 -0
  153. package/dist/standard/tween/tween.js +136 -0
  154. package/dist/standard/tween/tween.js.map +1 -0
  155. package/package.json +63 -0
  156. package/src/core/builder.ts +148 -0
  157. package/src/core/component.ts +71 -0
  158. package/src/core/index.ts +92 -0
  159. package/src/core/math.ts +128 -0
  160. package/src/core/relation.ts +46 -0
  161. package/src/core/resource.ts +18 -0
  162. package/src/core/runtime.ts +185 -0
  163. package/src/core/scheduler.ts +238 -0
  164. package/src/core/state.ts +295 -0
  165. package/src/core/strings.ts +10 -0
  166. package/src/core/types.ts +37 -0
  167. package/src/core/xml.ts +676 -0
  168. package/src/extras/arrows/index.ts +363 -0
  169. package/src/extras/index.ts +4 -0
  170. package/src/extras/lines/index.ts +368 -0
  171. package/src/extras/orbit/index.ts +133 -0
  172. package/src/extras/text/index.ts +641 -0
  173. package/src/index.ts +3 -0
  174. package/src/standard/compute/graph.ts +165 -0
  175. package/src/standard/compute/index.ts +116 -0
  176. package/src/standard/defaults.ts +17 -0
  177. package/src/standard/index.ts +7 -0
  178. package/src/standard/input/index.ts +142 -0
  179. package/src/standard/loading/index.ts +136 -0
  180. package/src/standard/render/camera.ts +87 -0
  181. package/src/standard/render/forward.ts +212 -0
  182. package/src/standard/render/index.ts +175 -0
  183. package/src/standard/render/light.ts +81 -0
  184. package/src/standard/render/mesh/box.ts +20 -0
  185. package/src/standard/render/mesh/index.ts +227 -0
  186. package/src/standard/render/mesh/plane.ts +11 -0
  187. package/src/standard/render/mesh/sphere.ts +40 -0
  188. package/src/standard/render/postprocess.ts +235 -0
  189. package/src/standard/render/scene.ts +116 -0
  190. package/src/standard/transforms/index.ts +184 -0
  191. package/src/standard/transforms/wasm.ts +61 -0
  192. package/src/standard/tween/easing.ts +169 -0
  193. package/src/standard/tween/index.ts +13 -0
  194. package/src/standard/tween/sequence.ts +142 -0
  195. package/src/standard/tween/tween.ts +265 -0
  196. package/src/vite-env.d.ts +6 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"easing.js","sources":["../../../src/standard/tween/easing.ts"],"sourcesContent":["export type EasingFn = (t: number) => number;\n\nconst linear: EasingFn = (t) => t;\n\nconst easeInQuad: EasingFn = (t) => t * t;\nconst easeOutQuad: EasingFn = (t) => t * (2 - t);\nconst easeInOutQuad: EasingFn = (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t);\n\nconst easeInCubic: EasingFn = (t) => t * t * t;\nconst easeOutCubic: EasingFn = (t) => --t * t * t + 1;\nconst easeInOutCubic: EasingFn = (t) =>\n t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n\nconst easeInQuart: EasingFn = (t) => t * t * t * t;\nconst easeOutQuart: EasingFn = (t) => 1 - --t * t * t * t;\nconst easeInOutQuart: EasingFn = (t) => (t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t);\n\nconst easeInQuint: EasingFn = (t) => t * t * t * t * t;\nconst easeOutQuint: EasingFn = (t) => 1 + --t * t * t * t * t;\nconst easeInOutQuint: EasingFn = (t) =>\n t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;\n\nconst easeInSine: EasingFn = (t) => 1 - Math.cos((t * Math.PI) / 2);\nconst easeOutSine: EasingFn = (t) => Math.sin((t * Math.PI) / 2);\nconst easeInOutSine: EasingFn = (t) => -(Math.cos(Math.PI * t) - 1) / 2;\n\nconst easeInExpo: EasingFn = (t) => (t === 0 ? 0 : Math.pow(2, 10 * t - 10));\nconst easeOutExpo: EasingFn = (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t));\nconst easeInOutExpo: EasingFn = (t) =>\n t === 0\n ? 0\n : t === 1\n ? 1\n : t < 0.5\n ? Math.pow(2, 20 * t - 10) / 2\n : (2 - Math.pow(2, -20 * t + 10)) / 2;\n\nconst easeInCirc: EasingFn = (t) => 1 - Math.sqrt(1 - t * t);\nconst easeOutCirc: EasingFn = (t) => Math.sqrt(1 - --t * t);\nconst easeInOutCirc: EasingFn = (t) =>\n t < 0.5\n ? (1 - Math.sqrt(1 - 4 * t * t)) / 2\n : (Math.sqrt(1 - (-2 * t + 2) * (-2 * t + 2)) + 1) / 2;\n\nconst easeInBack: EasingFn = (t) => {\n const c = 1.70158;\n return (c + 1) * t * t * t - c * t * t;\n};\nconst easeOutBack: EasingFn = (t) => {\n const c = 1.70158;\n return 1 + (c + 1) * Math.pow(t - 1, 3) + c * Math.pow(t - 1, 2);\n};\nconst easeInOutBack: EasingFn = (t) => {\n const c = 1.70158 * 1.525;\n return t < 0.5\n ? (Math.pow(2 * t, 2) * ((c + 1) * 2 * t - c)) / 2\n : (Math.pow(2 * t - 2, 2) * ((c + 1) * (t * 2 - 2) + c) + 2) / 2;\n};\n\nconst easeInElastic: EasingFn = (t) =>\n t === 0\n ? 0\n : t === 1\n ? 1\n : -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * ((2 * Math.PI) / 3));\nconst easeOutElastic: EasingFn = (t) =>\n t === 0\n ? 0\n : t === 1\n ? 1\n : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * ((2 * Math.PI) / 3)) + 1;\nconst easeInOutElastic: EasingFn = (t) =>\n t === 0\n ? 0\n : t === 1\n ? 1\n : t < 0.5\n ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * ((2 * Math.PI) / 4.5))) / 2\n : (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * ((2 * Math.PI) / 4.5))) /\n 2 +\n 1;\n\nconst easeOutBounce: EasingFn = (t) => {\n const n1 = 7.5625;\n const d1 = 2.75;\n if (t < 1 / d1) return n1 * t * t;\n if (t < 2 / d1) return n1 * (t -= 1.5 / d1) * t + 0.75;\n if (t < 2.5 / d1) return n1 * (t -= 2.25 / d1) * t + 0.9375;\n return n1 * (t -= 2.625 / d1) * t + 0.984375;\n};\nconst easeInBounce: EasingFn = (t) => 1 - easeOutBounce(1 - t);\nconst easeInOutBounce: EasingFn = (t) =>\n t < 0.5 ? (1 - easeOutBounce(1 - 2 * t)) / 2 : (1 + easeOutBounce(2 * t - 1)) / 2;\n\nexport const EASING_FUNCTIONS: readonly EasingFn[] = [\n linear,\n easeInQuad,\n easeOutQuad,\n easeInOutQuad,\n easeInCubic,\n easeOutCubic,\n easeInOutCubic,\n easeInQuart,\n easeOutQuart,\n easeInOutQuart,\n easeInQuint,\n easeOutQuint,\n easeInOutQuint,\n easeInSine,\n easeOutSine,\n easeInOutSine,\n easeInExpo,\n easeOutExpo,\n easeInOutExpo,\n easeInCirc,\n easeOutCirc,\n easeInOutCirc,\n easeInBack,\n easeOutBack,\n easeInOutBack,\n easeInElastic,\n easeOutElastic,\n easeInOutElastic,\n easeInBounce,\n easeOutBounce,\n easeInOutBounce,\n] as const;\n\nconst EASING_INDEX: Record<string, number> = {\n linear: 0,\n \"ease-in-quad\": 1,\n \"ease-out-quad\": 2,\n \"ease-in-out-quad\": 3,\n \"ease-in-cubic\": 4,\n \"ease-out-cubic\": 5,\n \"ease-in-out-cubic\": 6,\n \"ease-in-quart\": 7,\n \"ease-out-quart\": 8,\n \"ease-in-out-quart\": 9,\n \"ease-in-quint\": 10,\n \"ease-out-quint\": 11,\n \"ease-in-out-quint\": 12,\n \"ease-in-sine\": 13,\n \"ease-out-sine\": 14,\n \"ease-in-out-sine\": 15,\n \"ease-in-expo\": 16,\n \"ease-out-expo\": 17,\n \"ease-in-out-expo\": 18,\n \"ease-in-circ\": 19,\n \"ease-out-circ\": 20,\n \"ease-in-out-circ\": 21,\n \"ease-in-back\": 22,\n \"ease-out-back\": 23,\n \"ease-in-out-back\": 24,\n \"ease-in-elastic\": 25,\n \"ease-out-elastic\": 26,\n \"ease-in-out-elastic\": 27,\n \"ease-in-bounce\": 28,\n \"ease-out-bounce\": 29,\n \"ease-in-out-bounce\": 30,\n};\n\nexport function getEasingIndex(name: string): number {\n return EASING_INDEX[name] ?? 0;\n}\n\nexport function getEasing(index: number): EasingFn {\n return EASING_FUNCTIONS[index] ?? linear;\n}\n"],"names":["linear","t","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInSine","easeOutSine","easeInOutSine","easeInExpo","easeOutExpo","easeInOutExpo","easeInCirc","easeOutCirc","easeInOutCirc","easeInBack","easeOutBack","easeInOutBack","c","easeInElastic","easeOutElastic","easeInOutElastic","easeOutBounce","easeInBounce","easeInOutBounce","EASING_FUNCTIONS","EASING_INDEX","getEasingIndex","name","getEasing","index"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { Tween, TweenState, TweenTarget, TweenSystem, TweenPlugin, createTween, type TweenOptions, } from './tween';
2
+ export { Sequence, SequenceState, Pause, computeTweenDelays, finalizeSequences } from './sequence';
3
+ export { EASING_FUNCTIONS, getEasing, getEasingIndex, type EasingFn } from './easing';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/standard/tween/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,KAAK,YAAY,GACpB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEnG,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { State, ParseContext } from '../../core';
2
+ export declare const Pause: {
3
+ duration: number[];
4
+ };
5
+ export declare const SequenceState: {
6
+ readonly IDLE: 0;
7
+ readonly PLAYING: 1;
8
+ readonly COMPLETE: 2;
9
+ };
10
+ export declare const Sequence: {
11
+ state: number[];
12
+ elapsed: number[];
13
+ };
14
+ export declare function finalizeSequences(_state: State, _context: ParseContext): void;
15
+ export declare function computeTweenDelays(state: State, seqEid: number): void;
16
+ declare function ensureSequencesResolved(state: State): void;
17
+ declare function checkSequenceCompletion(state: State): void;
18
+ export declare function updateSequences(state: State, dt: number): void;
19
+ export { ensureSequencesResolved, checkSequenceCompletion };
20
+ //# sourceMappingURL=sequence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../../../src/standard/tween/sequence.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AASpE,eAAO,MAAM,KAAK;cACE,MAAM,EAAE;CAC3B,CAAC;AAMF,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AAEX,eAAO,MAAM,QAAQ;WACJ,MAAM,EAAE;aACN,MAAM,EAAE;CAC1B,CAAC;AASF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAG;AAWjF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAWrE;AAiDD,iBAAS,uBAAuB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAMnD;AAED,iBAAS,uBAAuB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAmBnD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAE9D;AAED,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1,95 @@
1
+ import { Pair as f } from "bitecs";
2
+ import { setTraits as h } from "../../core/component.js";
3
+ import "../../core/builder.js";
4
+ import { ChildOf as p } from "../../core/relation.js";
5
+ import "../../core/math.js";
6
+ import "fast-xml-parser";
7
+ import { Tween as n, TweenState as a, ensureResolved as T, captureFromValue as C } from "./tween.js";
8
+ const L = (e, t) => e - t, P = (e, t) => e.endTime - t.endTime, d = [], l = [], E = {
9
+ duration: []
10
+ };
11
+ h(E, {
12
+ defaults: () => ({ duration: 0.5 })
13
+ });
14
+ const u = {
15
+ IDLE: 0,
16
+ PLAYING: 1,
17
+ COMPLETE: 2
18
+ }, r = {
19
+ state: [],
20
+ elapsed: []
21
+ };
22
+ h(r, {
23
+ defaults: () => ({
24
+ state: u.IDLE,
25
+ elapsed: 0
26
+ })
27
+ });
28
+ function Y(e, t) {
29
+ }
30
+ function S(e, t) {
31
+ d.length = 0;
32
+ for (const o of e.query([f(p.relation, t)]))
33
+ d.push(o);
34
+ return d.sort(L), d;
35
+ }
36
+ function g(e, t) {
37
+ const o = S(e, t);
38
+ let i = 0;
39
+ for (const s of o)
40
+ e.hasComponent(s, E) ? i += E.duration[s] ?? 0 : e.hasComponent(s, n) && (n.delay[s] = i);
41
+ }
42
+ function I(e, t) {
43
+ for (const o of e.query([r])) {
44
+ if (r.state[o] !== u.PLAYING) continue;
45
+ const i = r.elapsed[o] ?? 0, s = i + t;
46
+ r.elapsed[o] = s;
47
+ for (const c of e.query([f(p.relation, o), n])) {
48
+ if (n.state[c] !== a.IDLE) continue;
49
+ const m = n.delay[c] ?? 0, q = s >= m, y = i >= m;
50
+ q && (C(e, c), n.state[c] = a.PLAYING, n.elapsed[c] = y ? 0 : s - m - t);
51
+ }
52
+ }
53
+ }
54
+ function O(e, t) {
55
+ l.length = 0;
56
+ for (const o of e.query([f(p.relation, t), n])) {
57
+ if (n.state[o] === a.COMPLETE && n.elapsed[o] >= n.duration[o])
58
+ continue;
59
+ const i = n.delay[o] ?? 0, s = n.duration[o] ?? 0;
60
+ l.push({ eid: o, endTime: i + s });
61
+ }
62
+ l.sort(P);
63
+ for (const { eid: o } of l)
64
+ n.state[o] = a.COMPLETE, T(e, o);
65
+ }
66
+ function B(e) {
67
+ for (const t of e.query([r]))
68
+ r.state[t] === u.COMPLETE && O(e, t);
69
+ }
70
+ function R(e) {
71
+ for (const t of e.query([r])) {
72
+ if (r.state[t] !== u.PLAYING) continue;
73
+ let o = !0, i = !1;
74
+ for (const s of e.query([f(p.relation, t), n]))
75
+ if (i = !0, n.state[s] !== a.COMPLETE) {
76
+ o = !1;
77
+ break;
78
+ }
79
+ i && o && (r.state[t] = u.COMPLETE);
80
+ }
81
+ }
82
+ function b(e, t) {
83
+ I(e, t);
84
+ }
85
+ export {
86
+ E as Pause,
87
+ r as Sequence,
88
+ u as SequenceState,
89
+ R as checkSequenceCompletion,
90
+ g as computeTweenDelays,
91
+ B as ensureSequencesResolved,
92
+ Y as finalizeSequences,
93
+ b as updateSequences
94
+ };
95
+ //# sourceMappingURL=sequence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence.js","sources":["../../../src/standard/tween/sequence.ts"],"sourcesContent":["import { Pair } from \"bitecs\";\nimport { setTraits } from \"../../core/component\";\nimport { ChildOf, type State, type ParseContext } from \"../../core\";\nimport { Tween, TweenState, ensureResolved, captureFromValue } from \"./tween\";\n\nconst compareNumbers = (a: number, b: number) => a - b;\nconst compareByEndTime = (a: { endTime: number }, b: { endTime: number }) => a.endTime - b.endTime;\n\nconst childrenBuffer: number[] = [];\nconst tweensBuffer: { eid: number; endTime: number }[] = [];\n\nexport const Pause = {\n duration: [] as number[],\n};\n\nsetTraits(Pause, {\n defaults: () => ({ duration: 0.5 }),\n});\n\nexport const SequenceState = {\n IDLE: 0,\n PLAYING: 1,\n COMPLETE: 2,\n} as const;\n\nexport const Sequence = {\n state: [] as number[],\n elapsed: [] as number[],\n};\n\nsetTraits(Sequence, {\n defaults: () => ({\n state: SequenceState.IDLE,\n elapsed: 0,\n }),\n});\n\nexport function finalizeSequences(_state: State, _context: ParseContext): void {}\n\nfunction getChildrenSorted(state: State, parentEid: number): number[] {\n childrenBuffer.length = 0;\n for (const childEid of state.query([Pair(ChildOf.relation, parentEid)])) {\n childrenBuffer.push(childEid);\n }\n childrenBuffer.sort(compareNumbers);\n return childrenBuffer;\n}\n\nexport function computeTweenDelays(state: State, seqEid: number): void {\n const children = getChildrenSorted(state, seqEid);\n let cumulativeDelay = 0;\n\n for (const childEid of children) {\n if (state.hasComponent(childEid, Pause)) {\n cumulativeDelay += Pause.duration[childEid] ?? 0;\n } else if (state.hasComponent(childEid, Tween)) {\n Tween.delay[childEid] = cumulativeDelay;\n }\n }\n}\n\nfunction updateSequencePlayheads(state: State, dt: number): void {\n for (const seqEid of state.query([Sequence])) {\n if (Sequence.state[seqEid] !== SequenceState.PLAYING) continue;\n\n const prevElapsed = Sequence.elapsed[seqEid] ?? 0;\n const elapsed = prevElapsed + dt;\n Sequence.elapsed[seqEid] = elapsed;\n\n for (const childEid of state.query([Pair(ChildOf.relation, seqEid), Tween])) {\n if (Tween.state[childEid] !== TweenState.IDLE) continue;\n\n const delay = Tween.delay[childEid] ?? 0;\n const shouldStart = elapsed >= delay;\n const wasStarted = prevElapsed >= delay;\n\n if (shouldStart) {\n captureFromValue(state, childEid);\n Tween.state[childEid] = TweenState.PLAYING;\n Tween.elapsed[childEid] = wasStarted ? 0 : elapsed - delay - dt;\n }\n }\n }\n}\n\nfunction ensureSequenceResolved(state: State, seqEid: number): void {\n tweensBuffer.length = 0;\n\n for (const childEid of state.query([Pair(ChildOf.relation, seqEid), Tween])) {\n if (\n Tween.state[childEid] === TweenState.COMPLETE &&\n Tween.elapsed[childEid] >= Tween.duration[childEid]\n ) {\n continue;\n }\n const delay = Tween.delay[childEid] ?? 0;\n const duration = Tween.duration[childEid] ?? 0;\n tweensBuffer.push({ eid: childEid, endTime: delay + duration });\n }\n\n tweensBuffer.sort(compareByEndTime);\n\n for (const { eid } of tweensBuffer) {\n Tween.state[eid] = TweenState.COMPLETE;\n ensureResolved(state, eid);\n }\n}\n\nfunction ensureSequencesResolved(state: State): void {\n for (const seqEid of state.query([Sequence])) {\n if (Sequence.state[seqEid] === SequenceState.COMPLETE) {\n ensureSequenceResolved(state, seqEid);\n }\n }\n}\n\nfunction checkSequenceCompletion(state: State): void {\n for (const seqEid of state.query([Sequence])) {\n if (Sequence.state[seqEid] !== SequenceState.PLAYING) continue;\n\n let allComplete = true;\n let hasChildren = false;\n\n for (const childEid of state.query([Pair(ChildOf.relation, seqEid), Tween])) {\n hasChildren = true;\n if (Tween.state[childEid] !== TweenState.COMPLETE) {\n allComplete = false;\n break;\n }\n }\n\n if (hasChildren && allComplete) {\n Sequence.state[seqEid] = SequenceState.COMPLETE;\n }\n }\n}\n\nexport function updateSequences(state: State, dt: number): void {\n updateSequencePlayheads(state, dt);\n}\n\nexport { ensureSequencesResolved, checkSequenceCompletion };\n"],"names":["compareNumbers","a","b","compareByEndTime","childrenBuffer","tweensBuffer","Pause","setTraits","SequenceState","Sequence","finalizeSequences","_state","_context","getChildrenSorted","state","parentEid","childEid","Pair","ChildOf","computeTweenDelays","seqEid","children","cumulativeDelay","Tween","updateSequencePlayheads","dt","prevElapsed","elapsed","TweenState","delay","shouldStart","wasStarted","captureFromValue","ensureSequenceResolved","duration","eid","ensureResolved","ensureSequencesResolved","checkSequenceCompletion","allComplete","hasChildren","updateSequences"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { State, System, ParseContext, Plugin } from '../../core';
2
+ export declare const TweenState: {
3
+ readonly IDLE: 0;
4
+ readonly PLAYING: 1;
5
+ readonly COMPLETE: 2;
6
+ };
7
+ export declare const Tween: {
8
+ state: number[];
9
+ from: number[];
10
+ to: number[];
11
+ duration: number[];
12
+ elapsed: number[];
13
+ delay: number[];
14
+ easingIndex: number[];
15
+ };
16
+ export declare const TweenTarget: import('../..').RelationDef;
17
+ export declare function finalizePendingTweens(state: State, context: ParseContext): void;
18
+ export declare function captureFromValue(state: State, tweenEid: number): void;
19
+ export declare function ensureResolved(state: State, tweenEid: number): void;
20
+ export interface TweenOptions {
21
+ readonly to: number;
22
+ readonly duration?: number;
23
+ readonly easing?: string;
24
+ }
25
+ export declare function createTween(state: State, targetEid: number, fieldPath: string, options: TweenOptions): number | null;
26
+ export declare const TweenSystem: System;
27
+ export declare const TweenPlugin: Plugin;
28
+ //# sourceMappingURL=tween.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tween.d.ts","sourceRoot":"","sources":["../../../src/standard/tween/tween.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,KAAK,EACV,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,MAAM,EACd,MAAM,YAAY,CAAC;AA0BpB,eAAO,MAAM,UAAU;;;;CAIb,CAAC;AAEX,eAAO,MAAM,KAAK;WACD,MAAM,EAAE;UACT,MAAM,EAAE;QACV,MAAM,EAAE;cACF,MAAM,EAAE;aACT,MAAM,EAAE;WACV,MAAM,EAAE;iBACF,MAAM,EAAE;CAC9B,CAAC;AA4BF,eAAO,MAAM,WAAW,6BAEtB,CAAC;AAgDH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAgB/E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAOrE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAenE;AA2CD,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,WAAW,CACvB,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,GACtB,MAAM,GAAG,IAAI,CAqBf;AAED,eAAO,MAAM,WAAW,EAAE,MAWzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAOzB,CAAC"}
@@ -0,0 +1,136 @@
1
+ import "bitecs";
2
+ import { setTraits as y } from "../../core/component.js";
3
+ import "../../core/builder.js";
4
+ import { defineRelation as E } from "../../core/relation.js";
5
+ import "../../core/math.js";
6
+ import { registerPostLoadHook as P } from "../../core/xml.js";
7
+ import { getEasingIndex as g, getEasing as x } from "./easing.js";
8
+ import { Pause as I, Sequence as w, ensureSequencesResolved as b, updateSequences as v, checkSequenceCompletion as A } from "./sequence.js";
9
+ function L(n) {
10
+ if (n._value) {
11
+ const o = {};
12
+ for (const e of n._value.split(";")) {
13
+ const t = e.indexOf(":");
14
+ if (t === -1) continue;
15
+ const i = e.slice(0, t).trim(), s = e.slice(t + 1).trim();
16
+ i && s && (o[i] = s);
17
+ }
18
+ return o;
19
+ }
20
+ return n;
21
+ }
22
+ const c = {
23
+ IDLE: 0,
24
+ PLAYING: 1,
25
+ COMPLETE: 2
26
+ }, r = {
27
+ state: [],
28
+ from: [],
29
+ to: [],
30
+ duration: [],
31
+ elapsed: [],
32
+ delay: [],
33
+ easingIndex: []
34
+ };
35
+ y(r, {
36
+ defaults: () => ({
37
+ state: c.IDLE,
38
+ from: 0,
39
+ to: 0,
40
+ duration: 1,
41
+ elapsed: 0,
42
+ delay: 0,
43
+ easingIndex: 0
44
+ }),
45
+ adapter: (n, o, e) => {
46
+ const t = L(n), i = {};
47
+ return t.duration && (i.duration = parseFloat(t.duration)), t.delay && (i.delay = parseFloat(t.delay)), t.easing && (i.easingIndex = g(t.easing)), t.target && S(o, e, t, e.currentEid), i;
48
+ }
49
+ });
50
+ const a = E("tween-target", {
51
+ exclusive: !0
52
+ });
53
+ function R(n) {
54
+ if (!n.startsWith("@")) return null;
55
+ const o = n.slice(1), e = o.indexOf(".");
56
+ if (e === -1) return null;
57
+ const t = o.slice(0, e), i = o.slice(e + 1), s = i.lastIndexOf(".");
58
+ return s === -1 ? null : {
59
+ entity: t,
60
+ component: i.slice(0, s),
61
+ field: i.slice(s + 1)
62
+ };
63
+ }
64
+ let d = [];
65
+ function S(n, o, e, t) {
66
+ d.push({
67
+ tweenEid: t,
68
+ target: e.target,
69
+ to: e.to
70
+ });
71
+ }
72
+ function h(n, o) {
73
+ for (const e of d) {
74
+ const t = R(e.target);
75
+ if (!t) continue;
76
+ const i = o.getEntityByName(t.entity);
77
+ i === null || !n.bindFieldAccessor(e.tweenEid, t.component, t.field) || (n.addRelation(e.tweenEid, a, i), r.to[e.tweenEid] = parseFloat(e.to));
78
+ }
79
+ d = [];
80
+ }
81
+ function B(n, o) {
82
+ const e = n.getFirstRelationTarget(o, a), t = n.getFieldAccessor(o);
83
+ t && e >= 0 && (r.from[o] = t.get(e) ?? 0);
84
+ }
85
+ function O(n, o) {
86
+ const e = r.elapsed[o], t = r.duration[o];
87
+ if (e >= t) return;
88
+ const i = n.getFirstRelationTarget(o, a), s = n.getFieldAccessor(o);
89
+ s && i >= 0 && (r.from[o] = s.get(i) ?? 0, s.set(i, r.to[o])), r.elapsed[o] = t;
90
+ }
91
+ function q(n, o) {
92
+ for (const e of n.query([r])) {
93
+ const t = r.state[e];
94
+ if (t === c.COMPLETE) {
95
+ O(n, e);
96
+ continue;
97
+ }
98
+ if (t !== c.PLAYING) continue;
99
+ const i = n.getFirstRelationTarget(e, a), s = n.getFieldAccessor(e);
100
+ r.elapsed[e] === 0 && s && i >= 0 && (r.from[e] = s.get(i) ?? 0), r.elapsed[e] += o;
101
+ const l = r.elapsed[e], p = r.duration[e], u = Math.min(l / p, 1), m = x(r.easingIndex[e])(u), f = r.from[e], T = r.to[e], F = f + (T - f) * m;
102
+ s && i >= 0 && s.set(i, F), u >= 1 && (r.state[e] = c.COMPLETE);
103
+ }
104
+ }
105
+ function H(n, o, e, t) {
106
+ const i = n.resolveFieldPath(e);
107
+ if (!i) return null;
108
+ const s = n.addEntity();
109
+ return n.addComponent(s, r), n.bindFieldAccessor(s, i.component, i.field) ? (n.addRelation(s, a, o), r.to[s] = t.to, r.duration[s] = t.duration ?? 1, r.elapsed[s] = 0, r.easingIndex[s] = g(t.easing ?? "linear"), s) : (n.removeEntity(s), null);
110
+ }
111
+ const C = {
112
+ group: "simulation",
113
+ update(n) {
114
+ const o = n.time.deltaTime;
115
+ b(n), v(n, o), q(n, o), A(n);
116
+ }
117
+ }, V = {
118
+ systems: [C],
119
+ components: { Tween: r, Sequence: w, Pause: I },
120
+ relations: [a],
121
+ initialize() {
122
+ P(h);
123
+ }
124
+ };
125
+ export {
126
+ r as Tween,
127
+ V as TweenPlugin,
128
+ c as TweenState,
129
+ C as TweenSystem,
130
+ a as TweenTarget,
131
+ B as captureFromValue,
132
+ H as createTween,
133
+ O as ensureResolved,
134
+ h as finalizePendingTweens
135
+ };
136
+ //# sourceMappingURL=tween.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tween.js","sources":["../../../src/standard/tween/tween.ts"],"sourcesContent":["import {\n defineRelation,\n registerPostLoadHook,\n type State,\n type System,\n type ParseContext,\n type Plugin,\n} from \"../../core\";\nimport { setTraits } from \"../../core/component\";\nimport { getEasingIndex, getEasing } from \"./easing\";\nimport {\n Sequence,\n Pause,\n updateSequences,\n ensureSequencesResolved,\n checkSequenceCompletion,\n} from \"./sequence\";\n\nfunction parseTweenAttrs(attrs: Record<string, string>): Record<string, string> {\n if (attrs._value) {\n const parsed: Record<string, string> = {};\n for (const part of attrs._value.split(\";\")) {\n const colonIdx = part.indexOf(\":\");\n if (colonIdx === -1) continue;\n const key = part.slice(0, colonIdx).trim();\n const value = part.slice(colonIdx + 1).trim();\n if (key && value) parsed[key] = value;\n }\n return parsed;\n }\n return attrs;\n}\n\nexport const TweenState = {\n IDLE: 0,\n PLAYING: 1,\n COMPLETE: 2,\n} as const;\n\nexport const Tween = {\n state: [] as number[],\n from: [] as number[],\n to: [] as number[],\n duration: [] as number[],\n elapsed: [] as number[],\n delay: [] as number[],\n easingIndex: [] as number[],\n};\n\nsetTraits(Tween, {\n defaults: () => ({\n state: TweenState.IDLE,\n from: 0,\n to: 0,\n duration: 1,\n elapsed: 0,\n delay: 0,\n easingIndex: 0,\n }),\n adapter: (attrs: Record<string, string>, state: State, context: ParseContext) => {\n const parsed = parseTweenAttrs(attrs);\n const result: Record<string, number> = {};\n\n if (parsed.duration) result.duration = parseFloat(parsed.duration);\n if (parsed.delay) result.delay = parseFloat(parsed.delay);\n if (parsed.easing) result.easingIndex = getEasingIndex(parsed.easing);\n\n if (parsed.target) {\n setupTweenFromXml(state, context, parsed, context.currentEid);\n }\n\n return result;\n },\n});\n\nexport const TweenTarget = defineRelation(\"tween-target\", {\n exclusive: true,\n});\n\ninterface ParsedTargetPath {\n readonly entity: string;\n readonly component: string;\n readonly field: string;\n}\n\nfunction parseTargetPath(path: string): ParsedTargetPath | null {\n if (!path.startsWith(\"@\")) return null;\n\n const rest = path.slice(1);\n const firstDot = rest.indexOf(\".\");\n if (firstDot === -1) return null;\n\n const entity = rest.slice(0, firstDot);\n const fieldPath = rest.slice(firstDot + 1);\n const dotIndex = fieldPath.lastIndexOf(\".\");\n if (dotIndex === -1) return null;\n\n return {\n entity,\n component: fieldPath.slice(0, dotIndex),\n field: fieldPath.slice(dotIndex + 1),\n };\n}\n\ninterface PendingTween {\n readonly tweenEid: number;\n readonly target: string;\n readonly to: string;\n}\n\nlet pendingXmlTweens: PendingTween[] = [];\n\nfunction setupTweenFromXml(\n _state: State,\n _context: ParseContext,\n attrs: Record<string, string>,\n tweenEid: number\n): void {\n pendingXmlTweens.push({\n tweenEid,\n target: attrs.target,\n to: attrs.to,\n });\n}\n\nexport function finalizePendingTweens(state: State, context: ParseContext): void {\n for (const pending of pendingXmlTweens) {\n const parsed = parseTargetPath(pending.target);\n if (!parsed) continue;\n\n const targetEid = context.getEntityByName(parsed.entity);\n if (targetEid === null) continue;\n\n const binding = state.bindFieldAccessor(pending.tweenEid, parsed.component, parsed.field);\n if (!binding) continue;\n\n state.addRelation(pending.tweenEid, TweenTarget, targetEid);\n\n Tween.to[pending.tweenEid] = parseFloat(pending.to);\n }\n pendingXmlTweens = [];\n}\n\nexport function captureFromValue(state: State, tweenEid: number): void {\n const targetEid = state.getFirstRelationTarget(tweenEid, TweenTarget);\n const binding = state.getFieldAccessor(tweenEid);\n\n if (binding && targetEid >= 0) {\n Tween.from[tweenEid] = binding.get(targetEid) ?? 0;\n }\n}\n\nexport function ensureResolved(state: State, tweenEid: number): void {\n const elapsed = Tween.elapsed[tweenEid];\n const duration = Tween.duration[tweenEid];\n\n if (elapsed >= duration) return;\n\n const targetEid = state.getFirstRelationTarget(tweenEid, TweenTarget);\n const binding = state.getFieldAccessor(tweenEid);\n\n if (binding && targetEid >= 0) {\n Tween.from[tweenEid] = binding.get(targetEid) ?? 0;\n binding.set(targetEid, Tween.to[tweenEid]);\n }\n\n Tween.elapsed[tweenEid] = duration;\n}\n\nfunction updateTweens(state: State, dt: number): void {\n for (const tweenEid of state.query([Tween])) {\n const tweenState = Tween.state[tweenEid];\n\n if (tweenState === TweenState.COMPLETE) {\n ensureResolved(state, tweenEid);\n continue;\n }\n\n if (tweenState !== TweenState.PLAYING) continue;\n\n const targetEid = state.getFirstRelationTarget(tweenEid, TweenTarget);\n const binding = state.getFieldAccessor(tweenEid);\n\n if (Tween.elapsed[tweenEid] === 0 && binding && targetEid >= 0) {\n Tween.from[tweenEid] = binding.get(targetEid) ?? 0;\n }\n\n Tween.elapsed[tweenEid] += dt;\n\n const elapsed = Tween.elapsed[tweenEid];\n const duration = Tween.duration[tweenEid];\n const rawProgress = Math.min(elapsed / duration, 1);\n\n const easingFn = getEasing(Tween.easingIndex[tweenEid]);\n const easedProgress = easingFn(rawProgress);\n\n const from = Tween.from[tweenEid];\n const to = Tween.to[tweenEid];\n const value = from + (to - from) * easedProgress;\n\n if (binding && targetEid >= 0) {\n binding.set(targetEid, value);\n }\n\n if (rawProgress >= 1) {\n Tween.state[tweenEid] = TweenState.COMPLETE;\n }\n }\n}\n\nexport interface TweenOptions {\n readonly to: number;\n readonly duration?: number;\n readonly easing?: string;\n}\n\nexport function createTween(\n state: State,\n targetEid: number,\n fieldPath: string,\n options: TweenOptions\n): number | null {\n const parsed = state.resolveFieldPath(fieldPath);\n if (!parsed) return null;\n\n const tweenEid = state.addEntity();\n state.addComponent(tweenEid, Tween);\n\n const binding = state.bindFieldAccessor(tweenEid, parsed.component, parsed.field);\n if (!binding) {\n state.removeEntity(tweenEid);\n return null;\n }\n\n state.addRelation(tweenEid, TweenTarget, targetEid);\n\n Tween.to[tweenEid] = options.to;\n Tween.duration[tweenEid] = options.duration ?? 1;\n Tween.elapsed[tweenEid] = 0;\n Tween.easingIndex[tweenEid] = getEasingIndex(options.easing ?? \"linear\");\n\n return tweenEid;\n}\n\nexport const TweenSystem: System = {\n group: \"simulation\",\n\n update(state: State) {\n const dt = state.time.deltaTime;\n\n ensureSequencesResolved(state);\n updateSequences(state, dt);\n updateTweens(state, dt);\n checkSequenceCompletion(state);\n },\n};\n\nexport const TweenPlugin: Plugin = {\n systems: [TweenSystem],\n components: { Tween, Sequence, Pause },\n relations: [TweenTarget],\n initialize() {\n registerPostLoadHook(finalizePendingTweens);\n },\n};\n"],"names":["parseTweenAttrs","attrs","parsed","part","colonIdx","key","value","TweenState","Tween","setTraits","state","context","result","getEasingIndex","setupTweenFromXml","TweenTarget","defineRelation","parseTargetPath","path","rest","firstDot","entity","fieldPath","dotIndex","pendingXmlTweens","_state","_context","tweenEid","finalizePendingTweens","pending","targetEid","captureFromValue","binding","ensureResolved","elapsed","duration","updateTweens","dt","tweenState","rawProgress","easedProgress","getEasing","from","to","createTween","options","TweenSystem","ensureSequencesResolved","updateSequences","checkSequenceCompletion","TweenPlugin","Sequence","Pause","registerPostLoadHook"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@multiplekex/shallot",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "@shallot/source": "./src/index.ts",
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./extras": {
15
+ "@shallot/source": "./src/extras/index.ts",
16
+ "types": "./dist/extras/index.d.ts",
17
+ "default": "./dist/extras/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src"
23
+ ],
24
+ "workspaces": [
25
+ "examples/*"
26
+ ],
27
+ "scripts": {
28
+ "dev": "vite build --watch",
29
+ "build": "bun run build:wasm && vite build",
30
+ "build:wasm": "./rust/transforms/build.sh",
31
+ "check": "tsc",
32
+ "test": "bun test",
33
+ "format": "prettier --write .",
34
+ "format:check": "prettier --check .",
35
+ "prepublishOnly": "bun run build"
36
+ },
37
+ "dependencies": {
38
+ "@mapbox/tiny-sdf": "^2.0.7",
39
+ "bitecs": "^0.4.0",
40
+ "fast-xml-parser": "^5.3.3",
41
+ "wgpu-matrix": "^3.4.0"
42
+ },
43
+ "devDependencies": {
44
+ "@napi-rs/canvas": "^0.1.88",
45
+ "@tauri-apps/plugin-fs": "^2.4.4",
46
+ "@types/bun": "latest",
47
+ "@types/three": "^0.182.0",
48
+ "mitata": "^1.0.34",
49
+ "prettier": "^3.7.4",
50
+ "three": "^0.182.0",
51
+ "troika-three-text": "^0.52.4",
52
+ "vite": "^7.3.0",
53
+ "vite-plugin-dts": "^4.5.4",
54
+ "vite-plugin-wasm": "^3.5.0",
55
+ "webgpu": "^0.3.8"
56
+ },
57
+ "peerDependencies": {
58
+ "typescript": "^5"
59
+ },
60
+ "trustedDependencies": [
61
+ "webgpu"
62
+ ]
63
+ }
@@ -0,0 +1,148 @@
1
+ import { State } from "./state";
2
+ import type { Plugin, Loading } from "./types";
3
+ import { toposort, type System } from "./scheduler";
4
+ import { registerComponent } from "./component";
5
+
6
+ export class StateBuilder {
7
+ static defaultPlugins: readonly Plugin[] = [];
8
+ static loading: ((canvas: HTMLCanvasElement) => Loading) | null = null;
9
+
10
+ private readonly _plugins: Plugin[] = [];
11
+ private readonly _systems: System[] = [];
12
+ private readonly _scenes: string[] = [];
13
+ private readonly _excludedPlugins = new Set<Plugin>();
14
+ private _useDefaultPlugins = true;
15
+ private _canvas: HTMLCanvasElement | null = null;
16
+ private _loading: Loading | null | undefined = undefined;
17
+
18
+ withCanvas(canvas: HTMLCanvasElement): this {
19
+ this._canvas = canvas;
20
+ return this;
21
+ }
22
+
23
+ withPlugins(...plugins: Plugin[]): this {
24
+ this._plugins.push(...plugins);
25
+ return this;
26
+ }
27
+
28
+ withoutPlugin(plugin: Plugin): this {
29
+ this._excludedPlugins.add(plugin);
30
+ return this;
31
+ }
32
+
33
+ withoutPlugins(...plugins: Plugin[]): this {
34
+ for (const p of plugins) this._excludedPlugins.add(p);
35
+ return this;
36
+ }
37
+
38
+ withoutDefaultPlugins(): this {
39
+ this._useDefaultPlugins = false;
40
+ return this;
41
+ }
42
+
43
+ withSystems(...systems: System[]): this {
44
+ this._systems.push(...systems);
45
+ return this;
46
+ }
47
+
48
+ withScene(path: string): this {
49
+ this._scenes.push(path);
50
+ return this;
51
+ }
52
+
53
+ withLoading(loading: Loading | null): this {
54
+ this._loading = loading;
55
+ return this;
56
+ }
57
+
58
+ async build(): Promise<State> {
59
+ const loading =
60
+ this._loading === undefined && this._canvas
61
+ ? (StateBuilder.loading?.(this._canvas) ?? null)
62
+ : this._loading;
63
+
64
+ const cleanup = loading?.show();
65
+
66
+ const state = new State(this._canvas);
67
+
68
+ const pluginSet = new Set<Plugin>();
69
+
70
+ if (this._useDefaultPlugins) {
71
+ for (const plugin of StateBuilder.defaultPlugins) {
72
+ if (!this._excludedPlugins.has(plugin)) {
73
+ pluginSet.add(plugin);
74
+ }
75
+ }
76
+ }
77
+
78
+ for (const plugin of this._plugins) {
79
+ pluginSet.add(plugin);
80
+ }
81
+
82
+ const allPlugins = [...pluginSet];
83
+
84
+ for (const plugin of allPlugins) {
85
+ if (plugin.components) {
86
+ for (const [name, component] of Object.entries(plugin.components)) {
87
+ registerComponent(name, component);
88
+ }
89
+ }
90
+ if (plugin.systems) {
91
+ for (const system of plugin.systems) {
92
+ state.scheduler.register(system);
93
+ }
94
+ }
95
+ }
96
+
97
+ const edges: [Plugin, Plugin][] = [];
98
+ for (const plugin of allPlugins) {
99
+ for (const dep of plugin.dependencies ?? []) {
100
+ if (allPlugins.includes(dep)) {
101
+ edges.push([dep, plugin]);
102
+ }
103
+ }
104
+ }
105
+ const sorted = toposort(allPlugins, edges);
106
+
107
+ let completed = 0;
108
+ const total = sorted.length;
109
+
110
+ for (const plugin of sorted) {
111
+ await plugin.initialize?.(state);
112
+ completed++;
113
+ loading?.update(completed / total);
114
+ }
115
+
116
+ for (const system of this._systems) {
117
+ state.scheduler.register(system);
118
+ }
119
+
120
+ if (this._scenes.length > 0) {
121
+ const { initRuntime } = await import("./runtime");
122
+ const { loadSceneFile } = await import("./xml");
123
+ const runtime = await initRuntime();
124
+ for (const scenePath of this._scenes) {
125
+ const result = await loadSceneFile(
126
+ state,
127
+ scenePath,
128
+ runtime.readFile.bind(runtime)
129
+ );
130
+ if (result.errors.length > 0) {
131
+ console.warn(`Scene "${scenePath}" loaded with errors:`, result.errors);
132
+ }
133
+ }
134
+ }
135
+
136
+ cleanup?.();
137
+
138
+ return state;
139
+ }
140
+
141
+ async run(): Promise<State> {
142
+ const state = await this.build();
143
+ await state.start();
144
+ return state;
145
+ }
146
+ }
147
+
148
+ State.Builder = StateBuilder;
@@ -0,0 +1,71 @@
1
+ import type { State } from "./state";
2
+ import { toKebabCase } from "./strings";
3
+
4
+ export type ComponentArray = number[] | Float32Array | Uint32Array;
5
+ export type ComponentData = Record<string, ComponentArray>;
6
+
7
+ export interface ParseContext {
8
+ readonly currentEid: number;
9
+ getEntityByName(name: string): number | null;
10
+ setName(name: string, eid: number): void;
11
+ }
12
+
13
+ export interface FieldAccessor {
14
+ get(eid: number): number;
15
+ set(eid: number, value: number): void;
16
+ }
17
+
18
+ export interface ComponentTraits {
19
+ defaults?: () => Record<string, number>;
20
+ adapter?: (
21
+ attrs: Record<string, string>,
22
+ state: State,
23
+ context: ParseContext
24
+ ) => Record<string, number>;
25
+ accessors?: Record<string, FieldAccessor>;
26
+ }
27
+
28
+ const traitsMap = new WeakMap<ComponentData, ComponentTraits>();
29
+
30
+ export function setTraits(component: ComponentData, traits: ComponentTraits): void {
31
+ traitsMap.set(component, traits);
32
+ }
33
+
34
+ export function getTraits(component: ComponentData): ComponentTraits | undefined {
35
+ return traitsMap.get(component);
36
+ }
37
+
38
+ export interface RegisteredComponent {
39
+ readonly component: ComponentData;
40
+ readonly name: string;
41
+ readonly traits?: ComponentTraits;
42
+ }
43
+
44
+ const registry = new Map<string, RegisteredComponent>();
45
+
46
+ export function registerComponent(name: string, component: ComponentData): void {
47
+ const kebabName = toKebabCase(name);
48
+ const traits = traitsMap.get(component);
49
+ registry.set(kebabName, { component, name: kebabName, traits });
50
+ }
51
+
52
+ export function getRegisteredComponent(name: string): RegisteredComponent | undefined {
53
+ return registry.get(toKebabCase(name));
54
+ }
55
+
56
+ export function clearRegistry(): void {
57
+ registry.clear();
58
+ }
59
+
60
+ export function directAccessor(
61
+ data: ComponentArray,
62
+ stride: number,
63
+ offset: number
64
+ ): FieldAccessor {
65
+ return {
66
+ get: (eid) => data[eid * stride + offset],
67
+ set: (eid, v) => {
68
+ data[eid * stride + offset] = v;
69
+ },
70
+ };
71
+ }