@daneren2005/shared-memory-ecs 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,18 +1,17 @@
1
- import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./create-component-worker-vbX3vEia.js";
2
- import s from "@daneren2005/shared-memory-objects/memory-heap";
3
- import { MAX_BYTE_OFFSET_LENGTH as c } from "@daneren2005/shared-memory-objects/utils/pointer";
4
- import l from "@daneren2005/shared-memory-objects/local-pool";
1
+ import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, r as c, s as l, t as u, u as d } from "./create-component-worker-BM942gjg.js";
2
+ import f from "@daneren2005/shared-memory-objects/memory-heap";
3
+ import { MAX_BYTE_OFFSET_LENGTH as p } from "@daneren2005/shared-memory-objects/utils/pointer";
5
4
  //#region \0rolldown/runtime.js
6
- var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescriptor, p = Object.getOwnPropertyNames, m = Object.getPrototypeOf, h = Object.prototype.hasOwnProperty, g = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t.exports), _ = (e, t, n, r) => {
7
- if (t && typeof t == "object" || typeof t == "function") for (var i = p(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !h.call(e, s) && s !== n && d(e, s, {
5
+ var m = Object.create, h = Object.defineProperty, g = Object.getOwnPropertyDescriptor, _ = Object.getOwnPropertyNames, v = Object.getPrototypeOf, y = Object.prototype.hasOwnProperty, b = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t.exports), x = (e, t, n, r) => {
6
+ if (t && typeof t == "object" || typeof t == "function") for (var i = _(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !y.call(e, s) && s !== n && h(e, s, {
8
7
  get: ((e) => t[e]).bind(null, s),
9
- enumerable: !(r = f(t, s)) || r.enumerable
8
+ enumerable: !(r = g(t, s)) || r.enumerable
10
9
  });
11
10
  return e;
12
- }, v = /* @__PURE__ */ ((e, t, n) => (n = e == null ? {} : u(m(e)), _(t || !e || !e.__esModule ? d(n, "default", {
11
+ }, S = /* @__PURE__ */ ((e, t, n) => (n = e == null ? {} : m(v(e)), x(t || !e || !e.__esModule ? h(n, "default", {
13
12
  value: e,
14
13
  enumerable: !0
15
- }) : n, e)))((/* @__PURE__ */ g(((e, t) => {
14
+ }) : n, e)))((/* @__PURE__ */ b(((e, t) => {
16
15
  var n = Object.prototype.hasOwnProperty, r = "~";
17
16
  function i() {}
18
17
  Object.create && (i.prototype = Object.create(null), new i().__proto__ || (r = !1));
@@ -99,41 +98,76 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
99
98
  var t;
100
99
  return e ? (t = r ? r + e : e, this._events[t] && s(this, t)) : (this._events = new i(), this._eventsCount = 0), this;
101
100
  }, c.prototype.off = c.prototype.removeListener, c.prototype.addListener = c.prototype.on, c.prefixed = r, c.EventEmitter = c, t !== void 0 && (t.exports = c);
102
- })))(), 1), y = class {
103
- heap;
104
- pool;
101
+ })))(), 1), C = class extends S.default {
102
+ eid;
103
+ config;
104
+ world;
105
+ components = {};
105
106
  constructor(e, t, n) {
106
- this.heap = e, this.pool = new l(e, {
107
- type: t,
108
- dataLength: n
109
- });
107
+ super(), this.world = e, this.eid = n ?? e.allocateEid(), n === void 0 && (this.loadComponent("entity", t ?? {}, !1), t && this.load(t));
110
108
  }
111
- get length() {
112
- return this.pool.length;
109
+ loadComponent(e, t, n = !0) {
110
+ let r = this.world.registry[e], i = r.memoryComponent, a = i.create(r.toBlock(t, this)), o = r.attach(this, i, a);
111
+ return o.block ??= i.getBlock(a), this.components[e] = o, n && this.emit("component-added", e, o), o;
113
112
  }
114
- get rawLength() {
115
- return this.pool.bufferLength;
113
+ attachComponent(e, t) {
114
+ let n = this.world.registry[e], r = n.attach(this, n.memoryComponent, t);
115
+ return r.block ??= n.memoryComponent.getBlock(t), this.components[e] = r, r;
116
116
  }
117
- create(e) {
118
- return this.pool.push(e);
117
+ removeComponent(e) {
118
+ let t = this.components[e];
119
+ if (t) {
120
+ let n = this.world.registry[e];
121
+ this.world.deferComponentMemoryFree(n.memoryComponent, t.index, n.free ? () => n.free(t) : void 0), delete this.components[e], this.emit("component-removed", e);
122
+ }
119
123
  }
120
- getBlock(e) {
121
- return this.pool.at(e);
124
+ setComponent(e, t, n) {
125
+ let r = this.components[e];
126
+ r && (r[t] = n, this.emit("component-property-updated", e, t, n));
122
127
  }
123
- get(e, t) {
124
- return this.pool.get(e, t);
128
+ setComponentBulk(e, t) {
129
+ let n = this.components[e];
130
+ n && Object.assign(n, t);
125
131
  }
126
- set(e, t, n) {
127
- let r = this.pool.at(e);
128
- r[t] = n;
132
+ deleteComponent(e, t) {
133
+ let n = this.components[e];
134
+ n && (delete n[t], this.emit("component-property-deleted", e, t));
129
135
  }
130
- delete(e) {
131
- this.pool.deleteIndex(e);
136
+ deleteAllComponentMemory() {
137
+ let e = this.world.registry, t = this.components;
138
+ for (let n of Object.keys(t)) {
139
+ let r = e[n], i = t[n];
140
+ i && this.world.deferComponentMemoryFree(r.memoryComponent, i.index, r.free ? () => r.free(i) : void 0);
141
+ }
132
142
  }
133
- clear() {
134
- this.pool.clear();
143
+ load(e) {
144
+ let t = e, n = this.world.registry;
145
+ for (let r of Object.keys(n)) {
146
+ if (r === "entity") continue;
147
+ let i = n[r];
148
+ i.loadInFinishLoading || i.loadProperties.some((e) => e in t) && this.loadComponent(r, e, !1);
149
+ }
150
+ this.config = e;
135
151
  }
136
- }, b = class extends v.default {
152
+ save() {
153
+ let e = {}, t = this.world.registry, n = this.components;
154
+ for (let r of Object.keys(n)) {
155
+ let i = t[r], a = n[r];
156
+ i.save && a && Object.assign(e, i.save(a));
157
+ }
158
+ return e;
159
+ }
160
+ finishLoading() {
161
+ let e = this.config;
162
+ if (!e) return;
163
+ let t = e, n = this.world.registry;
164
+ for (let r of Object.keys(n)) {
165
+ if (r === "entity") continue;
166
+ let i = n[r];
167
+ i.loadInFinishLoading && i.loadProperties.some((e) => e in t) && this.loadComponent(r, e, !1);
168
+ }
169
+ }
170
+ }, w = class extends S.default {
137
171
  world;
138
172
  name;
139
173
  currentDelta = 0;
@@ -153,6 +187,17 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
153
187
  return this.deltaBetweenRuns > 0 && (e = this.currentDelta % this.deltaBetweenRuns), this.run(this.currentDelta - e), this.currentDelta = e, this.firstRun = !1, this.onRunFinished(), !0;
154
188
  } else return !1;
155
189
  }
190
+ onError(e, t = {}) {
191
+ let n = t.entityId === void 0 ? "" : ` (entity ${t.entityId})`;
192
+ console.error(`Error in system ${this.name}${n}: ${e.message}`, e);
193
+ let r = {
194
+ system: this.name,
195
+ error: e,
196
+ entityId: t.entityId,
197
+ phase: t.phase
198
+ };
199
+ this.world.emit("system-error", r);
200
+ }
156
201
  onRunFinished() {
157
202
  this.world.notifySystemRunCompleted(this);
158
203
  }
@@ -166,7 +211,7 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
166
211
  destroy() {
167
212
  this.removeAllListeners();
168
213
  }
169
- }, x = class extends b {
214
+ }, T = class extends w {
170
215
  remainingInstancesToRun = [];
171
216
  remainingInstancesStartTime = null;
172
217
  iterationsPerCheck;
@@ -192,15 +237,31 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
192
237
  }
193
238
  runIterables(e, t) {
194
239
  let n = performance.now();
195
- this.beforeRunIterables();
196
- for (let r = 0; r < e.length; r++) if (this.updateIterable(e[r], t), r % this.iterationsPerCheck === 0 && performance.now() - n >= this.maxMsPerFrame) {
197
- this.remainingInstancesToRun = e.slice(r + 1), this.remainingInstancesStartTime = t;
240
+ try {
241
+ this.beforeRunIterables();
242
+ } catch (e) {
243
+ this.onError(e, { phase: "preRun" }), this.remainingInstancesToRun = [], this.remainingInstancesStartTime = null;
198
244
  return;
199
245
  }
246
+ for (let r = 0; r < e.length; r++) {
247
+ try {
248
+ this.updateIterable(e[r], t);
249
+ } catch (t) {
250
+ this.onError(t, {
251
+ phase: "update",
252
+ entityId: this.getIterableEntityId(e[r])
253
+ });
254
+ }
255
+ if (r % this.iterationsPerCheck === 0 && performance.now() - n >= this.maxMsPerFrame) {
256
+ this.remainingInstancesToRun = e.slice(r + 1), this.remainingInstancesStartTime = t;
257
+ return;
258
+ }
259
+ }
200
260
  this.remainingInstancesToRun = [], this.remainingInstancesStartTime = null;
201
261
  }
202
262
  beforeRunIterables() {}
203
- }, S = class extends x {
263
+ getIterableEntityId(e) {}
264
+ }, E = class extends T {
204
265
  entities = /* @__PURE__ */ new Map();
205
266
  options;
206
267
  constructor(e, t = { name: "EntitySystem" }) {
@@ -224,6 +285,9 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
224
285
  filterEntity(e) {
225
286
  return !e.components.entity.isStatic;
226
287
  }
288
+ getIterableEntityId(e) {
289
+ return e.eid;
290
+ }
227
291
  isEntityInSystem(e) {
228
292
  return this.entities.has(e.eid);
229
293
  }
@@ -236,30 +300,41 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
236
300
  shouldRun() {
237
301
  return this.entities.size > 0;
238
302
  }
239
- }, C = class {
303
+ }, D = class {
240
304
  onmessage(e, t = []) {}
241
- }, w = class extends C {
305
+ }, O = class extends D {
242
306
  updateFunction;
243
307
  entities = [];
244
308
  queryEntities = {};
245
309
  worldExtension;
246
- constructor(e) {
247
- super(), this.updateFunction = e;
310
+ world;
311
+ allocator;
312
+ createsEntities;
313
+ constructor(e, t, n = !1) {
314
+ super(), this.updateFunction = e, this.world = t, this.createsEntities = n;
315
+ let r = t.registry;
316
+ this.allocator = {
317
+ allocateEid: () => t.allocateEid(),
318
+ allocateComponentBlock: (e, t) => r[e].memoryComponent.create(t)
319
+ };
248
320
  }
249
321
  postMessage(e) {
250
322
  if (e.type === "init") this.onMessageTyped({ type: "init-complete" });
251
323
  else if (e.type === "load") this.worldExtension = this.updateFunction.init?.(e.data) ?? void 0, this.onMessageTyped({ type: "loaded" });
252
324
  else if (e.type === "reset") this.entities = [], this.queryEntities = {};
253
325
  else if (e.type === "run") {
254
- this.worldExtension && Object.assign(e.world, this.worldExtension);
255
- let t = performance.now(), n = [], r = {}, i = [];
256
- this.entities = a(this.entities, e.entities);
257
- let o = {};
326
+ if (this.worldExtension && Object.assign(e.world, this.worldExtension), e.world.getString = (e) => this.world.constantStrings.getString(e) ?? "", e.world.heap = this.world.heap, e.world.allocate = this.allocator, this.createsEntities) {
327
+ let t = this.world.registry;
328
+ e.world.buildEntityDescriptor = (e) => a(e, this.world.factory.configs, t, this.allocator);
329
+ }
330
+ let t = performance.now(), n = [], r = {}, i = [], o = [];
331
+ this.entities = d(this.entities, e.entities);
332
+ let s = {};
258
333
  Object.entries(e.queries).forEach(([e, t]) => {
259
- let n = a(this.queryEntities[e] ?? [], t);
260
- this.queryEntities[e] = n, o[e] = n;
334
+ let n = d(this.queryEntities[e] ?? [], t);
335
+ this.queryEntities[e] = n, s[e] = n;
261
336
  });
262
- let s = {
337
+ let c = {
263
338
  entityComponentChanged(e, t, r, i) {
264
339
  n.push({
265
340
  entityId: e,
@@ -291,25 +366,50 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
291
366
  createEntity(e) {
292
367
  i.push(e);
293
368
  }
294
- };
295
- if (this.updateFunction.preRun && this.updateFunction.preRun(e.world, this.entities, o, s), this.entities.forEach((t) => {
296
- this.updateFunction(e.world, t.entityId, t.components, o, s);
297
- }), this.updateFunction.entityRemoved) for (let t of e.entities.removed) this.updateFunction.entityRemoved(e.world, t, s);
298
- let c = performance.now() - t;
369
+ }, l = !1;
370
+ if (this.updateFunction.preRun) try {
371
+ this.updateFunction.preRun(e.world, this.entities, s, c);
372
+ } catch (e) {
373
+ l = !0, o.push({
374
+ error: e,
375
+ phase: "preRun"
376
+ });
377
+ }
378
+ if (l || this.entities.forEach((t) => {
379
+ try {
380
+ this.updateFunction(e.world, t.entityId, t.components, s, c);
381
+ } catch (e) {
382
+ o.push({
383
+ error: e,
384
+ phase: "update",
385
+ entityId: t.entityId
386
+ });
387
+ }
388
+ }), this.updateFunction.entityRemoved) for (let t of e.entities.removed) try {
389
+ this.updateFunction.entityRemoved(e.world, t, c);
390
+ } catch (e) {
391
+ o.push({
392
+ error: e,
393
+ phase: "entityRemoved",
394
+ entityId: t
395
+ });
396
+ }
397
+ let u = performance.now() - t;
299
398
  this.onMessageTyped({
300
399
  type: "run-complete",
301
400
  generation: e.generation,
302
- runTime: c,
401
+ runTime: u,
303
402
  events: n,
304
403
  systemEvents: r,
305
- created: i
404
+ created: i,
405
+ errors: o
306
406
  });
307
407
  }
308
408
  }
309
409
  onMessageTyped(e) {
310
410
  this.onmessage({ data: e });
311
411
  }
312
- }, T = "___main", E = class extends b {
412
+ }, k = "___main", A = class extends w {
313
413
  entities = /* @__PURE__ */ new Map();
314
414
  options;
315
415
  worker;
@@ -331,16 +431,27 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
331
431
  this.removeEntity(e);
332
432
  }), e.entities.forEach((e) => {
333
433
  this.checkAddEntity(e);
334
- }), !t.forceMainThread && globalThis.Worker !== void 0 && globalThis.SharedArrayBuffer !== void 0 ? (this.worker = t.getWorker(), this.isWorkerThread = !0) : (this.worker = new w(t.updateFunction), this.isWorkerThread = !1), this.initWorker();
434
+ }), !t.forceMainThread && globalThis.Worker !== void 0 && globalThis.SharedArrayBuffer !== void 0 ? (this.worker = t.getWorker(), this.isWorkerThread = !0, e.on("grow-buffer", (e) => {
435
+ this.worker.postMessage({
436
+ type: "grow-buffer",
437
+ buffer: e
438
+ });
439
+ })) : (this.worker = new O(t.updateFunction, e, !!t.createsEntities), this.isWorkerThread = !1), this.initWorker();
335
440
  }
336
441
  initWorker() {
337
442
  this.worker.onmessage = (e) => {
338
443
  let t = e.data;
339
444
  if (t.type === "init-complete") this.initialized = !0, this.initPromise &&= (this.initPromise.resolve(), null);
340
445
  else if (t.type === "loaded") this.loadingPromise &&= (this.loadingPromise.resolve(), null);
446
+ else if (t.type === "grow-buffer-from-worker") this.world.addGrownBuffer(t.buffer);
341
447
  else if (t.type === "run-complete") {
342
448
  if (t.generation !== this.generation) return;
343
- this.isRunning = !1, this.world.emit(`system-${this.name}-worker-finished`, t.runTime);
449
+ this.isRunning = !1, this.world.emit(`system-${this.name}-worker-finished`, t.runTime), t.errors.forEach(({ error: e, entityId: t, phase: n }) => {
450
+ this.onError(e, {
451
+ entityId: t,
452
+ phase: n
453
+ });
454
+ });
344
455
  for (let e of Object.keys(t.systemEvents)) this.emit(e, t.systemEvents[e]);
345
456
  t.events.forEach((e) => {
346
457
  let t = this.world.getEntityByEid(e.entityId);
@@ -350,7 +461,7 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
350
461
  }
351
462
  t.emit(e.event, ...e.args);
352
463
  }), t.created.forEach((e) => {
353
- this.world.loadEntity(e);
464
+ this.world.adoptEntity(e);
354
465
  }), this.world.emit(`system-${this.name}-worker-events-finished`, t.runTime), this.world.notifySystemRunCompleted(this), this.runCompletePromise &&= (this.runCompletePromise.resolve(), null);
355
466
  }
356
467
  }, this.worker.postMessage({ type: "init" });
@@ -372,7 +483,10 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
372
483
  };
373
484
  let n = {
374
485
  type: "load",
375
- data: this.options.getInitData?.()
486
+ data: this.options.getInitData?.(),
487
+ heap: this.isWorkerThread ? this.world.heap.getSharedMemory() : void 0,
488
+ sharedMemory: this.isWorkerThread ? this.world.getSharedComponentMemory() : void 0,
489
+ factoryConfigs: this.isWorkerThread && this.options.createsEntities ? this.world.factory.configs : void 0
376
490
  };
377
491
  return this.worker.postMessage(n), e;
378
492
  }
@@ -411,7 +525,7 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
411
525
  elapsedTime: e
412
526
  };
413
527
  this.addDataToWorld?.(t), this.isRunning = !0;
414
- let n = this.buildQueryDelta(T, this.options), r = {};
528
+ let n = this.buildQueryDelta(k, this.options), r = {};
415
529
  Object.entries(this.options.queries ?? {}).forEach(([e, t]) => {
416
530
  r[e] = this.buildQueryDelta(e, t);
417
531
  });
@@ -442,10 +556,10 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
442
556
  };
443
557
  }
444
558
  buildComponents(e, t) {
445
- let n = {}, r = this.world.registry;
559
+ let n = {};
446
560
  return [...t.required, ...t.optional ?? []].forEach((t) => {
447
- let i = e.components[t], a = r[t].memoryComponent;
448
- i && a && (n[t] = a.getBlock(i.index));
561
+ let r = e.components[t]?.block;
562
+ r && (n[t] = r);
449
563
  }), n;
450
564
  }
451
565
  isEntityInSystem(e) {
@@ -473,89 +587,28 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
473
587
  }
474
588
  checkAddEntity(e) {
475
589
  let t = this.matchesQuery(e, this.options);
476
- return this.updateEntityList(T, this.entities, e, t), Object.entries(this.options.queries ?? {}).forEach(([t, n]) => {
590
+ return this.updateEntityList(k, this.entities, e, t), Object.entries(this.options.queries ?? {}).forEach(([t, n]) => {
477
591
  let r = this.queryEntities[t] ?? (this.queryEntities[t] = /* @__PURE__ */ new Map());
478
592
  this.updateEntityList(t, r, e, this.matchesQuery(e, n));
479
593
  }), t;
480
594
  }
481
595
  removeEntity(e) {
482
- this.updateEntityList(T, this.entities, e, !1), Object.entries(this.queryEntities).forEach(([t, n]) => {
596
+ this.updateEntityList(k, this.entities, e, !1), Object.entries(this.queryEntities).forEach(([t, n]) => {
483
597
  this.updateEntityList(t, n, e, !1);
484
598
  });
485
599
  }
600
+ recheckMembership() {
601
+ this.world.entities.forEach((e) => {
602
+ this.checkAddEntity(e);
603
+ });
604
+ }
486
605
  shouldRun() {
487
606
  return this.entities.size > 0;
488
607
  }
489
608
  destroy() {
490
609
  super.destroy(), "terminate" in this.worker && this.worker.terminate();
491
610
  }
492
- }, D = class e extends v.default {
493
- static eidCounter = 1;
494
- eid;
495
- config;
496
- world;
497
- components = {};
498
- constructor(t, n) {
499
- super(), this.world = t, this.eid = e.eidCounter++, this.loadComponent("entity", n ?? {}, !1), n && this.load(n);
500
- }
501
- loadComponent(e, t, n = !0) {
502
- let r = this.world.registry[e], i = r.memoryComponent, a = r.load(this, i, t);
503
- return this.components[e] = a, n && this.emit("component-added", e, a), a;
504
- }
505
- removeComponent(e) {
506
- let t = this.components[e];
507
- if (t) {
508
- let n = this.world.registry[e];
509
- this.world.deferComponentMemoryFree(n.memoryComponent, t.index, n.free ? () => n.free(t) : void 0), delete this.components[e], this.emit("component-removed", e);
510
- }
511
- }
512
- setComponent(e, t, n) {
513
- let r = this.components[e];
514
- r && (r[t] = n, this.emit("component-property-updated", e, t, n));
515
- }
516
- setComponentBulk(e, t) {
517
- let n = this.components[e];
518
- n && Object.assign(n, t);
519
- }
520
- deleteComponent(e, t) {
521
- let n = this.components[e];
522
- n && (delete n[t], this.emit("component-property-deleted", e, t));
523
- }
524
- deleteAllComponentMemory() {
525
- let e = this.world.registry, t = this.components;
526
- for (let n of Object.keys(t)) {
527
- let r = e[n], i = t[n];
528
- i && this.world.deferComponentMemoryFree(r.memoryComponent, i.index, r.free ? () => r.free(i) : void 0);
529
- }
530
- }
531
- load(e) {
532
- let t = e, n = this.world.registry;
533
- for (let r of Object.keys(n)) {
534
- if (r === "entity") continue;
535
- let i = n[r];
536
- i.loadInFinishLoading || i.loadProperties.some((e) => e in t) && this.loadComponent(r, e, !1);
537
- }
538
- this.config = e;
539
- }
540
- save() {
541
- let e = {}, t = this.world.registry, n = this.components;
542
- for (let r of Object.keys(n)) {
543
- let i = t[r], a = n[r];
544
- i.save && a && Object.assign(e, i.save(a));
545
- }
546
- return e;
547
- }
548
- finishLoading() {
549
- let e = this.config;
550
- if (!e) return;
551
- let t = e, n = this.world.registry;
552
- for (let r of Object.keys(n)) {
553
- if (r === "entity") continue;
554
- let i = n[r];
555
- i.loadInFinishLoading && i.loadProperties.some((e) => e in t) && this.loadComponent(r, e, !1);
556
- }
557
- }
558
- }, O = class {
611
+ }, j = class {
559
612
  world;
560
613
  configs;
561
614
  constructor(e = {}) {
@@ -576,10 +629,12 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
576
629
  return this.world.addEntity(n, t);
577
630
  }
578
631
  createEntity(e) {
579
- return new D(this.world, e);
632
+ return new C(this.world, e);
580
633
  }
581
- }, k = c, A = 1e4, j = class extends v.default {
634
+ }, M = p, N = 1e4, P = class extends S.default {
582
635
  heap;
636
+ constantStrings;
637
+ eidCounter;
583
638
  registry;
584
639
  factory;
585
640
  entities = /* @__PURE__ */ new Map();
@@ -601,19 +656,36 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
601
656
  waitElapsed: 0
602
657
  };
603
658
  constructor(e, t = {}) {
604
- super(), this.heap = new s({ bufferSize: t.heapSize ?? k });
605
- let n = {
659
+ super(), this.heap = new f({ bufferSize: t.heapSize ?? M }), this.constantStrings = new n(this.heap), this.eidCounter = this.heap.allocUI32(1), this.heap.addOnGrowBufferHandlers((e) => this.emit("grow-buffer", e));
660
+ let i = {
606
661
  ...e,
607
- entity: r
608
- }, i = {};
609
- for (let e of Object.keys(n)) {
610
- let t = n[e];
611
- i[e] = {
662
+ entity: l
663
+ }, a = {};
664
+ for (let e of Object.keys(i)) {
665
+ let t = i[e];
666
+ a[e] = {
612
667
  ...t,
613
- memoryComponent: new y(this.heap, t.type, t.size)
668
+ memoryComponent: new r(this.heap, t.type, t.size)
614
669
  };
615
670
  }
616
- this.registry = i, this.factory = t.factory ?? new O(), this.factory.world = this;
671
+ this.registry = a, this.factory = t.factory ?? new j(), this.factory.world = this;
672
+ }
673
+ allocateEid() {
674
+ return Atomics.add(this.eidCounter.data, 0, 1) + 1;
675
+ }
676
+ getSharedComponentMemory() {
677
+ let e = {};
678
+ for (let t of Object.keys(this.registry)) e[t] = this.registry[t].memoryComponent.getSharedMemory();
679
+ return {
680
+ components: e,
681
+ eidCounter: this.eidCounter.getSharedMemory()
682
+ };
683
+ }
684
+ addGrownBuffer(e) {
685
+ this.heap.buffers[e.bufferPosition] === void 0 && this.heap.addSharedBuffer(e), this.emit("grow-buffer", e);
686
+ }
687
+ get needsSpareBuffer() {
688
+ return this.systems.some((e) => e instanceof A && e.isWorkerThread && !!e.options.createsEntities);
617
689
  }
618
690
  async init() {
619
691
  await Promise.all(this.systems.map((e) => e.init()).filter((e) => e instanceof Promise));
@@ -633,11 +705,21 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
633
705
  loadEntity(e, t = !0) {
634
706
  return this.factory.loadEntity(e, t);
635
707
  }
708
+ adoptEntity(e) {
709
+ let t = new C(this, void 0, e.eid);
710
+ t.loadComponent("entity", {
711
+ type: e.type,
712
+ isStatic: e.isStatic
713
+ }, !1);
714
+ for (let n of Object.keys(e.components)) t.attachComponent(n, e.components[n]);
715
+ return this.addEntity(t, !0);
716
+ }
636
717
  load(e) {
637
718
  if (!this.pristine) {
638
719
  for (let e of Array.from(this.entities.values())) this.removeEntity(e);
639
720
  this.systems.forEach((e) => e.clear()), this.consolidateFreeBuffersForReload();
640
721
  }
722
+ for (let e of Object.keys(this.factory.configs)) this.constantStrings.getOrCreate(e);
641
723
  let t = e.entities.map((e) => this.loadEntity(e, !1));
642
724
  for (let e of t) e.finishLoading(), this.emit("entity-added", e), e.on("death", () => {
643
725
  this.onEntityDied(e);
@@ -691,9 +773,9 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
691
773
  }
692
774
  checkFreeBufferTimeout(e) {
693
775
  let t = this.activeFreeBuffer;
694
- if (t.waitingSystems.size !== 0 && (t.waitElapsed += e, t.waitElapsed >= A)) {
776
+ if (t.waitingSystems.size !== 0 && (t.waitElapsed += e, t.waitElapsed >= N)) {
695
777
  let e = Array.from(t.waitingSystems).map((e) => e.name).join(", ");
696
- console.warn(`shared-memory-ecs: deferred component free waited over ${A}ms on system(s): ${e}; freeing anyway`), t.waitingSystems.clear(), this.processFreeBuffers();
778
+ console.warn(`shared-memory-ecs: deferred component free waited over ${N}ms on system(s): ${e}; freeing anyway`), t.waitingSystems.clear(), this.processFreeBuffers();
697
779
  }
698
780
  }
699
781
  addSystem(e) {
@@ -717,7 +799,7 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
717
799
  runUpdate(e) {
718
800
  if (this.playerTime += e, this.paused) return {};
719
801
  let t = e;
720
- e = this.timeScale * e, this.gameTime += e, this.processFreeBuffers();
802
+ e = this.timeScale * e, this.gameTime += e, this.processFreeBuffers(), this.needsSpareBuffer && this.heap.ensureSpareBuffer();
721
803
  let n = null;
722
804
  return this.systems.forEach((t) => {
723
805
  let r = !0, i = !1, a = !1;
@@ -725,8 +807,12 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
725
807
  try {
726
808
  r = t.shouldRun(), r && (i = t.update(e));
727
809
  } catch (e) {
728
- let t = e;
729
- console.error(t.message, t), a = !0, n = t;
810
+ let r = e;
811
+ console.error(r.message, r), a = !0, n = r, this.emit("system-error", {
812
+ system: t.name,
813
+ error: r,
814
+ phase: "run"
815
+ });
730
816
  }
731
817
  this.emit(`system-${t.name}-finished`, {
732
818
  ran: i,
@@ -743,12 +829,12 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
743
829
  }
744
830
  addEntityToComponentSystem(e, t) {
745
831
  this.systems.forEach((n) => {
746
- (n instanceof S && n.options.components?.includes(t) || n instanceof E && this.componentAffectsComponentSystem(n, t)) && n.checkAddEntity(e);
832
+ (n instanceof E && n.options.components?.includes(t) || n instanceof A && this.componentAffectsComponentSystem(n, t)) && n.checkAddEntity(e);
747
833
  });
748
834
  }
749
835
  removeEntityFromComponentSystem(e, t) {
750
836
  this.systems.forEach((n) => {
751
- n instanceof S && n.options.components?.includes(t) ? n.removeEntity(e) : n instanceof E && this.componentAffectsComponentSystem(n, t) && n.checkAddEntity(e);
837
+ n instanceof E && n.options.components?.includes(t) ? n.removeEntity(e) : n instanceof A && this.componentAffectsComponentSystem(n, t) && n.checkAddEntity(e);
752
838
  });
753
839
  }
754
840
  componentAffectsComponentSystem(e, t) {
@@ -763,19 +849,19 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
763
849
  };
764
850
  //#endregion
765
851
  //#region src/actions/kill-entity.ts
766
- function M(e) {
852
+ function F(e) {
767
853
  e.components.entity.dead = !0, e.emit("death");
768
854
  }
769
855
  //#endregion
770
856
  //#region src/performance-timing.ts
771
- var N = 1e3, P = {
857
+ var I = 1e3, L = {
772
858
  avg: 0,
773
859
  min: 0,
774
860
  max: 0,
775
861
  samples: 0
776
862
  };
777
- function F(e) {
778
- if (!e.length) return { ...P };
863
+ function R(e) {
864
+ if (!e.length) return { ...L };
779
865
  let t = 0, n = Infinity, r = 0;
780
866
  for (let i of e) t += i, i < n && (n = i), i > r && (r = i);
781
867
  return {
@@ -785,13 +871,13 @@ function F(e) {
785
871
  samples: e.length
786
872
  };
787
873
  }
788
- var I = class extends v.default {
874
+ var z = class extends S.default {
789
875
  world;
790
876
  ticksBetweenUpdates;
791
877
  stats = {
792
- update: { ...P },
878
+ update: { ...L },
793
879
  systems: [],
794
- events: { ...P }
880
+ events: { ...L }
795
881
  };
796
882
  ticks = 0;
797
883
  updateStart = 0;
@@ -808,9 +894,9 @@ var I = class extends v.default {
808
894
  this.ticks = 0, this.updateTimes = [], this.systemTimings.forEach((e) => {
809
895
  e.run = [], e.events = [], e.eventStart = -1;
810
896
  }), this.stats = {
811
- update: { ...P },
897
+ update: { ...L },
812
898
  systems: [],
813
- events: { ...P }
899
+ events: { ...L }
814
900
  };
815
901
  }
816
902
  destroy() {
@@ -852,14 +938,14 @@ var I = class extends v.default {
852
938
  let t = this.systemTimings.get(e.name);
853
939
  return {
854
940
  name: e.name,
855
- run: F(t?.run ?? []),
856
- events: F(t?.events ?? [])
941
+ run: R(t?.run ?? []),
942
+ events: R(t?.events ?? [])
857
943
  };
858
- }), t = { ...P };
944
+ }), t = { ...L };
859
945
  e.forEach((e) => {
860
946
  t.avg += e.events.avg, t.min += e.events.min, t.max += e.events.max, t.samples += e.events.samples;
861
947
  }), this.stats = {
862
- update: F(this.updateTimes),
948
+ update: R(this.updateTimes),
863
949
  systems: e,
864
950
  events: t
865
951
  }, this.ticks = 0, this.updateTimes = [], this.systemTimings.forEach((e) => {
@@ -868,6 +954,6 @@ var I = class extends v.default {
868
954
  }
869
955
  };
870
956
  //#endregion
871
- export { D as BaseEntity, j as BaseWorld, E as ComponentSystem, w as ComponentWebWorker, t as DEAD_INDEX, N as DEFAULT_TICKS_BETWEEN_UPDATES, O as EntityFactory, S as EntitySystem, x as IterableSystem, y as MemoryComponent, I as PerformanceTiming, e as STATIC_INDEX, b as System, C as WebWorker, o as createComponentWorker, n as createEntityWorker, r as entityDefinition, M as killEntity, i as killEntityWorker };
957
+ export { C as BaseEntity, P as BaseWorld, t as Component, A as ComponentSystem, O as ComponentWebWorker, n as ConstantStringCache, i as DEAD_INDEX, I as DEFAULT_TICKS_BETWEEN_UPDATES, j as EntityFactory, E as EntitySystem, T as IterableSystem, r as MemoryComponent, z as PerformanceTiming, e as STATIC_INDEX, w as System, s as TYPE_INDEX, D as WebWorker, u as createComponentWorker, o as createEntityWorker, l as entityDefinition, F as killEntity, c as killEntityWorker };
872
958
 
873
959
  //# sourceMappingURL=index.js.map