@carbonenginejs/runtime-utils 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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +23 -0
  3. package/README.md +56 -0
  4. package/THIRD-PARTY-NOTICES.md +38 -0
  5. package/docs/README.md +81 -0
  6. package/docs/architecture.md +101 -0
  7. package/docs/concepts/foundation-consolidation.md +86 -0
  8. package/docs/const-kb.md +92 -0
  9. package/docs/core-types/DECORATOR-TODOS.md +25 -0
  10. package/docs/core-types/README.md +203 -0
  11. package/docs/reference/api.md +70 -0
  12. package/docs/reference/classes/README.md +115 -0
  13. package/package.json +132 -0
  14. package/src/arrays.js +5 -0
  15. package/src/audio/audioFormats.js +34 -0
  16. package/src/audio/index.js +1 -0
  17. package/src/box3.js +1385 -0
  18. package/src/bytes.js +56 -0
  19. package/src/compression.js +56 -0
  20. package/src/constants/index.js +6 -0
  21. package/src/constants.js +15 -0
  22. package/src/curve.js +419 -0
  23. package/src/d3d/dxgiFormats.js +46 -0
  24. package/src/d3d/index.js +2 -0
  25. package/src/d3d/primitiveTopology.js +11 -0
  26. package/src/document/CjsCarbonDocument.js +212 -0
  27. package/src/document/CjsClassRegistry.js +373 -0
  28. package/src/document/CjsDocumentDehydrator.js +142 -0
  29. package/src/document/CjsDocumentHydrator.js +156 -0
  30. package/src/document/CjsStructRegistry.js +348 -0
  31. package/src/document/hydrationAdapter.js +129 -0
  32. package/src/document/index.js +6 -0
  33. package/src/geometry/box.js +137 -0
  34. package/src/geometry/cylinder.js +244 -0
  35. package/src/geometry/helpers/LICENSE +15 -0
  36. package/src/geometry/helpers/earcut.js +766 -0
  37. package/src/geometry/helpers/misc.js +103 -0
  38. package/src/geometry/index.js +8 -0
  39. package/src/geometry/json.js +165 -0
  40. package/src/geometry/lathe.js +172 -0
  41. package/src/geometry/octahedron.js +0 -0
  42. package/src/geometry/plane.js +81 -0
  43. package/src/geometry/shape.js +95 -0
  44. package/src/geometry/sphere.js +123 -0
  45. package/src/geometry/torus.js +96 -0
  46. package/src/graphics/colorSpaces.js +22 -0
  47. package/src/graphics/index.js +4 -0
  48. package/src/graphics/pixelFormats.js +158 -0
  49. package/src/graphics/textureDimensions.js +22 -0
  50. package/src/graphics/trinityEnums.js +87 -0
  51. package/src/index.js +58 -0
  52. package/src/is.js +524 -0
  53. package/src/json.js +23 -0
  54. package/src/lifecycle/CjsLifecycleState.js +77 -0
  55. package/src/lifecycle/index.js +1 -0
  56. package/src/lne3.js +497 -0
  57. package/src/lookup.js +48 -0
  58. package/src/mat3.js +131 -0
  59. package/src/mat4.js +699 -0
  60. package/src/math/index.js +25 -0
  61. package/src/math/scalar.js +63 -0
  62. package/src/media/index.js +1 -0
  63. package/src/media/mediaTypes.js +50 -0
  64. package/src/mesh.js +394 -0
  65. package/src/model/CjsEventEmitter.js +333 -0
  66. package/src/model/CjsModel.js +1544 -0
  67. package/src/model/CjsModelState.js +72 -0
  68. package/src/model/index.js +4 -0
  69. package/src/model/sourceRecordUtils.js +54 -0
  70. package/src/noise.js +310 -0
  71. package/src/num.js +827 -0
  72. package/src/path.js +21 -0
  73. package/src/pln.js +762 -0
  74. package/src/pool.js +160 -0
  75. package/src/quat.js +144 -0
  76. package/src/ray3.js +1085 -0
  77. package/src/renderContext/formats.js +145 -0
  78. package/src/renderContext/index.js +5 -0
  79. package/src/renderContext/presentation.js +125 -0
  80. package/src/renderContext/resources.js +27 -0
  81. package/src/renderContext/upscaling.js +22 -0
  82. package/src/renderContext/window.js +20 -0
  83. package/src/runtime/CjsRuntimeState.js +50 -0
  84. package/src/schema/CjsSchema.js +1009 -0
  85. package/src/schema/index.js +17 -0
  86. package/src/shader/index.js +1 -0
  87. package/src/shader/shaderStages.js +37 -0
  88. package/src/sph3.js +754 -0
  89. package/src/tangent.js +288 -0
  90. package/src/text.js +40 -0
  91. package/src/tri3.js +650 -0
  92. package/src/types/carbonTypes.js +635 -0
  93. package/src/types/index.js +2 -0
  94. package/src/utils.js +58 -0
  95. package/src/validation.js +46 -0
  96. package/src/vec2.js +229 -0
  97. package/src/vec3.js +1172 -0
  98. package/src/vec4.js +347 -0
  99. package/src/vertex.js +108 -0
  100. package/src/webgpu/index.js +1 -0
  101. package/src/webgpu/textureFormats.js +121 -0
@@ -0,0 +1,333 @@
1
+ import { ensureRuntimeState, getRuntimeState } from "../runtime/CjsRuntimeState.js";
2
+
3
+ const ANY_SOURCE = Symbol("CjsEventEmitter.AnySource");
4
+
5
+ /**
6
+ * Minimal event emitter with lowercase exact-name dispatch.
7
+ *
8
+ * Event storage is allocated lazily and remains owned by the emitter.
9
+ */
10
+ export class CjsEventEmitter
11
+ {
12
+ /**
13
+ * Adds event listeners from a plain object.
14
+ *
15
+ * A key ending in ".once" registers a once-only listener. Values may be a
16
+ * function or [function, source].
17
+ *
18
+ * @param {object|null} events
19
+ * @returns {CjsEventEmitter}
20
+ */
21
+ AddEvents(events = null)
22
+ {
23
+ if (!events || typeof events !== "object") return this;
24
+
25
+ for (const key of Object.keys(events))
26
+ {
27
+ const entry = NormalizeEventEntry(key, events[key]);
28
+ this.OnEvent(entry.eventName, entry.listener, entry.source, entry.once);
29
+ }
30
+
31
+ return this;
32
+ }
33
+
34
+ /**
35
+ * Adds a listener for a lowercased exact event name.
36
+ *
37
+ * @param {string} eventName
38
+ * @param {Function} listener
39
+ * @param {*} source Optional callback source and `this` value.
40
+ * @param {boolean} once
41
+ * @returns {CjsEventEmitter}
42
+ */
43
+ OnEvent(eventName, listener, source = null, once = false)
44
+ {
45
+ CreateEventRecord(this, eventName, listener, source, once);
46
+ return this;
47
+ }
48
+
49
+ /**
50
+ * Adds a listener that is removed before its first callback is invoked.
51
+ *
52
+ * @param {string} eventName
53
+ * @param {Function} listener
54
+ * @param {*} source Optional callback source and `this` value.
55
+ * @returns {CjsEventEmitter}
56
+ */
57
+ OnceEvent(eventName, listener, source = null)
58
+ {
59
+ return this.OnEvent(eventName, listener, source, true);
60
+ }
61
+
62
+ /**
63
+ * Removes matching listeners from this emitter.
64
+ *
65
+ * `eventName="*"` means all event buckets. It is cleanup matching only, not
66
+ * wildcard dispatch.
67
+ *
68
+ * @param {string} eventName
69
+ * @param {?Function} listener
70
+ * @param {*} source Optional callback source to match.
71
+ * @returns {CjsEventEmitter}
72
+ */
73
+ OffEvent(eventName = "*", listener = null, source = ANY_SOURCE)
74
+ {
75
+ for (const record of FindEventRecords(this, eventName, listener, source))
76
+ {
77
+ RemoveEventRecord(record);
78
+ }
79
+
80
+ return this;
81
+ }
82
+
83
+ /**
84
+ * Emits a lowercased exact event name to all currently registered records.
85
+ *
86
+ * @param {string} eventName
87
+ * @param {...*} args
88
+ * @returns {CjsEventEmitter}
89
+ */
90
+ EmitEvent(eventName, ...args)
91
+ {
92
+ if ((getRuntimeState(this)?.suppressEvents ?? 0) > 0) return this;
93
+ const events = GetEventMap(this);
94
+ if (!events) return this;
95
+
96
+ const name = NormalizeEventName(eventName);
97
+ const records = events.get(name);
98
+ if (!records) return this;
99
+
100
+ let error = null;
101
+
102
+ try
103
+ {
104
+ for (const record of [...records])
105
+ {
106
+ if (!records.has(record)) continue;
107
+ if (record.once) RemoveEventRecord(record);
108
+ record.listener.call(record.source, ...args);
109
+ }
110
+ }
111
+ catch (err)
112
+ {
113
+ error = err;
114
+ }
115
+
116
+ if (error) throw error;
117
+ return this;
118
+ }
119
+
120
+ /**
121
+ * Checks whether this emitter has a matching listener record.
122
+ *
123
+ * @param {string} eventName
124
+ * @param {?Function} listener
125
+ * @param {*} source Optional callback source to match.
126
+ * @returns {boolean}
127
+ */
128
+ HasEvent(eventName = "*", listener = null, source = ANY_SOURCE)
129
+ {
130
+ return FindEventRecords(this, eventName, listener, source).length > 0;
131
+ }
132
+
133
+ /**
134
+ * Clears an event bucket or all event buckets from this emitter.
135
+ *
136
+ * @param {string} eventName
137
+ * @returns {CjsEventEmitter}
138
+ */
139
+ ClearEvent(eventName = "*")
140
+ {
141
+ return this.OffEvent(eventName);
142
+ }
143
+
144
+ /**
145
+ * Gets the lowercased exact event names with active listener buckets.
146
+ *
147
+ * @returns {Array<string>}
148
+ */
149
+ GetEventNames()
150
+ {
151
+ const events = GetEventMap(this);
152
+ return events ? [...events.keys()] : [];
153
+ }
154
+
155
+ /**
156
+ * Gets the number of active listener records for an event or all events.
157
+ *
158
+ * @param {string} eventName
159
+ * @returns {number}
160
+ */
161
+ GetEventListenerCount(eventName = "*")
162
+ {
163
+ return FindEventRecords(this, eventName).length;
164
+ }
165
+
166
+ }
167
+
168
+ /**
169
+ * Creates and indexes a listener record.
170
+ *
171
+ * @param {CjsEventEmitter} emitter
172
+ * @param {string} eventName
173
+ * @param {Function} listener
174
+ * @param {*} source
175
+ * @param {boolean} once
176
+ * @returns {object}
177
+ * @private
178
+ */
179
+ function CreateEventRecord(emitter, eventName, listener, source, once)
180
+ {
181
+ const name = NormalizeEventName(eventName);
182
+ if (typeof listener !== "function")
183
+ {
184
+ throw new TypeError("CjsEventEmitter.OnEvent requires a listener function.");
185
+ }
186
+
187
+ const record = {
188
+ emitter,
189
+ eventName: name,
190
+ listener,
191
+ source,
192
+ once: !!once
193
+ };
194
+
195
+ const events = GetEventMap(emitter, true);
196
+
197
+ let records = events.get(name);
198
+ if (!records)
199
+ {
200
+ records = new Set();
201
+ events.set(name, records);
202
+ }
203
+
204
+ records.add(record);
205
+
206
+ return record;
207
+ }
208
+
209
+ /**
210
+ * Removes a listener record from its emitter index.
211
+ *
212
+ * @param {object} record
213
+ * @returns {void}
214
+ * @private
215
+ */
216
+ function RemoveEventRecord(record)
217
+ {
218
+ const events = GetEventMap(record.emitter);
219
+ const records = events?.get(record.eventName);
220
+
221
+ if (records)
222
+ {
223
+ records.delete(record);
224
+ if (!records.size) events.delete(record.eventName);
225
+ if (!events.size) delete getRuntimeState(record.emitter).events;
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Normalizes exact event names to lowercase.
231
+ *
232
+ * @param {*} eventName
233
+ * @returns {string}
234
+ * @private
235
+ */
236
+ function NormalizeEventName(eventName)
237
+ {
238
+ const name = String(eventName || "").trim().toLowerCase();
239
+ if (!name) throw new TypeError("CjsEventEmitter requires an event name.");
240
+ return name;
241
+ }
242
+
243
+ /**
244
+ * Finds listener records indexed on an emitter.
245
+ *
246
+ * @param {CjsEventEmitter} emitter
247
+ * @param {string} eventName
248
+ * @param {?Function} listener
249
+ * @param {*} source
250
+ * @returns {Array<object>}
251
+ */
252
+ function FindEventRecords(emitter, eventName = "*", listener = null, source = ANY_SOURCE)
253
+ {
254
+ const events = GetEventMap(emitter);
255
+ if (!events) return [];
256
+
257
+ const names = eventName === "*" ? [...events.keys()] : [NormalizeEventName(eventName)];
258
+ const result = [];
259
+
260
+ for (const name of names)
261
+ {
262
+ const records = events.get(name);
263
+ if (!records) continue;
264
+
265
+ for (const record of records)
266
+ {
267
+ if (listener && record.listener !== listener) continue;
268
+ if (source !== ANY_SOURCE && record.source !== source) continue;
269
+ result.push(record);
270
+ }
271
+ }
272
+
273
+ return result;
274
+ }
275
+
276
+ /**
277
+ * Normalizes an AddEvents() object entry.
278
+ *
279
+ * @param {string} key
280
+ * @param {*} value
281
+ * @returns {{eventName: string, listener: Function, source: *, once: boolean}}
282
+ */
283
+ function NormalizeEventEntry(key, value)
284
+ {
285
+ let eventName = String(key);
286
+ let once = false;
287
+ let listener = value;
288
+ let source = null;
289
+
290
+ if (eventName.endsWith(".once"))
291
+ {
292
+ eventName = eventName.slice(0, -5);
293
+ once = true;
294
+ }
295
+
296
+ if (Array.isArray(value))
297
+ {
298
+ [listener, source = null] = value;
299
+ }
300
+
301
+ if (typeof listener !== "function")
302
+ {
303
+ throw new TypeError("CjsEventEmitter.AddEvents requires listener functions.");
304
+ }
305
+
306
+ return { eventName, listener, source, once };
307
+ }
308
+
309
+ /**
310
+ * Gets or lazily creates an emitter's event map.
311
+ *
312
+ * @param {CjsEventEmitter} emitter
313
+ * @param {boolean} create
314
+ * @returns {Map<string, Set<object>>|null}
315
+ * @private
316
+ */
317
+ function GetEventMap(emitter, create = false)
318
+ {
319
+ const state = create ? ensureRuntimeState(emitter) : getRuntimeState(emitter);
320
+ if (!state) return null;
321
+
322
+ if (state.events === undefined)
323
+ {
324
+ if (!create) return null;
325
+ state.events = new Map();
326
+ }
327
+ else if (!(state.events instanceof Map))
328
+ {
329
+ throw new TypeError("CjsEventEmitter requires __state.events to be a Map.");
330
+ }
331
+
332
+ return state.events;
333
+ }