@daneren2005/shared-memory-ecs 1.3.0 → 1.5.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.
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-CaB32Dgn.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;
@@ -150,16 +184,23 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
150
184
  update(e) {
151
185
  if (this.currentDelta += e, this.currentDelta >= this.deltaBetweenRuns || this.firstRun) {
152
186
  let e = 0;
153
- return this.deltaBetweenRuns > 0 && (e = this.currentDelta % this.deltaBetweenRuns), this.run(this.currentDelta - e), this.currentDelta = e, this.firstRun = !1, !0;
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
+ onRunFinished() {
191
+ this.world.notifySystemRunCompleted(this);
192
+ }
193
+ isCurrentlyRunning() {
194
+ return !1;
195
+ }
196
+ waitForRunToComplete() {}
156
197
  shouldRun() {
157
198
  return !0;
158
199
  }
159
200
  destroy() {
160
201
  this.removeAllListeners();
161
202
  }
162
- }, x = class extends b {
203
+ }, T = class extends w {
163
204
  remainingInstancesToRun = [];
164
205
  remainingInstancesStartTime = null;
165
206
  iterationsPerCheck;
@@ -171,12 +212,18 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
171
212
  super.clear(), this.remainingInstancesToRun = [], this.remainingInstancesStartTime = null;
172
213
  }
173
214
  update(e) {
174
- return this.remainingInstancesToRun.length ? (this.runIterables(this.remainingInstancesToRun, this.remainingInstancesStartTime ?? 0), this.currentDelta += e, !0) : super.update(e);
215
+ return this.remainingInstancesToRun.length ? (this.runIterables(this.remainingInstancesToRun, this.remainingInstancesStartTime ?? 0), this.currentDelta += e, this.remainingInstancesToRun.length || this.onRunFinished(), !0) : super.update(e);
175
216
  }
176
217
  run(e) {
177
218
  let t = this.getIterables();
178
219
  this.runIterables(t, e);
179
220
  }
221
+ onRunFinished() {
222
+ this.remainingInstancesToRun.length || super.onRunFinished();
223
+ }
224
+ isCurrentlyRunning() {
225
+ return this.remainingInstancesToRun.length > 0;
226
+ }
180
227
  runIterables(e, t) {
181
228
  let n = performance.now();
182
229
  this.beforeRunIterables();
@@ -187,7 +234,7 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
187
234
  this.remainingInstancesToRun = [], this.remainingInstancesStartTime = null;
188
235
  }
189
236
  beforeRunIterables() {}
190
- }, S = class extends x {
237
+ }, E = class extends T {
191
238
  entities = /* @__PURE__ */ new Map();
192
239
  options;
193
240
  constructor(e, t = { name: "EntitySystem" }) {
@@ -223,27 +270,38 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
223
270
  shouldRun() {
224
271
  return this.entities.size > 0;
225
272
  }
226
- }, C = class {
273
+ }, D = class {
227
274
  onmessage(e, t = []) {}
228
- }, w = class extends C {
275
+ }, O = class extends D {
229
276
  updateFunction;
230
277
  entities = [];
231
278
  queryEntities = {};
232
279
  worldExtension;
233
- constructor(e) {
234
- super(), this.updateFunction = e;
280
+ world;
281
+ allocator;
282
+ createsEntities;
283
+ constructor(e, t, n = !1) {
284
+ super(), this.updateFunction = e, this.world = t, this.createsEntities = n;
285
+ let r = t.registry;
286
+ this.allocator = {
287
+ allocateEid: () => t.allocateEid(),
288
+ allocateComponentBlock: (e, t) => r[e].memoryComponent.create(t)
289
+ };
235
290
  }
236
291
  postMessage(e) {
237
292
  if (e.type === "init") this.onMessageTyped({ type: "init-complete" });
238
293
  else if (e.type === "load") this.worldExtension = this.updateFunction.init?.(e.data) ?? void 0, this.onMessageTyped({ type: "loaded" });
239
294
  else if (e.type === "reset") this.entities = [], this.queryEntities = {};
240
295
  else if (e.type === "run") {
241
- this.worldExtension && Object.assign(e.world, this.worldExtension);
296
+ if (this.worldExtension && Object.assign(e.world, this.worldExtension), e.world.getString = (e) => this.world.constantStrings.getString(e) ?? "", e.world.allocate = this.allocator, this.createsEntities) {
297
+ let t = this.world.registry;
298
+ e.world.buildEntityDescriptor = (e) => a(e, this.world.factory.configs, t, this.allocator);
299
+ }
242
300
  let t = performance.now(), n = [], r = {}, i = [];
243
- this.entities = a(this.entities, e.entities);
301
+ this.entities = d(this.entities, e.entities);
244
302
  let o = {};
245
303
  Object.entries(e.queries).forEach(([e, t]) => {
246
- let n = a(this.queryEntities[e] ?? [], t);
304
+ let n = d(this.queryEntities[e] ?? [], t);
247
305
  this.queryEntities[e] = n, o[e] = n;
248
306
  });
249
307
  let s = {
@@ -296,7 +354,7 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
296
354
  onMessageTyped(e) {
297
355
  this.onmessage({ data: e });
298
356
  }
299
- }, T = "___main", E = class extends b {
357
+ }, k = "___main", A = class extends w {
300
358
  entities = /* @__PURE__ */ new Map();
301
359
  options;
302
360
  worker;
@@ -304,6 +362,7 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
304
362
  initialized = !1;
305
363
  initPromise = null;
306
364
  loadingPromise = null;
365
+ runCompletePromise = null;
307
366
  isRunning = !1;
308
367
  generation = 0;
309
368
  queryEntities = {};
@@ -317,13 +376,19 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
317
376
  this.removeEntity(e);
318
377
  }), e.entities.forEach((e) => {
319
378
  this.checkAddEntity(e);
320
- }), !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();
379
+ }), !t.forceMainThread && globalThis.Worker !== void 0 && globalThis.SharedArrayBuffer !== void 0 ? (this.worker = t.getWorker(), this.isWorkerThread = !0, e.on("grow-buffer", (e) => {
380
+ this.worker.postMessage({
381
+ type: "grow-buffer",
382
+ buffer: e
383
+ });
384
+ })) : (this.worker = new O(t.updateFunction, e, !!t.createsEntities), this.isWorkerThread = !1), this.initWorker();
321
385
  }
322
386
  initWorker() {
323
387
  this.worker.onmessage = (e) => {
324
388
  let t = e.data;
325
389
  if (t.type === "init-complete") this.initialized = !0, this.initPromise &&= (this.initPromise.resolve(), null);
326
390
  else if (t.type === "loaded") this.loadingPromise &&= (this.loadingPromise.resolve(), null);
391
+ else if (t.type === "grow-buffer-from-worker") this.world.addGrownBuffer(t.buffer);
327
392
  else if (t.type === "run-complete") {
328
393
  if (t.generation !== this.generation) return;
329
394
  this.isRunning = !1, this.world.emit(`system-${this.name}-worker-finished`, t.runTime);
@@ -336,8 +401,8 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
336
401
  }
337
402
  t.emit(e.event, ...e.args);
338
403
  }), t.created.forEach((e) => {
339
- this.world.loadEntity(e);
340
- }), this.world.emit(`system-${this.name}-worker-events-finished`, t.runTime);
404
+ this.world.adoptEntity(e);
405
+ }), this.world.emit(`system-${this.name}-worker-events-finished`, t.runTime), this.world.notifySystemRunCompleted(this), this.runCompletePromise &&= (this.runCompletePromise.resolve(), null);
341
406
  }
342
407
  }, this.worker.postMessage({ type: "init" });
343
408
  }
@@ -358,23 +423,49 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
358
423
  };
359
424
  let n = {
360
425
  type: "load",
361
- data: this.options.getInitData?.()
426
+ data: this.options.getInitData?.(),
427
+ heap: this.isWorkerThread ? this.world.heap.getSharedMemory() : void 0,
428
+ sharedMemory: this.isWorkerThread ? this.world.getSharedComponentMemory() : void 0,
429
+ factoryConfigs: this.isWorkerThread && this.options.createsEntities ? this.world.factory.configs : void 0
362
430
  };
363
431
  return this.worker.postMessage(n), e;
364
432
  }
365
433
  clear() {
366
- super.clear(), this.isRunning = !1, this.generation++, this.entities.clear(), Object.values(this.queryEntities).forEach((e) => e.clear()), this.queryDeltas = {}, this.worker.postMessage({ type: "reset" });
434
+ if (super.clear(), this.isRunning && !this.runCompletePromise) {
435
+ let { promise: e, resolve: t } = Promise.withResolvers();
436
+ this.runCompletePromise = {
437
+ promise: e,
438
+ resolve: t
439
+ };
440
+ }
441
+ this.isRunning = !1, this.generation++, this.entities.clear(), Object.values(this.queryEntities).forEach((e) => e.clear()), this.queryDeltas = {}, this.worker.postMessage({ type: "reset" });
367
442
  }
368
443
  update(e) {
369
444
  return this.isRunning ? (this.currentDelta += e, !1) : super.update(e);
370
445
  }
446
+ onRunFinished() {}
447
+ isCurrentlyRunning() {
448
+ return this.isRunning;
449
+ }
450
+ waitForRunToComplete() {
451
+ if (this.isRunning) {
452
+ if (!this.runCompletePromise) {
453
+ let { promise: e, resolve: t } = Promise.withResolvers();
454
+ this.runCompletePromise = {
455
+ promise: e,
456
+ resolve: t
457
+ };
458
+ }
459
+ return this.runCompletePromise.promise;
460
+ }
461
+ }
371
462
  run(e) {
372
463
  let t = {
373
464
  gameTime: this.world.gameTime,
374
465
  elapsedTime: e
375
466
  };
376
467
  this.addDataToWorld?.(t), this.isRunning = !0;
377
- let n = this.buildQueryDelta(T, this.options), r = {};
468
+ let n = this.buildQueryDelta(k, this.options), r = {};
378
469
  Object.entries(this.options.queries ?? {}).forEach(([e, t]) => {
379
470
  r[e] = this.buildQueryDelta(e, t);
380
471
  });
@@ -405,10 +496,10 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
405
496
  };
406
497
  }
407
498
  buildComponents(e, t) {
408
- let n = {}, r = this.world.registry;
499
+ let n = {};
409
500
  return [...t.required, ...t.optional ?? []].forEach((t) => {
410
- let i = e.components[t], a = r[t].memoryComponent;
411
- i && a && (n[t] = a.getBlock(i.index));
501
+ let r = e.components[t]?.block;
502
+ r && (n[t] = r);
412
503
  }), n;
413
504
  }
414
505
  isEntityInSystem(e) {
@@ -436,86 +527,28 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
436
527
  }
437
528
  checkAddEntity(e) {
438
529
  let t = this.matchesQuery(e, this.options);
439
- return this.updateEntityList(T, this.entities, e, t), Object.entries(this.options.queries ?? {}).forEach(([t, n]) => {
530
+ return this.updateEntityList(k, this.entities, e, t), Object.entries(this.options.queries ?? {}).forEach(([t, n]) => {
440
531
  let r = this.queryEntities[t] ?? (this.queryEntities[t] = /* @__PURE__ */ new Map());
441
532
  this.updateEntityList(t, r, e, this.matchesQuery(e, n));
442
533
  }), t;
443
534
  }
444
535
  removeEntity(e) {
445
- this.updateEntityList(T, this.entities, e, !1), Object.entries(this.queryEntities).forEach(([t, n]) => {
536
+ this.updateEntityList(k, this.entities, e, !1), Object.entries(this.queryEntities).forEach(([t, n]) => {
446
537
  this.updateEntityList(t, n, e, !1);
447
538
  });
448
539
  }
540
+ recheckMembership() {
541
+ this.world.entities.forEach((e) => {
542
+ this.checkAddEntity(e);
543
+ });
544
+ }
449
545
  shouldRun() {
450
546
  return this.entities.size > 0;
451
547
  }
452
548
  destroy() {
453
549
  super.destroy(), "terminate" in this.worker && this.worker.terminate();
454
550
  }
455
- }, D = class e extends v.default {
456
- static eidCounter = 1;
457
- eid;
458
- config;
459
- world;
460
- components = {};
461
- constructor(t, n) {
462
- super(), this.world = t, this.eid = e.eidCounter++, this.loadComponent("entity", n ?? {}, !1), n && this.load(n);
463
- }
464
- loadComponent(e, t, n = !0) {
465
- let r = this.world.registry[e], i = r.memoryComponent, a = r.load(this, i, t);
466
- return this.components[e] = a, n && this.emit("component-added", e, a), a;
467
- }
468
- removeComponent(e) {
469
- let t = this.components[e];
470
- t && (this.world.registry[e].memoryComponent.delete(t.index), delete this.components[e], this.emit("component-removed", e));
471
- }
472
- setComponent(e, t, n) {
473
- let r = this.components[e];
474
- r && (r[t] = n, this.emit("component-property-updated", e, t, n));
475
- }
476
- setComponentBulk(e, t) {
477
- let n = this.components[e];
478
- n && Object.assign(n, t);
479
- }
480
- deleteComponent(e, t) {
481
- let n = this.components[e];
482
- n && (delete n[t], this.emit("component-property-deleted", e, t));
483
- }
484
- deleteAllComponentMemory() {
485
- let e = this.world.registry;
486
- for (let t of Object.keys(this.components)) {
487
- let n = this.components[t];
488
- n && e[t].memoryComponent.delete(n.index);
489
- }
490
- }
491
- load(e) {
492
- let t = e, n = this.world.registry;
493
- for (let r of Object.keys(n)) {
494
- if (r === "entity") continue;
495
- let i = n[r];
496
- i.loadInFinishLoading || i.loadProperties.some((e) => e in t) && this.loadComponent(r, e, !1);
497
- }
498
- this.config = e;
499
- }
500
- save() {
501
- let e = {}, t = this.world.registry, n = this.components;
502
- for (let r of Object.keys(n)) {
503
- let i = t[r], a = n[r];
504
- i.save && a && Object.assign(e, i.save(a));
505
- }
506
- return e;
507
- }
508
- finishLoading() {
509
- let e = this.config;
510
- if (!e) return;
511
- let t = e, n = this.world.registry;
512
- for (let r of Object.keys(n)) {
513
- if (r === "entity") continue;
514
- let i = n[r];
515
- i.loadInFinishLoading && i.loadProperties.some((e) => e in t) && this.loadComponent(r, e, !1);
516
- }
517
- }
518
- }, O = class {
551
+ }, j = class {
519
552
  world;
520
553
  configs;
521
554
  constructor(e = {}) {
@@ -536,10 +569,12 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
536
569
  return this.world.addEntity(n, t);
537
570
  }
538
571
  createEntity(e) {
539
- return new D(this.world, e);
572
+ return new C(this.world, e);
540
573
  }
541
- }, k = c, A = class extends v.default {
574
+ }, M = p, N = 1e4, P = class extends S.default {
542
575
  heap;
576
+ constantStrings;
577
+ eidCounter;
543
578
  registry;
544
579
  factory;
545
580
  entities = /* @__PURE__ */ new Map();
@@ -549,20 +584,45 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
549
584
  timeScale = 1;
550
585
  paused = !1;
551
586
  destroyed = !1;
587
+ pristine = !0;
588
+ activeFreeBuffer = {
589
+ frees: [],
590
+ waitingSystems: /* @__PURE__ */ new Set(),
591
+ waitElapsed: 0
592
+ };
593
+ nextFreeBuffer = {
594
+ frees: [],
595
+ waitingSystems: /* @__PURE__ */ new Set(),
596
+ waitElapsed: 0
597
+ };
552
598
  constructor(e, t = {}) {
553
- super(), this.heap = new s({ bufferSize: t.heapSize ?? k });
554
- let n = {
599
+ 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));
600
+ let i = {
555
601
  ...e,
556
- entity: r
557
- }, i = {};
558
- for (let e of Object.keys(n)) {
559
- let t = n[e];
560
- i[e] = {
602
+ entity: l
603
+ }, a = {};
604
+ for (let e of Object.keys(i)) {
605
+ let t = i[e];
606
+ a[e] = {
561
607
  ...t,
562
- memoryComponent: new y(this.heap, t.type, t.size)
608
+ memoryComponent: new r(this.heap, t.type, t.size)
563
609
  };
564
610
  }
565
- this.registry = i, this.factory = t.factory ?? new O(), this.factory.world = this;
611
+ this.registry = a, this.factory = t.factory ?? new j(), this.factory.world = this;
612
+ }
613
+ allocateEid() {
614
+ return Atomics.add(this.eidCounter.data, 0, 1) + 1;
615
+ }
616
+ getSharedComponentMemory() {
617
+ let e = {};
618
+ for (let t of Object.keys(this.registry)) e[t] = this.registry[t].memoryComponent.getSharedMemory();
619
+ return {
620
+ components: e,
621
+ eidCounter: this.eidCounter.getSharedMemory()
622
+ };
623
+ }
624
+ addGrownBuffer(e) {
625
+ this.heap.buffers[e.bufferPosition] === void 0 && this.heap.addSharedBuffer(e), this.emit("grow-buffer", e);
566
626
  }
567
627
  async init() {
568
628
  await Promise.all(this.systems.map((e) => e.init()).filter((e) => e instanceof Promise));
@@ -571,7 +631,7 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
571
631
  return Promise.all(this.systems.map((e) => e.finishLoading()).filter((e) => e instanceof Promise));
572
632
  }
573
633
  addEntity(e, t = !0) {
574
- return this.entities.set(e.eid, e), e.world = this, e.on("component-added", (t) => {
634
+ return this.entities.set(e.eid, e), e.world = this, this.pristine = !1, e.on("component-added", (t) => {
575
635
  this.addEntityToComponentSystem(e, t);
576
636
  }), e.on("component-removed", (t) => {
577
637
  this.removeEntityFromComponentSystem(e, t);
@@ -582,15 +642,33 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
582
642
  loadEntity(e, t = !0) {
583
643
  return this.factory.loadEntity(e, t);
584
644
  }
645
+ adoptEntity(e) {
646
+ let t = new C(this, void 0, e.eid);
647
+ t.loadComponent("entity", {
648
+ type: e.type,
649
+ isStatic: e.isStatic
650
+ }, !1);
651
+ for (let n of Object.keys(e.components)) t.attachComponent(n, e.components[n]);
652
+ return this.addEntity(t, !0);
653
+ }
585
654
  load(e) {
586
- for (let e of Array.from(this.entities.values())) this.removeEntity(e);
587
- this.systems.forEach((e) => e.clear());
655
+ if (!this.pristine) {
656
+ for (let e of Array.from(this.entities.values())) this.removeEntity(e);
657
+ this.systems.forEach((e) => e.clear()), this.consolidateFreeBuffersForReload();
658
+ }
659
+ for (let e of Object.keys(this.factory.configs)) this.constantStrings.getOrCreate(e);
588
660
  let t = e.entities.map((e) => this.loadEntity(e, !1));
589
661
  for (let e of t) e.finishLoading(), this.emit("entity-added", e), e.on("death", () => {
590
662
  this.onEntityDied(e);
591
663
  });
592
664
  this.gameTime = e.gameTime ?? 0, this.playerTime = e.playerTime ?? 0, this.timeScale = e.timeScale ?? 1, this.finishLoadingSystems();
593
665
  }
666
+ async clear() {
667
+ if (!this.pristine) {
668
+ for (let e of Array.from(this.entities.values())) this.removeEntity(e);
669
+ this.systems.forEach((e) => e.clear()), await Promise.all(this.systems.map((e) => e.waitForRunToComplete()).filter((e) => e instanceof Promise)), this.freeAllPendingBuffers(), this.pristine = !0;
670
+ }
671
+ }
594
672
  removeEntity(e) {
595
673
  this.entities.delete(e.eid) && this.emit("entity-removed", e), e.deleteAllComponentMemory();
596
674
  }
@@ -600,6 +678,43 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
600
678
  getEntityByEid(e) {
601
679
  return this.entities.get(e);
602
680
  }
681
+ deferComponentMemoryFree(e, t, n) {
682
+ this.nextFreeBuffer.frees.push({
683
+ memoryComponent: e,
684
+ index: t,
685
+ free: n
686
+ });
687
+ }
688
+ notifySystemRunCompleted(e) {
689
+ this.activeFreeBuffer.waitingSystems.delete(e) && this.activeFreeBuffer.waitingSystems.size === 0 && this.processFreeBuffers();
690
+ }
691
+ processFreeBuffers() {
692
+ for (; this.activeFreeBuffer.waitingSystems.size === 0 && (this.activeFreeBuffer.frees.length > 0 && this.performFrees(this.activeFreeBuffer), this.nextFreeBuffer.frees.length !== 0);) this.promoteNextFreeBuffer();
693
+ }
694
+ promoteNextFreeBuffer() {
695
+ let e = this.activeFreeBuffer;
696
+ this.activeFreeBuffer = this.nextFreeBuffer, this.nextFreeBuffer = e;
697
+ let t = this.activeFreeBuffer;
698
+ t.waitElapsed = 0, t.waitingSystems.clear();
699
+ for (let e of this.systems) (e.shouldRun() || e.isCurrentlyRunning()) && t.waitingSystems.add(e);
700
+ }
701
+ consolidateFreeBuffersForReload() {
702
+ this.activeFreeBuffer.frees.length > 0 && (this.nextFreeBuffer.frees.push(...this.activeFreeBuffer.frees), this.activeFreeBuffer.frees.length = 0), this.activeFreeBuffer.waitingSystems.clear(), this.activeFreeBuffer.waitElapsed = 0;
703
+ }
704
+ freeAllPendingBuffers() {
705
+ this.performFrees(this.activeFreeBuffer), this.performFrees(this.nextFreeBuffer), this.activeFreeBuffer.waitingSystems.clear(), this.activeFreeBuffer.waitElapsed = 0, this.nextFreeBuffer.waitingSystems.clear(), this.nextFreeBuffer.waitElapsed = 0;
706
+ }
707
+ performFrees(e) {
708
+ for (let t of e.frees) t.free?.(), t.memoryComponent.delete(t.index);
709
+ e.frees.length = 0;
710
+ }
711
+ checkFreeBufferTimeout(e) {
712
+ let t = this.activeFreeBuffer;
713
+ if (t.waitingSystems.size !== 0 && (t.waitElapsed += e, t.waitElapsed >= N)) {
714
+ let e = Array.from(t.waitingSystems).map((e) => e.name).join(", ");
715
+ console.warn(`shared-memory-ecs: deferred component free waited over ${N}ms on system(s): ${e}; freeing anyway`), t.waitingSystems.clear(), this.processFreeBuffers();
716
+ }
717
+ }
603
718
  addSystem(e) {
604
719
  return this.systems.push(e), this.emit("system-added", e), e;
605
720
  }
@@ -620,23 +735,24 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
620
735
  }
621
736
  runUpdate(e) {
622
737
  if (this.playerTime += e, this.paused) return {};
623
- e = this.timeScale * e, this.gameTime += e;
624
- let t = null;
625
- return this.systems.forEach((n) => {
738
+ let t = e;
739
+ e = this.timeScale * e, this.gameTime += e, this.processFreeBuffers();
740
+ let n = null;
741
+ return this.systems.forEach((t) => {
626
742
  let r = !0, i = !1, a = !1;
627
- this.emit(`system-${n.name}-started`);
743
+ this.emit(`system-${t.name}-started`);
628
744
  try {
629
- r = n.shouldRun(), r && (i = n.update(e));
745
+ r = t.shouldRun(), r && (i = t.update(e));
630
746
  } catch (e) {
631
- let n = e;
632
- console.error(n.message, n), a = !0, t = n;
747
+ let t = e;
748
+ console.error(t.message, t), a = !0, n = t;
633
749
  }
634
- this.emit(`system-${n.name}-finished`, {
750
+ this.emit(`system-${t.name}-finished`, {
635
751
  ran: i,
636
752
  shouldRun: r,
637
753
  failed: a
638
754
  });
639
- }), { lastSystemError: t };
755
+ }), this.checkFreeBufferTimeout(t), { lastSystemError: n };
640
756
  }
641
757
  pause() {
642
758
  this.paused = !0;
@@ -646,12 +762,12 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
646
762
  }
647
763
  addEntityToComponentSystem(e, t) {
648
764
  this.systems.forEach((n) => {
649
- (n instanceof S && n.options.components?.includes(t) || n instanceof E && this.componentAffectsComponentSystem(n, t)) && n.checkAddEntity(e);
765
+ (n instanceof E && n.options.components?.includes(t) || n instanceof A && this.componentAffectsComponentSystem(n, t)) && n.checkAddEntity(e);
650
766
  });
651
767
  }
652
768
  removeEntityFromComponentSystem(e, t) {
653
769
  this.systems.forEach((n) => {
654
- n instanceof S && n.options.components?.includes(t) ? n.removeEntity(e) : n instanceof E && this.componentAffectsComponentSystem(n, t) && n.checkAddEntity(e);
770
+ n instanceof E && n.options.components?.includes(t) ? n.removeEntity(e) : n instanceof A && this.componentAffectsComponentSystem(n, t) && n.checkAddEntity(e);
655
771
  });
656
772
  }
657
773
  componentAffectsComponentSystem(e, t) {
@@ -666,19 +782,19 @@ var u = Object.create, d = Object.defineProperty, f = Object.getOwnPropertyDescr
666
782
  };
667
783
  //#endregion
668
784
  //#region src/actions/kill-entity.ts
669
- function j(e) {
785
+ function F(e) {
670
786
  e.components.entity.dead = !0, e.emit("death");
671
787
  }
672
788
  //#endregion
673
789
  //#region src/performance-timing.ts
674
- var M = 1e3, N = {
790
+ var I = 1e3, L = {
675
791
  avg: 0,
676
792
  min: 0,
677
793
  max: 0,
678
794
  samples: 0
679
795
  };
680
- function P(e) {
681
- if (!e.length) return { ...N };
796
+ function R(e) {
797
+ if (!e.length) return { ...L };
682
798
  let t = 0, n = Infinity, r = 0;
683
799
  for (let i of e) t += i, i < n && (n = i), i > r && (r = i);
684
800
  return {
@@ -688,13 +804,13 @@ function P(e) {
688
804
  samples: e.length
689
805
  };
690
806
  }
691
- var F = class extends v.default {
807
+ var z = class extends S.default {
692
808
  world;
693
809
  ticksBetweenUpdates;
694
810
  stats = {
695
- update: { ...N },
811
+ update: { ...L },
696
812
  systems: [],
697
- events: { ...N }
813
+ events: { ...L }
698
814
  };
699
815
  ticks = 0;
700
816
  updateStart = 0;
@@ -711,9 +827,9 @@ var F = class extends v.default {
711
827
  this.ticks = 0, this.updateTimes = [], this.systemTimings.forEach((e) => {
712
828
  e.run = [], e.events = [], e.eventStart = -1;
713
829
  }), this.stats = {
714
- update: { ...N },
830
+ update: { ...L },
715
831
  systems: [],
716
- events: { ...N }
832
+ events: { ...L }
717
833
  };
718
834
  }
719
835
  destroy() {
@@ -755,14 +871,14 @@ var F = class extends v.default {
755
871
  let t = this.systemTimings.get(e.name);
756
872
  return {
757
873
  name: e.name,
758
- run: P(t?.run ?? []),
759
- events: P(t?.events ?? [])
874
+ run: R(t?.run ?? []),
875
+ events: R(t?.events ?? [])
760
876
  };
761
- }), t = { ...N };
877
+ }), t = { ...L };
762
878
  e.forEach((e) => {
763
879
  t.avg += e.events.avg, t.min += e.events.min, t.max += e.events.max, t.samples += e.events.samples;
764
880
  }), this.stats = {
765
- update: P(this.updateTimes),
881
+ update: R(this.updateTimes),
766
882
  systems: e,
767
883
  events: t
768
884
  }, this.ticks = 0, this.updateTimes = [], this.systemTimings.forEach((e) => {
@@ -771,6 +887,6 @@ var F = class extends v.default {
771
887
  }
772
888
  };
773
889
  //#endregion
774
- export { D as BaseEntity, A as BaseWorld, E as ComponentSystem, w as ComponentWebWorker, t as DEAD_INDEX, M as DEFAULT_TICKS_BETWEEN_UPDATES, O as EntityFactory, S as EntitySystem, x as IterableSystem, y as MemoryComponent, F as PerformanceTiming, e as STATIC_INDEX, b as System, C as WebWorker, o as createComponentWorker, n as createEntityWorker, r as entityDefinition, j as killEntity, i as killEntityWorker };
890
+ 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 };
775
891
 
776
892
  //# sourceMappingURL=index.js.map