@daneren2005/shared-memory-ecs 1.8.2 → 1.10.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/README.md +299 -18
- package/dist/{create-system-worker-C4aS3-3R.js → create-system-worker-CNpRs2FO.js} +121 -71
- package/dist/create-system-worker-CNpRs2FO.js.map +1 -0
- package/dist/entity-compression.d.ts +40 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.js +822 -211
- package/dist/index.js.map +1 -1
- package/dist/scheduling/conflict-scheduler.d.ts +53 -0
- package/dist/scheduling/default-scheduler.d.ts +5 -0
- package/dist/scheduling/scheduler.d.ts +28 -0
- package/dist/systems/entity-system.d.ts +4 -1
- package/dist/systems/entity-worker-system.d.ts +19 -4
- package/dist/systems/iterable-system.d.ts +2 -2
- package/dist/systems/system.d.ts +17 -3
- package/dist/systems/worker-system.d.ts +4 -4
- package/dist/systems/workers/create-entity-system-worker.d.ts +1 -0
- package/dist/systems/workers/create-system-worker.d.ts +3 -2
- package/dist/systems/workers/entity-system-web-worker.d.ts +2 -0
- package/dist/systems/workers/entity-system-worker-message.d.ts +21 -3
- package/dist/systems/workers/entity-work-batch.d.ts +10 -0
- package/dist/worker.d.ts +2 -2
- package/dist/worker.js +1 -1
- package/dist/world.d.ts +13 -5
- package/package.json +3 -1
- package/dist/create-system-worker-C4aS3-3R.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as
|
|
2
|
-
import
|
|
3
|
-
import { MAX_BYTE_OFFSET_LENGTH as
|
|
1
|
+
import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as ee, u as te, v as h, y as g } from "./create-system-worker-CNpRs2FO.js";
|
|
2
|
+
import ne from "@daneren2005/shared-memory-objects/memory-heap";
|
|
3
|
+
import { MAX_BYTE_OFFSET_LENGTH as _ } from "@daneren2005/shared-memory-objects/utils/pointer";
|
|
4
4
|
//#region \0rolldown/runtime.js
|
|
5
|
-
var
|
|
6
|
-
if (t && typeof t == "object" || typeof t == "function") for (var i =
|
|
5
|
+
var v = Object.create, y = Object.defineProperty, re = Object.getOwnPropertyDescriptor, b = Object.getOwnPropertyNames, x = Object.getPrototypeOf, S = Object.prototype.hasOwnProperty, ie = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t.exports), ae = (e, t, n, r) => {
|
|
6
|
+
if (t && typeof t == "object" || typeof t == "function") for (var i = b(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !S.call(e, s) && s !== n && y(e, s, {
|
|
7
7
|
get: ((e) => t[e]).bind(null, s),
|
|
8
|
-
enumerable: !(r =
|
|
8
|
+
enumerable: !(r = re(t, s)) || r.enumerable
|
|
9
9
|
});
|
|
10
10
|
return e;
|
|
11
|
-
},
|
|
11
|
+
}, C = /* @__PURE__ */ ((e, t, n) => (n = e == null ? {} : v(x(e)), ae(t || !e || !e.__esModule || !S.call(e, "default") ? y(n, "default", {
|
|
12
12
|
value: e,
|
|
13
13
|
enumerable: !0
|
|
14
|
-
}) : n, e)))((/* @__PURE__ */
|
|
14
|
+
}) : n, e)))((/* @__PURE__ */ ie(((e, t) => {
|
|
15
15
|
var n = Object.prototype.hasOwnProperty, r = "~";
|
|
16
16
|
function i() {}
|
|
17
17
|
Object.create && (i.prototype = Object.create(null), new i().__proto__ || (r = !1));
|
|
@@ -98,14 +98,18 @@ var b = Object.create, x = Object.defineProperty, S = Object.getOwnPropertyDescr
|
|
|
98
98
|
var t;
|
|
99
99
|
return e ? (t = r ? r + e : e, this._events[t] && s(this, t)) : (this._events = new i(), this._eventsCount = 0), this;
|
|
100
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);
|
|
101
|
-
})))(), 1),
|
|
101
|
+
})))(), 1), w = class extends C.default {
|
|
102
102
|
world;
|
|
103
103
|
name;
|
|
104
104
|
currentDelta = 0;
|
|
105
105
|
deltaBetweenRuns;
|
|
106
106
|
firstRun;
|
|
107
|
+
reads;
|
|
108
|
+
writes;
|
|
109
|
+
exclusive;
|
|
110
|
+
scheduledGameTime;
|
|
107
111
|
constructor(e, t = { name: "System" }) {
|
|
108
|
-
super(), this.name = t.name, this.world = e, this.deltaBetweenRuns = t.deltaBetweenRuns ?? 0, this.firstRun = t.firstRun !== void 0 && t.firstRun;
|
|
112
|
+
super(), this.name = t.name, this.world = e, this.reads = t.reads, this.writes = t.writes, this.exclusive = t.exclusive ?? !1, this.deltaBetweenRuns = t.deltaBetweenRuns ?? 0, this.firstRun = t.firstRun !== void 0 && t.firstRun;
|
|
109
113
|
}
|
|
110
114
|
init() {}
|
|
111
115
|
clear() {
|
|
@@ -113,6 +117,18 @@ var b = Object.create, x = Object.defineProperty, S = Object.getOwnPropertyDescr
|
|
|
113
117
|
}
|
|
114
118
|
finishLoading() {}
|
|
115
119
|
addEntities(e) {}
|
|
120
|
+
get gameTime() {
|
|
121
|
+
return this.scheduledGameTime ?? this.world.gameTime;
|
|
122
|
+
}
|
|
123
|
+
withGameTime(e, t) {
|
|
124
|
+
let n = this.scheduledGameTime;
|
|
125
|
+
this.scheduledGameTime = e;
|
|
126
|
+
try {
|
|
127
|
+
return t();
|
|
128
|
+
} finally {
|
|
129
|
+
this.scheduledGameTime = n;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
116
132
|
update(e) {
|
|
117
133
|
if (this.currentDelta += e, this.currentDelta >= this.deltaBetweenRuns || this.firstRun) {
|
|
118
134
|
let e = 0;
|
|
@@ -141,17 +157,30 @@ var b = Object.create, x = Object.defineProperty, S = Object.getOwnPropertyDescr
|
|
|
141
157
|
shouldRun() {
|
|
142
158
|
return !0;
|
|
143
159
|
}
|
|
160
|
+
get readComponents() {
|
|
161
|
+
return this.reads;
|
|
162
|
+
}
|
|
163
|
+
get requiresExclusiveScheduling() {
|
|
164
|
+
return this.exclusive;
|
|
165
|
+
}
|
|
166
|
+
get createdComponents() {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
get creationReadComponents() {
|
|
170
|
+
return this.readComponents;
|
|
171
|
+
}
|
|
172
|
+
get creationReadQueries() {}
|
|
144
173
|
destroy() {
|
|
145
174
|
this.removeAllListeners();
|
|
146
175
|
}
|
|
147
176
|
};
|
|
148
|
-
function
|
|
177
|
+
function T(e, t, n) {
|
|
149
178
|
let r = e.groups.map(t);
|
|
150
179
|
for (let t = 0; t < e.entities.length; t++) r[e.groupIndexes[t]] && n(e.entities[t]);
|
|
151
180
|
}
|
|
152
181
|
//#endregion
|
|
153
182
|
//#region src/systems/iterable-system.ts
|
|
154
|
-
var
|
|
183
|
+
var E = class extends w {
|
|
155
184
|
remainingInstancesToRun = [];
|
|
156
185
|
remainingInstancesStartTime = null;
|
|
157
186
|
iterationsPerCheck;
|
|
@@ -201,7 +230,7 @@ var j = class extends k {
|
|
|
201
230
|
}
|
|
202
231
|
beforeRunIterables() {}
|
|
203
232
|
getIterableEntityId(e) {}
|
|
204
|
-
},
|
|
233
|
+
}, D = class e extends E {
|
|
205
234
|
entities = /* @__PURE__ */ new Map();
|
|
206
235
|
options;
|
|
207
236
|
constructor(e, t = { name: "EntitySystem" }) {
|
|
@@ -239,7 +268,7 @@ var j = class extends k {
|
|
|
239
268
|
t.entities.forEach((e) => this.onEntityAdded(e));
|
|
240
269
|
return;
|
|
241
270
|
}
|
|
242
|
-
|
|
271
|
+
T(t, (e) => this.hasComponents(e), (e) => {
|
|
243
272
|
this.filterEntity(e) && (this.entities.set(e.eid, e), this.options.updateEntityOnAdd && this.updateEntity(e, 0));
|
|
244
273
|
});
|
|
245
274
|
}
|
|
@@ -255,11 +284,28 @@ var j = class extends k {
|
|
|
255
284
|
shouldRun() {
|
|
256
285
|
return this.isCurrentlyRunning() || this.entities.size > 0;
|
|
257
286
|
}
|
|
258
|
-
|
|
287
|
+
get creationReadComponents() {
|
|
288
|
+
if (!this.options.components) return this.reads ? ["entity", ...this.reads] : void 0;
|
|
289
|
+
let e = this.options.components.filter((e) => e !== "entity");
|
|
290
|
+
return [...this.reads ?? [], ...e.length ? e : ["entity"]];
|
|
291
|
+
}
|
|
292
|
+
get creationReadQueries() {
|
|
293
|
+
if (this.checkAddEntity === e.prototype.checkAddEntity) return [this.options.components ?? []];
|
|
294
|
+
}
|
|
295
|
+
get readComponents() {
|
|
296
|
+
let e = this.options.components ?? this.reads;
|
|
297
|
+
return e ? [
|
|
298
|
+
"entity",
|
|
299
|
+
...e,
|
|
300
|
+
...this.reads ?? []
|
|
301
|
+
] : void 0;
|
|
302
|
+
}
|
|
303
|
+
}, O = class {
|
|
259
304
|
onmessage(e, t = []) {}
|
|
260
|
-
},
|
|
305
|
+
}, k = class extends O {
|
|
261
306
|
updateFunction;
|
|
262
307
|
entities = [];
|
|
308
|
+
workState = new a();
|
|
263
309
|
queryEntities = {};
|
|
264
310
|
worldExtension;
|
|
265
311
|
world;
|
|
@@ -274,57 +320,67 @@ var j = class extends k {
|
|
|
274
320
|
allocateComponentBlock: (e, t) => i[e].memoryComponent.create(t)
|
|
275
321
|
};
|
|
276
322
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
else if (
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
323
|
+
getString = (e) => this.world.constantStrings.getString(e) ?? "";
|
|
324
|
+
postMessage(t) {
|
|
325
|
+
if (t.type === "init") this.onMessageTyped({ type: "init-complete" });
|
|
326
|
+
else if (t.type === "load") {
|
|
327
|
+
this.entities = e(this.entities, t.entities), Object.entries(t.queries).forEach(([t, n]) => {
|
|
328
|
+
this.queryEntities[t] = e(this.queryEntities[t] ?? [], n);
|
|
329
|
+
});
|
|
330
|
+
let n = {
|
|
331
|
+
gameTime: t.gameTime,
|
|
332
|
+
getString: this.getString,
|
|
333
|
+
heap: this.world.heap
|
|
334
|
+
};
|
|
335
|
+
this.worldExtension = this.updateFunction.init?.(n, t.data, this.entities, this.queryEntities) ?? void 0, this.onMessageTyped({ type: "loaded" });
|
|
336
|
+
} else if (t.type === "reset") this.workState.clear(), this.entities = [], this.queryEntities = {};
|
|
337
|
+
else if (t.type === "run") {
|
|
338
|
+
if (t.world = this.workState.getWorld(t.world, t.workBatch), this.worldExtension && Object.assign(t.world, this.worldExtension), t.world.getString = this.getString, t.world.heap = this.world.heap, t.world.allocate = this.allocator, this.createsEntities) {
|
|
339
|
+
let e = this.world.registry;
|
|
340
|
+
t.world.buildEntityDescriptor = (t) => o(t, this.world.factory.configs, e, this.allocator, this.world.factory.getWorkerClasses());
|
|
285
341
|
}
|
|
286
342
|
if (this.addsComponents) {
|
|
287
|
-
let
|
|
288
|
-
|
|
343
|
+
let e = this.world.registry;
|
|
344
|
+
t.world.buildComponentDescriptor = (t, n) => l(t, n, e, this.allocator);
|
|
289
345
|
}
|
|
290
|
-
let
|
|
291
|
-
this.entities =
|
|
292
|
-
let u = {};
|
|
293
|
-
Object.entries(
|
|
294
|
-
let
|
|
295
|
-
this.queryEntities[
|
|
346
|
+
let n = performance.now(), r = [], i = {}, a = [], s = [], c = [];
|
|
347
|
+
this.entities = e(this.entities, t.entities);
|
|
348
|
+
let u = this.workState.getEntities(this.entities, t.entities, t.workBatch), d = {};
|
|
349
|
+
Object.entries(t.queries).forEach(([t, n]) => {
|
|
350
|
+
let r = e(this.queryEntities[t] ?? [], n);
|
|
351
|
+
this.queryEntities[t] = r, d[t] = r;
|
|
296
352
|
});
|
|
297
|
-
let
|
|
298
|
-
entityComponentChanged(e, t,
|
|
299
|
-
|
|
353
|
+
let f = {
|
|
354
|
+
entityComponentChanged(e, t, n, i) {
|
|
355
|
+
r.push({
|
|
300
356
|
entityId: e,
|
|
301
357
|
event: "component-property-updated",
|
|
302
358
|
args: [
|
|
303
359
|
t,
|
|
304
|
-
|
|
360
|
+
n,
|
|
305
361
|
i
|
|
306
362
|
]
|
|
307
363
|
});
|
|
308
364
|
},
|
|
309
|
-
emitEntityEvent(e, t, ...
|
|
310
|
-
|
|
365
|
+
emitEntityEvent(e, t, ...n) {
|
|
366
|
+
r.push({
|
|
311
367
|
entityId: e,
|
|
312
368
|
event: t,
|
|
313
|
-
args:
|
|
369
|
+
args: n
|
|
314
370
|
});
|
|
315
371
|
},
|
|
316
372
|
emitSystemEvent(e, t) {
|
|
317
|
-
(
|
|
373
|
+
(i[e] ?? (i[e] = [])).push(t);
|
|
318
374
|
},
|
|
319
375
|
entityDied(e) {
|
|
320
|
-
|
|
376
|
+
r.push({
|
|
321
377
|
entityId: e,
|
|
322
378
|
event: "death",
|
|
323
379
|
args: []
|
|
324
380
|
});
|
|
325
381
|
},
|
|
326
382
|
createEntity(e) {
|
|
327
|
-
|
|
383
|
+
a.push(e);
|
|
328
384
|
},
|
|
329
385
|
addComponent(e, t) {
|
|
330
386
|
s.push({
|
|
@@ -342,8 +398,8 @@ var j = class extends k {
|
|
|
342
398
|
}
|
|
343
399
|
};
|
|
344
400
|
if (this.updateFunction.queryChanged) {
|
|
345
|
-
for (let [
|
|
346
|
-
this.updateFunction.queryChanged(
|
|
401
|
+
for (let [e, n] of Object.entries(t.queries)) if (n.added.length || n.removed.length) try {
|
|
402
|
+
this.updateFunction.queryChanged(t.world, e, n, f);
|
|
347
403
|
} catch (e) {
|
|
348
404
|
c.push({
|
|
349
405
|
error: e,
|
|
@@ -351,65 +407,80 @@ var j = class extends k {
|
|
|
351
407
|
});
|
|
352
408
|
}
|
|
353
409
|
}
|
|
354
|
-
let
|
|
355
|
-
if (this.updateFunction.preRun) try {
|
|
356
|
-
this.updateFunction.preRun(
|
|
410
|
+
let p = !1;
|
|
411
|
+
if (this.updateFunction.preRun && (!t.workBatch || t.workBatch.first)) try {
|
|
412
|
+
this.updateFunction.preRun(t.world, this.entities, d, f);
|
|
357
413
|
} catch (e) {
|
|
358
|
-
|
|
414
|
+
p = !0, c.push({
|
|
359
415
|
error: e,
|
|
360
416
|
phase: "preRun"
|
|
361
417
|
});
|
|
362
418
|
}
|
|
363
|
-
if (
|
|
419
|
+
if (!p && this.updateFunction.preBatch) try {
|
|
420
|
+
this.updateFunction.preBatch(t.world, u, d, f);
|
|
421
|
+
} catch (e) {
|
|
422
|
+
p = !0, c.push({
|
|
423
|
+
error: e,
|
|
424
|
+
phase: "preBatch"
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
if (p || u.forEach((e) => {
|
|
364
428
|
try {
|
|
365
|
-
this.updateFunction(
|
|
366
|
-
} catch (
|
|
429
|
+
this.updateFunction(t.world, e.entityId, e.components, d, f);
|
|
430
|
+
} catch (t) {
|
|
367
431
|
c.push({
|
|
368
|
-
error:
|
|
432
|
+
error: t,
|
|
369
433
|
phase: "update",
|
|
370
|
-
entityId:
|
|
434
|
+
entityId: e.entityId
|
|
371
435
|
});
|
|
372
436
|
}
|
|
373
|
-
}), this.updateFunction.entityRemoved) for (let
|
|
374
|
-
this.updateFunction.entityRemoved(
|
|
375
|
-
} catch (
|
|
437
|
+
}), this.updateFunction.entityRemoved) for (let e of t.entities.removed) try {
|
|
438
|
+
this.updateFunction.entityRemoved(t.world, e, f);
|
|
439
|
+
} catch (t) {
|
|
376
440
|
c.push({
|
|
377
|
-
error:
|
|
441
|
+
error: t,
|
|
378
442
|
phase: "entityRemoved",
|
|
379
|
-
entityId:
|
|
443
|
+
entityId: e
|
|
380
444
|
});
|
|
381
445
|
}
|
|
382
|
-
let
|
|
383
|
-
this.onMessageTyped({
|
|
446
|
+
let m = performance.now() - n;
|
|
447
|
+
this.workState.finish(t.workBatch, p), this.onMessageTyped({
|
|
384
448
|
type: "run-complete",
|
|
385
|
-
generation:
|
|
386
|
-
runTime:
|
|
387
|
-
events:
|
|
388
|
-
systemEvents:
|
|
389
|
-
created:
|
|
449
|
+
generation: t.generation,
|
|
450
|
+
runTime: m,
|
|
451
|
+
events: r,
|
|
452
|
+
systemEvents: i,
|
|
453
|
+
created: a,
|
|
390
454
|
componentChanges: s,
|
|
391
|
-
errors: c
|
|
455
|
+
errors: c,
|
|
456
|
+
workFailed: p
|
|
392
457
|
});
|
|
393
458
|
}
|
|
394
459
|
}
|
|
395
460
|
onMessageTyped(e) {
|
|
396
461
|
this.onmessage({ data: e });
|
|
397
462
|
}
|
|
398
|
-
},
|
|
463
|
+
}, A = "___main", j = class e extends w {
|
|
399
464
|
entities = /* @__PURE__ */ new Map();
|
|
400
465
|
options;
|
|
401
466
|
worker;
|
|
402
467
|
isWorkerThread;
|
|
403
468
|
initialized = !1;
|
|
404
469
|
initPromise = null;
|
|
470
|
+
initError = null;
|
|
405
471
|
loadingPromise = null;
|
|
406
472
|
runCompletePromise = null;
|
|
407
473
|
isRunning = !1;
|
|
474
|
+
workPass;
|
|
475
|
+
timingBatch;
|
|
476
|
+
pendingEffects;
|
|
477
|
+
completeEffects;
|
|
408
478
|
generation = 0;
|
|
409
479
|
queryEntities = {};
|
|
410
480
|
queryDeltas = {};
|
|
411
481
|
constructor(e, t) {
|
|
412
|
-
super(e, t),
|
|
482
|
+
if (super(e, t), t.workBatchSize !== void 0 && (!Number.isSafeInteger(t.workBatchSize) || t.workBatchSize <= 0)) throw Error("workBatchSize must be a positive safe integer");
|
|
483
|
+
this.options = t, Object.keys(this.options.queries ?? {}).forEach((e) => {
|
|
413
484
|
this.queryEntities[e] = /* @__PURE__ */ new Map();
|
|
414
485
|
}), e.on("entity-added", (t) => {
|
|
415
486
|
e.isBulkLoading || this.checkAddEntity(t);
|
|
@@ -422,55 +493,102 @@ var j = class extends k {
|
|
|
422
493
|
type: "grow-buffer",
|
|
423
494
|
buffer: e
|
|
424
495
|
});
|
|
425
|
-
})) : (this.worker = new
|
|
496
|
+
})) : (this.worker = new k(t.updateFunction, e, !!t.createsEntities, !!t.addsComponents), this.isWorkerThread = !1), this.initWorker();
|
|
426
497
|
}
|
|
427
498
|
initWorker() {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
499
|
+
let e = (e) => {
|
|
500
|
+
console.error(e, e.cause), this.initialized || (this.initError = e, this.initPromise?.reject(e));
|
|
501
|
+
};
|
|
502
|
+
if (!(this.worker instanceof k)) {
|
|
503
|
+
let t = (t) => {
|
|
504
|
+
e(Error(`Worker ${this.name} failed to load`, { cause: t }));
|
|
505
|
+
};
|
|
506
|
+
this.worker.onerror = t, this.worker.onmessageerror = t;
|
|
507
|
+
}
|
|
508
|
+
this.worker.onmessage = (t) => {
|
|
509
|
+
let n = t.data;
|
|
510
|
+
if (n.type === "unhandled-rejection") e(Error(`Worker ${this.name} had an unhandled promise rejection`, { cause: n.error }));
|
|
511
|
+
else if (n.type === "init-complete") this.initialized = !0, this.initPromise &&= (this.initPromise.resolve(), null);
|
|
512
|
+
else if (n.type === "loaded") this.loadingPromise &&= (this.loadingPromise.resolve(), null);
|
|
513
|
+
else if (n.type === "grow-buffer-from-worker") this.world.addGrownBuffer(n.buffer);
|
|
514
|
+
else if (n.type === "run-complete") {
|
|
515
|
+
if (n.generation !== this.generation) {
|
|
516
|
+
this.world.scheduler.prepareEffects && this.discardWorkerAllocations(n);
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
let e = this.timingBatch && {
|
|
520
|
+
...this.timingBatch,
|
|
521
|
+
last: this.timingBatch.last || !!n.workFailed
|
|
522
|
+
};
|
|
523
|
+
if (n.workFailed && (this.workPass = void 0), !this.completeEffects) {
|
|
524
|
+
this.applyWorkerEffects(n, !0, e);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
this.world.emit(`system-${this.name}-worker-finished`, n.runTime, e);
|
|
528
|
+
let t = this.generation, r = !1, i = () => {
|
|
529
|
+
this.pendingEffects = void 0, this.isRunning = !1, this.runCompletePromise?.resolve(), this.runCompletePromise = null;
|
|
530
|
+
}, a = {
|
|
531
|
+
apply: () => {
|
|
532
|
+
if (!r) {
|
|
533
|
+
if (t !== this.generation) {
|
|
534
|
+
a.discard();
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
r = !0, this.pendingEffects = void 0;
|
|
538
|
+
try {
|
|
539
|
+
this.applyWorkerEffects(n, !1, e);
|
|
540
|
+
} catch (e) {
|
|
541
|
+
this.onError(e, { phase: "run" }), this.world.notifySystemRunCompleted(this);
|
|
542
|
+
} finally {
|
|
543
|
+
i();
|
|
544
|
+
}
|
|
447
545
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
});
|
|
452
|
-
for (let e of Object.keys(t.systemEvents)) this.emit(e, t.systemEvents[e]);
|
|
453
|
-
t.events.forEach((e) => {
|
|
454
|
-
let t = this.world.getEntityByEid(e.entityId);
|
|
455
|
-
if (!t) {
|
|
456
|
-
console.warn(`${this.name}-event ${e.event}: Could not find entity with id ${e.entityId}`);
|
|
457
|
-
return;
|
|
546
|
+
},
|
|
547
|
+
discard: () => {
|
|
548
|
+
r || (r = !0, this.discardWorkerAllocations(n), i());
|
|
458
549
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
this.world.adoptEntity(e);
|
|
462
|
-
}), this.world.emit(`system-${this.name}-worker-events-finished`, t.runTime), this.world.notifySystemRunCompleted(this), this.runCompletePromise &&= (this.runCompletePromise.resolve(), null);
|
|
550
|
+
};
|
|
551
|
+
this.pendingEffects = a, this.completeEffects(a);
|
|
463
552
|
}
|
|
464
553
|
}, this.worker.postMessage({ type: "init" });
|
|
465
554
|
}
|
|
555
|
+
applyWorkerEffects(e, t, n) {
|
|
556
|
+
this.isRunning = !1, t && this.world.emit(`system-${this.name}-worker-finished`, e.runTime, n), e.errors.forEach(({ error: e, entityId: t, phase: n }) => {
|
|
557
|
+
this.onError(e, {
|
|
558
|
+
entityId: t,
|
|
559
|
+
phase: n
|
|
560
|
+
});
|
|
561
|
+
}), (e.componentChanges ?? []).forEach((e) => {
|
|
562
|
+
let t = this.world.getEntityByEid(e.entityId);
|
|
563
|
+
if (e.type === "add") {
|
|
564
|
+
let n = this.world.registry[e.component.name];
|
|
565
|
+
if (!t || !n || e.component.name === "entity") {
|
|
566
|
+
n?.memoryComponent.delete(e.component.index);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
let r = e.component.name;
|
|
570
|
+
t.removeComponent(r), t.attachComponent(r, e.component.index, !0);
|
|
571
|
+
} else t && e.componentName !== "entity" && t.removeComponent(e.componentName);
|
|
572
|
+
});
|
|
573
|
+
for (let t of Object.keys(e.systemEvents)) this.emit(t, e.systemEvents[t]);
|
|
574
|
+
e.events.forEach((e) => {
|
|
575
|
+
let t = this.world.getEntityByEid(e.entityId);
|
|
576
|
+
if (!t) {
|
|
577
|
+
console.warn(`${this.name}-event ${e.event}: Could not find entity with id ${e.entityId}`);
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
t.emit(e.event, ...e.args);
|
|
581
|
+
}), e.created.forEach((e) => {
|
|
582
|
+
this.world.adoptEntity(e);
|
|
583
|
+
}), this.world.emit(`system-${this.name}-worker-events-finished`, e.runTime, n), this.world.notifySystemRunCompleted(this), this.runCompletePromise &&= (this.runCompletePromise.resolve(), null);
|
|
584
|
+
}
|
|
585
|
+
discardWorkerAllocations(e) {
|
|
586
|
+
for (let t of e.created) for (let [e, n] of Object.entries(t.components)) this.world.registry[e]?.memoryComponent.delete(n);
|
|
587
|
+
for (let t of e.componentChanges ?? []) t.type === "add" && this.world.registry[t.component.name]?.memoryComponent.delete(t.component.index);
|
|
588
|
+
}
|
|
466
589
|
init() {
|
|
467
|
-
if (this.
|
|
468
|
-
if (this.
|
|
469
|
-
let { promise: e, resolve: t } = Promise.withResolvers();
|
|
470
|
-
return this.initPromise = {
|
|
471
|
-
promise: e,
|
|
472
|
-
resolve: t
|
|
473
|
-
}, e;
|
|
590
|
+
if (this.initError) return Promise.reject(this.initError);
|
|
591
|
+
if (!this.initialized) return this.initPromise ||= Promise.withResolvers(), this.initPromise.promise;
|
|
474
592
|
}
|
|
475
593
|
finishLoading() {
|
|
476
594
|
let { promise: e, resolve: t } = Promise.withResolvers();
|
|
@@ -478,34 +596,72 @@ var j = class extends k {
|
|
|
478
596
|
promise: e,
|
|
479
597
|
resolve: t
|
|
480
598
|
};
|
|
481
|
-
let n = {
|
|
599
|
+
let n = {};
|
|
600
|
+
Object.entries(this.options.queries ?? {}).forEach(([e, t]) => {
|
|
601
|
+
n[e] = this.buildQueryDelta(e, t);
|
|
602
|
+
});
|
|
603
|
+
let r = {
|
|
482
604
|
type: "load",
|
|
483
605
|
data: this.options.getInitData?.(),
|
|
606
|
+
gameTime: this.gameTime,
|
|
607
|
+
entities: this.buildQueryDelta(A, this.options),
|
|
608
|
+
queries: n,
|
|
484
609
|
heap: this.isWorkerThread ? this.world.heap.getSharedMemory() : void 0,
|
|
485
610
|
sharedMemory: this.isWorkerThread ? this.world.getSharedComponentMemory() : void 0,
|
|
486
611
|
factoryConfigs: this.isWorkerThread && this.options.createsEntities ? this.world.factory.configs : void 0,
|
|
487
612
|
factoryClasses: this.isWorkerThread && this.options.createsEntities ? this.world.factory.getWorkerClasses() : void 0,
|
|
488
613
|
addsComponents: !!this.options.addsComponents
|
|
489
614
|
};
|
|
490
|
-
return this.worker.postMessage(
|
|
615
|
+
return this.worker.postMessage(r), e;
|
|
491
616
|
}
|
|
492
617
|
clear() {
|
|
493
|
-
if (super.clear(), this.isRunning && !this.runCompletePromise) {
|
|
618
|
+
if (super.clear(), this.pendingEffects?.discard(), this.isRunning && !this.runCompletePromise) {
|
|
494
619
|
let { promise: e, resolve: t } = Promise.withResolvers();
|
|
495
620
|
this.runCompletePromise = {
|
|
496
621
|
promise: e,
|
|
497
622
|
resolve: t
|
|
498
623
|
};
|
|
499
624
|
}
|
|
500
|
-
this.isRunning = !1, this.generation++, this.entities.clear(), Object.values(this.queryEntities).forEach((e) => e.clear()), this.queryDeltas = {}, this.worker.postMessage({ type: "reset" });
|
|
625
|
+
this.isRunning = !1, this.generation++, this.entities.clear(), Object.values(this.queryEntities).forEach((e) => e.clear()), this.queryDeltas = {}, this.workPass = void 0, this.timingBatch = void 0, this.worker.postMessage({ type: "reset" });
|
|
501
626
|
}
|
|
502
627
|
update(e) {
|
|
503
|
-
return this.isRunning ? (this.currentDelta += e, !1) : super.update(e);
|
|
628
|
+
return this.isRunning ? (this.currentDelta += e, !1) : this.workPass ? (this.currentDelta += e, this.run(this.workPass.elapsedTime), !0) : super.update(e);
|
|
504
629
|
}
|
|
505
630
|
onRunFinished() {}
|
|
506
631
|
isCurrentlyRunning() {
|
|
507
632
|
return this.isRunning;
|
|
508
633
|
}
|
|
634
|
+
get readComponents() {
|
|
635
|
+
let e = [this.options, ...Object.values(this.options.queries ?? {})];
|
|
636
|
+
return [
|
|
637
|
+
"entity",
|
|
638
|
+
...this.reads ?? [],
|
|
639
|
+
...e.flatMap((e) => [...e.required, ...e.optional ?? []])
|
|
640
|
+
];
|
|
641
|
+
}
|
|
642
|
+
get requiresExclusiveScheduling() {
|
|
643
|
+
return super.requiresExclusiveScheduling || this.options.createsEntities === !0 || !!this.options.addsComponents;
|
|
644
|
+
}
|
|
645
|
+
get createdComponents() {
|
|
646
|
+
let e = this.options.createsEntities;
|
|
647
|
+
return e && typeof e != "boolean" ? ["entity", ...e] : [];
|
|
648
|
+
}
|
|
649
|
+
get creationReadComponents() {
|
|
650
|
+
let e = Object.values(this.options.queries ?? {});
|
|
651
|
+
return this.tracksMainQuery && e.push(this.options), [...this.reads ?? [], ...e.flatMap((e) => {
|
|
652
|
+
let t = e.required.filter((e) => e !== "entity"), n = e.optional?.filter((e) => e !== "entity") ?? [];
|
|
653
|
+
return [
|
|
654
|
+
...t.length ? t : ["entity"],
|
|
655
|
+
...n,
|
|
656
|
+
...e.not ?? []
|
|
657
|
+
];
|
|
658
|
+
})];
|
|
659
|
+
}
|
|
660
|
+
get creationReadQueries() {
|
|
661
|
+
if (this.checkAddEntity !== e.prototype.checkAddEntity || this.matchesQuery !== e.prototype.matchesQuery) return;
|
|
662
|
+
let t = Object.values(this.options.queries ?? {});
|
|
663
|
+
return this.tracksMainQuery && t.push(this.options), t.map((e) => e.required);
|
|
664
|
+
}
|
|
509
665
|
waitForRunToComplete() {
|
|
510
666
|
if (this.isRunning) {
|
|
511
667
|
if (!this.runCompletePromise) {
|
|
@@ -519,23 +675,48 @@ var j = class extends k {
|
|
|
519
675
|
}
|
|
520
676
|
}
|
|
521
677
|
run(e) {
|
|
522
|
-
let t =
|
|
523
|
-
|
|
678
|
+
let t, n = this.gameTime;
|
|
679
|
+
if (this.options.workBatchSize !== void 0 && this.tracksMainQuery) {
|
|
680
|
+
let r = !this.workPass, i = this.workPass ??= {
|
|
681
|
+
entities: Array.from(this.entities.values()),
|
|
682
|
+
cursor: 0,
|
|
683
|
+
elapsedTime: e,
|
|
684
|
+
gameTime: n
|
|
685
|
+
};
|
|
686
|
+
n = i.gameTime, e = i.elapsedTime;
|
|
687
|
+
let a = Math.min(i.cursor + this.options.workBatchSize, i.entities.length), o = [];
|
|
688
|
+
for (; i.cursor < a; i.cursor++) {
|
|
689
|
+
let e = i.entities[i.cursor];
|
|
690
|
+
this.entities.get(e.eid) === e && o.push(e.eid);
|
|
691
|
+
}
|
|
692
|
+
let s = i.cursor === i.entities.length;
|
|
693
|
+
t = {
|
|
694
|
+
entityIds: o,
|
|
695
|
+
first: r,
|
|
696
|
+
last: s
|
|
697
|
+
}, s && (this.workPass = void 0);
|
|
698
|
+
}
|
|
699
|
+
let r = {
|
|
700
|
+
gameTime: n,
|
|
524
701
|
elapsedTime: e
|
|
525
702
|
};
|
|
526
|
-
this.addDataToWorld?.(
|
|
527
|
-
|
|
703
|
+
(!t || t.first) && this.addDataToWorld?.(r), this.timingBatch = t && {
|
|
704
|
+
first: t.first,
|
|
705
|
+
last: t.last
|
|
706
|
+
}, this.isRunning = !0, this.completeEffects = this.world.scheduler.prepareEffects?.(this.world, this);
|
|
707
|
+
let i = this.buildQueryDelta(A, this.options), a = {};
|
|
528
708
|
Object.entries(this.options.queries ?? {}).forEach(([e, t]) => {
|
|
529
|
-
|
|
709
|
+
a[e] = this.buildQueryDelta(e, t);
|
|
530
710
|
});
|
|
531
|
-
let
|
|
711
|
+
let o = {
|
|
532
712
|
type: "run",
|
|
533
713
|
generation: this.generation,
|
|
534
|
-
world:
|
|
535
|
-
entities:
|
|
536
|
-
queries:
|
|
714
|
+
world: r,
|
|
715
|
+
entities: i,
|
|
716
|
+
queries: a,
|
|
717
|
+
workBatch: t
|
|
537
718
|
};
|
|
538
|
-
this.worker.postMessage(
|
|
719
|
+
this.worker.postMessage(o);
|
|
539
720
|
}
|
|
540
721
|
buildQueryDelta(e, t) {
|
|
541
722
|
let n = this.getQueryDelta(e), r = [];
|
|
@@ -592,7 +773,7 @@ var j = class extends k {
|
|
|
592
773
|
}
|
|
593
774
|
checkAddEntity(e) {
|
|
594
775
|
let t = this.tracksMainQuery && this.matchesQuery(e, this.options);
|
|
595
|
-
return this.updateEntityList(
|
|
776
|
+
return this.updateEntityList(A, this.entities, e, t), Object.entries(this.options.queries ?? {}).forEach(([t, n]) => {
|
|
596
777
|
let r = this.queryEntities[t] ?? (this.queryEntities[t] = /* @__PURE__ */ new Map());
|
|
597
778
|
this.updateEntityList(t, r, e, this.matchesQuery(e, n));
|
|
598
779
|
}), t;
|
|
@@ -602,19 +783,19 @@ var j = class extends k {
|
|
|
602
783
|
t.entities.forEach((e) => this.checkAddEntity(e));
|
|
603
784
|
return;
|
|
604
785
|
}
|
|
605
|
-
this.tracksMainQuery && this.addBatchToQuery(
|
|
786
|
+
this.tracksMainQuery && this.addBatchToQuery(A, this.entities, this.options, t), Object.entries(this.options.queries ?? {}).forEach(([e, n]) => {
|
|
606
787
|
let r = this.queryEntities[e] ?? (this.queryEntities[e] = /* @__PURE__ */ new Map());
|
|
607
788
|
this.addBatchToQuery(e, r, n, t);
|
|
608
789
|
});
|
|
609
790
|
}
|
|
610
791
|
addBatchToQuery(e, t, n, r) {
|
|
611
792
|
let i = this.getQueryDelta(e);
|
|
612
|
-
|
|
793
|
+
T(r, (e) => this.matchesComponents(e, n), (e) => {
|
|
613
794
|
e.components.entity.dead || n.filter && !n.filter(e) || (t.set(e.eid, e), this.markAdded(i, e));
|
|
614
795
|
});
|
|
615
796
|
}
|
|
616
797
|
removeEntity(e) {
|
|
617
|
-
this.updateEntityList(
|
|
798
|
+
this.updateEntityList(A, this.entities, e, !1), Object.entries(this.queryEntities).forEach(([t, n]) => {
|
|
618
799
|
this.updateEntityList(t, n, e, !1);
|
|
619
800
|
});
|
|
620
801
|
}
|
|
@@ -624,12 +805,12 @@ var j = class extends k {
|
|
|
624
805
|
});
|
|
625
806
|
}
|
|
626
807
|
shouldRun() {
|
|
627
|
-
return this.entities.size > 0;
|
|
808
|
+
return this.workPass !== void 0 || this.entities.size > 0;
|
|
628
809
|
}
|
|
629
810
|
destroy() {
|
|
630
|
-
super.destroy(), "terminate" in this.worker && this.worker.terminate();
|
|
811
|
+
super.destroy(), this.pendingEffects?.discard(), "terminate" in this.worker && this.worker.terminate();
|
|
631
812
|
}
|
|
632
|
-
},
|
|
813
|
+
}, M = class extends C.default {
|
|
633
814
|
eid;
|
|
634
815
|
config;
|
|
635
816
|
world;
|
|
@@ -730,7 +911,7 @@ var j = class extends k {
|
|
|
730
911
|
assertComponentPropertyMutable(e, t) {
|
|
731
912
|
if (e === "entity" && (t === "type" || t === "class")) throw Error(`Entity ${t} is immutable`);
|
|
732
913
|
}
|
|
733
|
-
},
|
|
914
|
+
}, N = class e {
|
|
734
915
|
world;
|
|
735
916
|
configs;
|
|
736
917
|
classes;
|
|
@@ -747,7 +928,7 @@ var j = class extends k {
|
|
|
747
928
|
this.world = e, this.forbiddenProperties.clear();
|
|
748
929
|
for (let t of Object.keys(this.classes)) {
|
|
749
930
|
let n = this.classes[t].entity;
|
|
750
|
-
if (n !==
|
|
931
|
+
if (n !== M && !(n.prototype instanceof M)) throw Error(`Entity class ${t} must extend BaseEntity`);
|
|
751
932
|
for (let n of this.classes[t].components) if (n === "entity" || !(n in e.registry)) throw Error(`Entity class ${t} contains unknown or reserved component ${n}`);
|
|
752
933
|
}
|
|
753
934
|
for (let e of Object.keys(this.configs)) this.validateTemplate(e, this.configs[e]);
|
|
@@ -773,7 +954,7 @@ var j = class extends k {
|
|
|
773
954
|
createAdoptedEntity(e, t, n) {
|
|
774
955
|
if (!t) {
|
|
775
956
|
if (this.hasClasses) throw Error(`Entity type ${e} has no class`);
|
|
776
|
-
return new
|
|
957
|
+
return new M(this.world, void 0, n);
|
|
777
958
|
}
|
|
778
959
|
let r = this.classes[t];
|
|
779
960
|
if (!r) throw Error(`Unknown entity class: ${t}`);
|
|
@@ -799,7 +980,7 @@ var j = class extends k {
|
|
|
799
980
|
return e ? this.getAllowedComponents(e) : void 0;
|
|
800
981
|
}
|
|
801
982
|
createEntity(e) {
|
|
802
|
-
return new
|
|
983
|
+
return new M(this.world, e);
|
|
803
984
|
}
|
|
804
985
|
get hasClasses() {
|
|
805
986
|
return this.allowedComponents.size > 0;
|
|
@@ -864,7 +1045,183 @@ var j = class extends k {
|
|
|
864
1045
|
}
|
|
865
1046
|
throw Error(`Entity type ${e} class ${t} loads a component outside its class`);
|
|
866
1047
|
}
|
|
867
|
-
},
|
|
1048
|
+
}, P = 45, F = "!", I = "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO", L = "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}", R = (/* @__PURE__ */ new Int8Array(128)).fill(-1);
|
|
1049
|
+
for (let e = 0; e < P; e++) R[I.charCodeAt(e)] = e, R[L.charCodeAt(e)] = e + P;
|
|
1050
|
+
function z(e) {
|
|
1051
|
+
let t = "";
|
|
1052
|
+
for (; e >= P;) t += L[e % P], e = Math.floor(e / P);
|
|
1053
|
+
return t + I[e];
|
|
1054
|
+
}
|
|
1055
|
+
var B = /* @__PURE__ */ new Float32Array(1), V = new Uint32Array(B.buffer);
|
|
1056
|
+
function oe(e, t) {
|
|
1057
|
+
switch (e.type) {
|
|
1058
|
+
case "boolean": return typeof t == "boolean" ? I[Number(t)] : void 0;
|
|
1059
|
+
case "string": return t === null ? I[0] : typeof t == "string" && t.length ? z(t.length) + t : void 0;
|
|
1060
|
+
case "float32": return typeof t != "number" || !Number.isFinite(t) || Math.fround(t) !== t ? void 0 : (B[0] = t, z(V[0]));
|
|
1061
|
+
default: {
|
|
1062
|
+
let n = se(e, t);
|
|
1063
|
+
return n === void 0 ? void 0 : z(n);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
function se(e, t) {
|
|
1068
|
+
if (typeof t != "number") return;
|
|
1069
|
+
let n = Math.round((t - (e.offset ?? 0)) * 10 ** (e.decimals ?? 0) / (e.step ?? 1));
|
|
1070
|
+
if (!Number.isSafeInteger(n) || H(e, n) !== t) return;
|
|
1071
|
+
if (e.type === "uint") return n >= 0 ? n : void 0;
|
|
1072
|
+
let r = n >= 0 ? n * 2 : -n * 2 - 1;
|
|
1073
|
+
return Number.isSafeInteger(r) ? r : void 0;
|
|
1074
|
+
}
|
|
1075
|
+
function H(e, t) {
|
|
1076
|
+
return t * (e.step ?? 1) / 10 ** (e.decimals ?? 0) + (e.offset ?? 0);
|
|
1077
|
+
}
|
|
1078
|
+
function U(e, t) {
|
|
1079
|
+
switch (e.type) {
|
|
1080
|
+
case "boolean": return t !== 0;
|
|
1081
|
+
case "float32": return V[0] = t, B[0];
|
|
1082
|
+
case "uint": return H(e, t);
|
|
1083
|
+
default: return H(e, t % 2 == 0 ? t / 2 : -(t + 1) / 2);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
function W(e) {
|
|
1087
|
+
return e.types === void 0 ? [e.type] : e.types;
|
|
1088
|
+
}
|
|
1089
|
+
var G = class {
|
|
1090
|
+
encoders = /* @__PURE__ */ new Map();
|
|
1091
|
+
used = /* @__PURE__ */ new Set();
|
|
1092
|
+
constructor(e) {
|
|
1093
|
+
let t = 0;
|
|
1094
|
+
for (let n of e) {
|
|
1095
|
+
let e = {
|
|
1096
|
+
key: t,
|
|
1097
|
+
definition: n,
|
|
1098
|
+
indices: new Map(n.properties.map((e, t) => [e.name, t]))
|
|
1099
|
+
};
|
|
1100
|
+
for (let r of W(n)) {
|
|
1101
|
+
if (this.encoders.has(r)) throw Error(`Duplicate compressed entity definition for ${r}`);
|
|
1102
|
+
this.encoders.set(r, {
|
|
1103
|
+
prefix: z(t++),
|
|
1104
|
+
group: e
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
get entityDefinitions() {
|
|
1110
|
+
let e = {};
|
|
1111
|
+
for (let t of this.used) e[t.key] = t.definition;
|
|
1112
|
+
return e;
|
|
1113
|
+
}
|
|
1114
|
+
compress(e) {
|
|
1115
|
+
let t = e.type === void 0 ? void 0 : this.encoders.get(e.type), n = t && this.encode(t, e);
|
|
1116
|
+
return !t || n === void 0 ? e : (this.used.add(t.group), n);
|
|
1117
|
+
}
|
|
1118
|
+
compressAll(e) {
|
|
1119
|
+
let t = e.map((e) => this.compress(e));
|
|
1120
|
+
return {
|
|
1121
|
+
entityDefinitions: this.entityDefinitions,
|
|
1122
|
+
entities: t
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
encode(e, t) {
|
|
1126
|
+
let n = [];
|
|
1127
|
+
for (let [r, i] of Object.entries(t)) {
|
|
1128
|
+
if (r === "type" || i === void 0) continue;
|
|
1129
|
+
let t = e.group.indices.get(r);
|
|
1130
|
+
if (t === void 0) return;
|
|
1131
|
+
let a = oe(e.group.definition.properties[t], i);
|
|
1132
|
+
if (a === void 0) return;
|
|
1133
|
+
n[t] = a;
|
|
1134
|
+
}
|
|
1135
|
+
let r = e.prefix;
|
|
1136
|
+
for (let e = 0; e < n.length; e++) r += n[e] ?? F;
|
|
1137
|
+
return r;
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
function ce(e, t) {
|
|
1141
|
+
return new G(t).compressAll(e);
|
|
1142
|
+
}
|
|
1143
|
+
var K = /* @__PURE__ */ new WeakMap();
|
|
1144
|
+
function le(e) {
|
|
1145
|
+
let t = K.get(e);
|
|
1146
|
+
if (t) return t;
|
|
1147
|
+
t = /* @__PURE__ */ new Map();
|
|
1148
|
+
for (let [n, r] of Object.entries(e)) {
|
|
1149
|
+
let e = W(r);
|
|
1150
|
+
for (let i = 0; i < e.length; i++) {
|
|
1151
|
+
if (t.has(Number(n) + i)) throw Error(`Compressed entity definitions overlap at key ${Number(n) + i}`);
|
|
1152
|
+
t.set(Number(n) + i, {
|
|
1153
|
+
type: e[i],
|
|
1154
|
+
properties: r.properties
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
return K.set(e, t), t;
|
|
1159
|
+
}
|
|
1160
|
+
function q(e, t) {
|
|
1161
|
+
let n = 0, r = () => {
|
|
1162
|
+
if (e[n] === F) {
|
|
1163
|
+
n++;
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
let t = 0, r = 1;
|
|
1167
|
+
for (; n < e.length;) {
|
|
1168
|
+
let i = e.charCodeAt(n++), a = i < 128 ? R[i] : -1;
|
|
1169
|
+
if (a < 0) throw Error(`Invalid compressed entity ${e}`);
|
|
1170
|
+
if (a < P) return t + a * r;
|
|
1171
|
+
t += (a - P) * r, r *= P;
|
|
1172
|
+
}
|
|
1173
|
+
throw Error(`Truncated compressed entity ${e}`);
|
|
1174
|
+
}, i = r(), a = i === void 0 ? void 0 : le(t).get(i);
|
|
1175
|
+
if (!a) throw Error(`No compressed entity definition for ${e}`);
|
|
1176
|
+
let o = { type: a.type };
|
|
1177
|
+
for (let t = 0; n < e.length; t++) {
|
|
1178
|
+
let i = a.properties[t];
|
|
1179
|
+
if (!i) throw Error(`Compressed entity ${e} has more values than ${a.type} defines`);
|
|
1180
|
+
let s = r();
|
|
1181
|
+
if (s !== void 0) {
|
|
1182
|
+
if (i.type !== "string") o[i.name] = U(i, s);
|
|
1183
|
+
else if (s === 0) o[i.name] = null;
|
|
1184
|
+
else {
|
|
1185
|
+
if (n + s > e.length) throw Error(`Truncated compressed entity ${e}`);
|
|
1186
|
+
o[i.name] = e.slice(n, n += s);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
return o;
|
|
1191
|
+
}
|
|
1192
|
+
function J(e, t) {
|
|
1193
|
+
return e.map((e) => {
|
|
1194
|
+
if (typeof e != "string") return e;
|
|
1195
|
+
if (!t) throw Error("Compressed entities need entityDefinitions to load");
|
|
1196
|
+
return q(e, t);
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
//#endregion
|
|
1200
|
+
//#region src/scheduling/default-scheduler.ts
|
|
1201
|
+
var Y = class {
|
|
1202
|
+
update(e, t) {
|
|
1203
|
+
let n = null;
|
|
1204
|
+
return e.systems.forEach((r) => {
|
|
1205
|
+
let i = !0, a = !1, o = !1;
|
|
1206
|
+
e.emit(`system-${r.name}-started`);
|
|
1207
|
+
try {
|
|
1208
|
+
i = r.shouldRun(), i && (a = r.update(t));
|
|
1209
|
+
} catch (t) {
|
|
1210
|
+
let i = t;
|
|
1211
|
+
console.error(i.message, i), o = !0, n = i, e.emit("system-error", {
|
|
1212
|
+
system: r.name,
|
|
1213
|
+
error: i,
|
|
1214
|
+
phase: "run"
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
e.emit(`system-${r.name}-finished`, {
|
|
1218
|
+
ran: a,
|
|
1219
|
+
shouldRun: i,
|
|
1220
|
+
failed: o
|
|
1221
|
+
});
|
|
1222
|
+
}), { lastSystemError: n };
|
|
1223
|
+
}
|
|
1224
|
+
}, ue = _, X = 1e4, de = class extends C.default {
|
|
868
1225
|
heap;
|
|
869
1226
|
constantStrings;
|
|
870
1227
|
eidCounter;
|
|
@@ -872,10 +1229,11 @@ var j = class extends k {
|
|
|
872
1229
|
factory;
|
|
873
1230
|
entities = /* @__PURE__ */ new Map();
|
|
874
1231
|
systems = [];
|
|
1232
|
+
scheduler;
|
|
875
1233
|
gameTime = 0;
|
|
876
1234
|
playerTime = 0;
|
|
877
1235
|
timeScale = 1;
|
|
878
|
-
|
|
1236
|
+
isPaused = !1;
|
|
879
1237
|
destroyed = !1;
|
|
880
1238
|
pristine = !0;
|
|
881
1239
|
isBulkLoading = !1;
|
|
@@ -889,20 +1247,21 @@ var j = class extends k {
|
|
|
889
1247
|
waitingSystems: /* @__PURE__ */ new Set(),
|
|
890
1248
|
waitElapsed: 0
|
|
891
1249
|
};
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1250
|
+
clearing = !1;
|
|
1251
|
+
constructor(e, t = {}) {
|
|
1252
|
+
super(), this.scheduler = t.scheduler ?? new Y(), this.heap = new ne({ bufferSize: t.heapSize ?? ue }), this.constantStrings = new h(this.heap), this.eidCounter = this.heap.allocUI32(1), this.heap.addOnGrowBufferHandlers((e) => this.emit("grow-buffer", e));
|
|
1253
|
+
let n = {
|
|
1254
|
+
...e,
|
|
896
1255
|
entity: i
|
|
897
|
-
},
|
|
898
|
-
for (let e of Object.keys(
|
|
899
|
-
let t =
|
|
900
|
-
|
|
1256
|
+
}, r = {};
|
|
1257
|
+
for (let e of Object.keys(n)) {
|
|
1258
|
+
let t = n[e];
|
|
1259
|
+
r[e] = {
|
|
901
1260
|
...t,
|
|
902
|
-
memoryComponent: new
|
|
1261
|
+
memoryComponent: new g(this.heap, t.type, t.size)
|
|
903
1262
|
};
|
|
904
1263
|
}
|
|
905
|
-
this.registry =
|
|
1264
|
+
this.registry = r, this.factory = t.factory ?? new N(), this.factory.setWorld(this);
|
|
906
1265
|
}
|
|
907
1266
|
allocateEid() {
|
|
908
1267
|
return Atomics.add(this.eidCounter.data, 0, 1) + 1;
|
|
@@ -919,13 +1278,13 @@ var j = class extends k {
|
|
|
919
1278
|
this.heap.buffers[e.bufferPosition] === void 0 && this.heap.addSharedBuffer(e), this.emit("grow-buffer", e);
|
|
920
1279
|
}
|
|
921
1280
|
get needsSpareBuffer() {
|
|
922
|
-
return this.systems.some((e) => e instanceof
|
|
1281
|
+
return this.systems.some((e) => e instanceof j && e.isWorkerThread && (!!e.options.createsEntities || !!e.options.addsComponents));
|
|
923
1282
|
}
|
|
924
1283
|
async init() {
|
|
925
1284
|
await Promise.all(this.systems.map((e) => e.init()).filter((e) => e instanceof Promise));
|
|
926
1285
|
}
|
|
927
|
-
finishLoadingSystems() {
|
|
928
|
-
|
|
1286
|
+
async finishLoadingSystems() {
|
|
1287
|
+
await Promise.all(this.systems.map((e) => e.finishLoading()).filter((e) => e instanceof Promise));
|
|
929
1288
|
}
|
|
930
1289
|
addEntity(e, t = !0) {
|
|
931
1290
|
return this.entities.set(e.eid, e), e.world = this, this.pristine = !1, e.on("component-added", (t) => {
|
|
@@ -960,29 +1319,34 @@ var j = class extends k {
|
|
|
960
1319
|
}
|
|
961
1320
|
}
|
|
962
1321
|
load(e) {
|
|
963
|
-
if (!this.pristine) {
|
|
1322
|
+
if (!this.pristine || this.scheduler.prepareEffects && this.systems.some((e) => e.isCurrentlyRunning())) {
|
|
964
1323
|
for (let e of Array.from(this.entities.values())) this.removeEntity(e);
|
|
965
|
-
this.systems.forEach((e) => e.clear()), this.consolidateFreeBuffersForReload();
|
|
1324
|
+
this.systems.forEach((e) => e.clear()), this.scheduler.reset?.(this), this.consolidateFreeBuffersForReload();
|
|
966
1325
|
}
|
|
967
1326
|
for (let e of Object.keys(this.factory.configs)) this.constantStrings.getOrCreate(e);
|
|
968
1327
|
for (let e of Object.keys(this.factory.classes)) this.constantStrings.getOrCreate(e);
|
|
969
1328
|
this.isBulkLoading = !0;
|
|
970
1329
|
try {
|
|
971
|
-
let t = e.entities.map((e) => this.loadEntity(e, !1));
|
|
1330
|
+
let t = ("entityDefinitions" in e ? J(e.entities, e.entityDefinitions) : e.entities).map((e) => this.loadEntity(e, !1));
|
|
972
1331
|
for (let e of t) e.finishLoading(), this.emit("entity-added", e), e.on("death", () => {
|
|
973
1332
|
this.onEntityDied(e);
|
|
974
1333
|
});
|
|
975
1334
|
} finally {
|
|
976
1335
|
this.isBulkLoading = !1;
|
|
977
1336
|
}
|
|
978
|
-
let t =
|
|
979
|
-
this.systems.forEach((e) => e.addEntities(t)), this.gameTime = e.gameTime ?? 0, this.playerTime = e.playerTime ?? 0, this.timeScale = e.timeScale ?? 1, this.finishLoadingSystems();
|
|
1337
|
+
let t = fe(this.entities.values());
|
|
1338
|
+
return this.systems.forEach((e) => e.addEntities(t)), this.gameTime = e.gameTime ?? 0, this.playerTime = e.playerTime ?? 0, this.timeScale = e.timeScale ?? 1, this.finishLoadingSystems();
|
|
980
1339
|
}
|
|
981
1340
|
async clear() {
|
|
982
|
-
if (!this.pristine) {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1341
|
+
if (!this.pristine || this.scheduler.beforeClear) {
|
|
1342
|
+
this.clearing = !0;
|
|
1343
|
+
try {
|
|
1344
|
+
this.scheduler.beforeClear?.(this), await Promise.all(this.systems.map((e) => e.waitForRunToComplete()).filter((e) => e instanceof Promise));
|
|
1345
|
+
for (let e of Array.from(this.entities.values())) this.removeEntity(e);
|
|
1346
|
+
this.systems.forEach((e) => e.clear()), this.scheduler.reset?.(this), this.freeAllPendingBuffers(), this.pristine = !0;
|
|
1347
|
+
} finally {
|
|
1348
|
+
this.clearing = !1;
|
|
1349
|
+
}
|
|
986
1350
|
}
|
|
987
1351
|
}
|
|
988
1352
|
removeEntity(e) {
|
|
@@ -1018,7 +1382,7 @@ var j = class extends k {
|
|
|
1018
1382
|
});
|
|
1019
1383
|
}
|
|
1020
1384
|
notifySystemRunCompleted(e) {
|
|
1021
|
-
this.activeFreeBuffer.waitingSystems.delete(e) && this.activeFreeBuffer.waitingSystems.size === 0 && this.processFreeBuffers();
|
|
1385
|
+
this.activeFreeBuffer.waitingSystems.delete(e) && this.activeFreeBuffer.waitingSystems.size === 0 && this.processFreeBuffers(), this.scheduler.runCompleted?.(this, e);
|
|
1022
1386
|
}
|
|
1023
1387
|
processFreeBuffers() {
|
|
1024
1388
|
for (; this.activeFreeBuffer.waitingSystems.size === 0 && (this.activeFreeBuffer.frees.length > 0 && this.performFrees(this.activeFreeBuffer), this.nextFreeBuffer.frees.length !== 0);) this.promoteNextFreeBuffer();
|
|
@@ -1042,22 +1406,22 @@ var j = class extends k {
|
|
|
1042
1406
|
}
|
|
1043
1407
|
checkFreeBufferTimeout(e) {
|
|
1044
1408
|
let t = this.activeFreeBuffer;
|
|
1045
|
-
if (t.waitingSystems.size !== 0 && (t.waitElapsed += e, t.waitElapsed >=
|
|
1409
|
+
if (t.waitingSystems.size !== 0 && (t.waitElapsed += e, t.waitElapsed >= X)) {
|
|
1046
1410
|
let e = Array.from(t.waitingSystems).map((e) => e.name).join(", ");
|
|
1047
|
-
console.warn(`shared-memory-ecs: deferred component free waited over ${
|
|
1411
|
+
console.warn(`shared-memory-ecs: deferred component free waited over ${X}ms on system(s): ${e}; freeing anyway`), t.waitingSystems.clear(), this.processFreeBuffers();
|
|
1048
1412
|
}
|
|
1049
1413
|
}
|
|
1050
1414
|
addSystem(e) {
|
|
1051
|
-
return this.systems.push(e), this.emit("system-added", e), e;
|
|
1415
|
+
return this.systems.push(e), this.scheduler.systemAdded?.(this, e), this.emit("system-added", e), e;
|
|
1052
1416
|
}
|
|
1053
1417
|
addSystemIfNotExists(e) {
|
|
1054
|
-
this.systems.findIndex((t) => e.name === t.name) === -1 && (this.systems.push(e), this.emit("system-added", e));
|
|
1418
|
+
this.systems.findIndex((t) => e.name === t.name) === -1 && (this.systems.push(e), this.scheduler.systemAdded?.(this, e), this.emit("system-added", e));
|
|
1055
1419
|
}
|
|
1056
1420
|
removeSystem(e) {
|
|
1057
1421
|
let t = this.systems.findIndex((t) => t.name === e);
|
|
1058
1422
|
if (t !== -1) {
|
|
1059
1423
|
let [e] = this.systems.splice(t, 1);
|
|
1060
|
-
this.emit("system-removed", e);
|
|
1424
|
+
this.scheduler.systemRemoved?.(this, e), this.emit("system-removed", e);
|
|
1061
1425
|
}
|
|
1062
1426
|
}
|
|
1063
1427
|
update(e) {
|
|
@@ -1069,41 +1433,35 @@ var j = class extends k {
|
|
|
1069
1433
|
if (this.playerTime += e, this.paused) return {};
|
|
1070
1434
|
let t = e;
|
|
1071
1435
|
e = this.timeScale * e, this.gameTime += e, this.processFreeBuffers(), this.needsSpareBuffer && this.heap.ensureSpareBuffer();
|
|
1072
|
-
let n =
|
|
1073
|
-
return this.
|
|
1074
|
-
let r = !0, i = !1, a = !1;
|
|
1075
|
-
this.emit(`system-${t.name}-started`);
|
|
1076
|
-
try {
|
|
1077
|
-
r = t.shouldRun(), r && (i = t.update(e));
|
|
1078
|
-
} catch (e) {
|
|
1079
|
-
let r = e;
|
|
1080
|
-
console.error(r.message, r), a = !0, n = r, this.emit("system-error", {
|
|
1081
|
-
system: t.name,
|
|
1082
|
-
error: r,
|
|
1083
|
-
phase: "run"
|
|
1084
|
-
});
|
|
1085
|
-
}
|
|
1086
|
-
this.emit(`system-${t.name}-finished`, {
|
|
1087
|
-
ran: i,
|
|
1088
|
-
shouldRun: r,
|
|
1089
|
-
failed: a
|
|
1090
|
-
});
|
|
1091
|
-
}), this.checkFreeBufferTimeout(t), { lastSystemError: n };
|
|
1436
|
+
let n = this.scheduler.update(this, e);
|
|
1437
|
+
return this.checkFreeBufferTimeout(t), n;
|
|
1092
1438
|
}
|
|
1093
1439
|
pause() {
|
|
1094
1440
|
this.paused = !0;
|
|
1095
1441
|
}
|
|
1442
|
+
get paused() {
|
|
1443
|
+
return this.isPaused;
|
|
1444
|
+
}
|
|
1445
|
+
set paused(e) {
|
|
1446
|
+
this.isPaused !== e && (this.isPaused = e, e && this.scheduler.pause?.(this));
|
|
1447
|
+
}
|
|
1448
|
+
prepareForSystemDispatch() {
|
|
1449
|
+
return this.dispatchAllowed ? (this.needsSpareBuffer && this.heap.ensureSpareBuffer(), !0) : !1;
|
|
1450
|
+
}
|
|
1451
|
+
get dispatchAllowed() {
|
|
1452
|
+
return !this.clearing && !this.destroyed;
|
|
1453
|
+
}
|
|
1096
1454
|
resume() {
|
|
1097
1455
|
this.paused = !1;
|
|
1098
1456
|
}
|
|
1099
1457
|
addEntityToEntityWorkerSystem(e, t) {
|
|
1100
1458
|
this.isBulkLoading || this.systems.forEach((n) => {
|
|
1101
|
-
(n instanceof
|
|
1459
|
+
(n instanceof D && n.options.components?.includes(t) || n instanceof j && this.componentAffectsEntityWorkerSystem(n, t)) && n.checkAddEntity(e);
|
|
1102
1460
|
});
|
|
1103
1461
|
}
|
|
1104
1462
|
removeEntityFromEntityWorkerSystem(e, t) {
|
|
1105
1463
|
this.isBulkLoading || this.systems.forEach((n) => {
|
|
1106
|
-
n instanceof
|
|
1464
|
+
n instanceof D && n.options.components?.includes(t) ? n.removeEntity(e) : n instanceof j && this.componentAffectsEntityWorkerSystem(n, t) && n.checkAddEntity(e);
|
|
1107
1465
|
});
|
|
1108
1466
|
}
|
|
1109
1467
|
componentAffectsEntityWorkerSystem(e, t) {
|
|
@@ -1113,10 +1471,10 @@ var j = class extends k {
|
|
|
1113
1471
|
destroy() {
|
|
1114
1472
|
this.destroyed ||= (this.systems.forEach((e) => {
|
|
1115
1473
|
e.destroy();
|
|
1116
|
-
}), !0);
|
|
1474
|
+
}), this.scheduler.destroy?.(this), !0);
|
|
1117
1475
|
}
|
|
1118
1476
|
};
|
|
1119
|
-
function
|
|
1477
|
+
function fe(e) {
|
|
1120
1478
|
let t = {
|
|
1121
1479
|
entities: [],
|
|
1122
1480
|
groupIndexes: [],
|
|
@@ -1129,28 +1487,279 @@ function H(e) {
|
|
|
1129
1487
|
return t;
|
|
1130
1488
|
}
|
|
1131
1489
|
//#endregion
|
|
1490
|
+
//#region src/scheduling/conflict-scheduler.ts
|
|
1491
|
+
var pe = class {
|
|
1492
|
+
compiled = Object.freeze({
|
|
1493
|
+
order: Object.freeze([]),
|
|
1494
|
+
batches: Object.freeze([])
|
|
1495
|
+
});
|
|
1496
|
+
registeredSystems = [];
|
|
1497
|
+
access = /* @__PURE__ */ new Map();
|
|
1498
|
+
nodes = /* @__PURE__ */ new Set();
|
|
1499
|
+
tails = /* @__PURE__ */ new Map();
|
|
1500
|
+
frontiers = /* @__PURE__ */ new Map();
|
|
1501
|
+
creators = /* @__PURE__ */ new Map();
|
|
1502
|
+
creationReaders = /* @__PURE__ */ new Map();
|
|
1503
|
+
exclusiveTail;
|
|
1504
|
+
running = /* @__PURE__ */ new Map();
|
|
1505
|
+
ready = [];
|
|
1506
|
+
readyIndex = 0;
|
|
1507
|
+
gameTime = 0;
|
|
1508
|
+
pumping = !1;
|
|
1509
|
+
resumeQueued = !1;
|
|
1510
|
+
continuationTimer;
|
|
1511
|
+
generation = 0;
|
|
1512
|
+
publications = /* @__PURE__ */ new Set();
|
|
1513
|
+
publicationReady = [];
|
|
1514
|
+
publishing = !1;
|
|
1515
|
+
get schedule() {
|
|
1516
|
+
return this.compiled;
|
|
1517
|
+
}
|
|
1518
|
+
rebuild(e) {
|
|
1519
|
+
let t = Array.from(new Set(e.systems)), n = t.map((e) => {
|
|
1520
|
+
let t = e.readComponents, n = e.creationReadQueries;
|
|
1521
|
+
return {
|
|
1522
|
+
reads: new Set(t),
|
|
1523
|
+
creationReads: new Set(n === void 0 ? e.creationReadComponents : e.reads),
|
|
1524
|
+
creationQueries: n?.map((e) => Array.from(e)),
|
|
1525
|
+
writes: new Set(e.writes),
|
|
1526
|
+
creates: new Set(e.createdComponents),
|
|
1527
|
+
exclusive: e.requiresExclusiveScheduling || t === void 0 || e.writes === void 0
|
|
1528
|
+
};
|
|
1529
|
+
});
|
|
1530
|
+
this.access = new Map(t.map((e, t) => [e, n[t]]));
|
|
1531
|
+
let r = [], i = [];
|
|
1532
|
+
for (let e = 0; e < t.length; e++) {
|
|
1533
|
+
let a = 0;
|
|
1534
|
+
for (let t = 0; t < e; t++) this.conflicts(n[t], n[e]) && (a = Math.max(a, i[t] + 1));
|
|
1535
|
+
i.push(a), (r[a] ??= []).push(t[e]);
|
|
1536
|
+
}
|
|
1537
|
+
return this.registeredSystems = e.systems.slice(), this.compiled = Object.freeze({
|
|
1538
|
+
order: Object.freeze(r.flat()),
|
|
1539
|
+
batches: Object.freeze(r.map((e) => Object.freeze(e)))
|
|
1540
|
+
}), this.compiled;
|
|
1541
|
+
}
|
|
1542
|
+
systemAdded(e) {
|
|
1543
|
+
this.rebuild(e);
|
|
1544
|
+
}
|
|
1545
|
+
systemRemoved(e) {
|
|
1546
|
+
this.rebuild(e);
|
|
1547
|
+
}
|
|
1548
|
+
update(e, t) {
|
|
1549
|
+
if (this.pumping) throw Error("ConflictScheduler does not support reentrant updates");
|
|
1550
|
+
this.refreshMembership(e), this.gameTime = e.gameTime ?? this.gameTime + t;
|
|
1551
|
+
for (let n of new Set(e.systems)) this.enqueue(n, this.access.get(n), t, this.gameTime);
|
|
1552
|
+
return this.pump(e, !0);
|
|
1553
|
+
}
|
|
1554
|
+
runCompleted(e, t) {
|
|
1555
|
+
let n = this.running.get(t);
|
|
1556
|
+
if (!n || (this.complete(n), this.pumping || this.resumeQueued)) return;
|
|
1557
|
+
this.resumeQueued = !0;
|
|
1558
|
+
let r = this.generation;
|
|
1559
|
+
queueMicrotask(() => {
|
|
1560
|
+
r === this.generation && (this.resumeQueued = !1, this.pump(e, !1));
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
pause(e) {
|
|
1564
|
+
this.scheduleContinuation(e);
|
|
1565
|
+
}
|
|
1566
|
+
scheduleContinuation(e) {
|
|
1567
|
+
if (this.continuationTimer !== void 0 || !e.paused || !this.dispatchAllowed(e) || !Array.from(this.running.values()).some((e) => this.isSliced(e))) return;
|
|
1568
|
+
let t = this.generation;
|
|
1569
|
+
this.continuationTimer = setTimeout(() => {
|
|
1570
|
+
t === this.generation && (this.continuationTimer = void 0, e.paused && this.pump(e, "sliced"));
|
|
1571
|
+
}, 0);
|
|
1572
|
+
}
|
|
1573
|
+
isSliced(e) {
|
|
1574
|
+
return e.system instanceof E && e.system.remainingInstancesToRun.length > 0;
|
|
1575
|
+
}
|
|
1576
|
+
reset() {
|
|
1577
|
+
this.continuationTimer !== void 0 && (clearTimeout(this.continuationTimer), this.continuationTimer = void 0);
|
|
1578
|
+
let e = Array.from(this.publications, (e) => e.effects);
|
|
1579
|
+
this.publications.clear(), this.publicationReady = [], this.nodes.clear(), this.tails.clear(), this.frontiers.clear(), this.creators.clear(), this.creationReaders.clear(), this.exclusiveTail = void 0, this.running.clear(), this.ready = [], this.readyIndex = 0, this.gameTime = 0, this.resumeQueued = !1, this.generation++, e.forEach((e) => e.discard());
|
|
1580
|
+
}
|
|
1581
|
+
beforeClear() {
|
|
1582
|
+
this.reset();
|
|
1583
|
+
}
|
|
1584
|
+
prepareEffects(e, t) {
|
|
1585
|
+
let n = this.running.get(t), r = this.generation;
|
|
1586
|
+
return (e) => {
|
|
1587
|
+
if (!n || r !== this.generation || !this.nodes.has(n)) {
|
|
1588
|
+
e.discard();
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
n.effects = e, this.publications.add(n), n.publicationDependencies === 0 && this.publicationReady.push(n), this.publish();
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
publish() {
|
|
1595
|
+
if (this.publishing) return;
|
|
1596
|
+
this.publishing = !0;
|
|
1597
|
+
let e = this.generation;
|
|
1598
|
+
try {
|
|
1599
|
+
for (; this.publicationReady.length && e === this.generation;) {
|
|
1600
|
+
let e = this.publicationReady.pop();
|
|
1601
|
+
this.publications.delete(e);
|
|
1602
|
+
let t = e.effects;
|
|
1603
|
+
e.effects = void 0, t.apply();
|
|
1604
|
+
}
|
|
1605
|
+
} finally {
|
|
1606
|
+
this.publishing = !1;
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
destroy() {
|
|
1610
|
+
this.reset();
|
|
1611
|
+
}
|
|
1612
|
+
refreshMembership(e) {
|
|
1613
|
+
(e.systems.length !== this.registeredSystems.length || e.systems.some((e, t) => e !== this.registeredSystems[t])) && this.rebuild(e);
|
|
1614
|
+
}
|
|
1615
|
+
pump(e, t) {
|
|
1616
|
+
this.pumping = !0;
|
|
1617
|
+
let n = null, r = this.generation;
|
|
1618
|
+
try {
|
|
1619
|
+
if (t) for (let i of Array.from(this.running.values())) {
|
|
1620
|
+
if (!i.system.isCurrentlyRunning() || t === "sliced" && !this.isSliced(i)) continue;
|
|
1621
|
+
if (!this.prepare(e)) return { lastSystemError: n };
|
|
1622
|
+
let a = this.dispatch(e, i, !0);
|
|
1623
|
+
if (n = a?.lastSystemError ?? n, !a || r !== this.generation) return { lastSystemError: n };
|
|
1624
|
+
}
|
|
1625
|
+
for (; this.readyIndex < this.ready.length && r === this.generation && this.prepare(e);) {
|
|
1626
|
+
let t = this.ready[this.readyIndex++], r = this.dispatch(e, t, !1);
|
|
1627
|
+
if (n = r?.lastSystemError ?? n, !r) {
|
|
1628
|
+
this.nodes.has(t) && t.state === "pending" && this.ready.push(t);
|
|
1629
|
+
break;
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
} finally {
|
|
1633
|
+
this.ready = this.ready.slice(this.readyIndex), this.readyIndex = 0, this.pumping = !1, this.scheduleContinuation(e);
|
|
1634
|
+
}
|
|
1635
|
+
return { lastSystemError: n };
|
|
1636
|
+
}
|
|
1637
|
+
enqueue(e, t, n, r) {
|
|
1638
|
+
let i = {
|
|
1639
|
+
system: e,
|
|
1640
|
+
access: t,
|
|
1641
|
+
elapsedTime: n,
|
|
1642
|
+
gameTime: r,
|
|
1643
|
+
state: "pending",
|
|
1644
|
+
dependencies: 0,
|
|
1645
|
+
dependents: [],
|
|
1646
|
+
publicationDependencies: 0,
|
|
1647
|
+
publicationDependents: []
|
|
1648
|
+
}, a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), s = (e) => {
|
|
1649
|
+
e && e.state !== "complete" && a.add(e);
|
|
1650
|
+
};
|
|
1651
|
+
if (s(this.tails.get(e)), s(this.exclusiveTail), t.exclusive) this.tails.forEach(s), this.exclusiveTail = i;
|
|
1652
|
+
else {
|
|
1653
|
+
let n = (e) => {
|
|
1654
|
+
e && e.state !== "complete" && o.add(e);
|
|
1655
|
+
};
|
|
1656
|
+
for (let e of t.creates) {
|
|
1657
|
+
let t = this.frontier(e);
|
|
1658
|
+
n(t.writer), n(t.creator);
|
|
1659
|
+
}
|
|
1660
|
+
if (t.creates.size) for (let e of this.creationReaders.values()) this.observesCreation(t, e.access) && n(e);
|
|
1661
|
+
for (let n of t.reads) if (!t.writes.has(n)) {
|
|
1662
|
+
let t = this.frontier(n);
|
|
1663
|
+
s(t.writer), t.readers.set(e, i);
|
|
1664
|
+
}
|
|
1665
|
+
for (let e of this.creators.values()) this.observesCreation(e.access, t) && s(e);
|
|
1666
|
+
(t.creationReads.size || t.creationQueries?.length) && this.creationReaders.set(t, i);
|
|
1667
|
+
for (let e of t.writes) {
|
|
1668
|
+
let t = this.frontier(e);
|
|
1669
|
+
s(t.writer), s(t.creator), t.readers.forEach(s), t.readers.clear(), t.writer = i;
|
|
1670
|
+
}
|
|
1671
|
+
for (let e of t.creates) this.frontier(e).creator = i;
|
|
1672
|
+
t.creates.size && this.creators.set(t, i);
|
|
1673
|
+
}
|
|
1674
|
+
for (let e of a) e.dependents.push(i);
|
|
1675
|
+
i.dependencies = a.size;
|
|
1676
|
+
for (let e of o) e.publicationDependents.push(i);
|
|
1677
|
+
i.publicationDependencies = o.size, this.nodes.add(i), this.tails.set(e, i), i.dependencies || this.ready.push(i);
|
|
1678
|
+
}
|
|
1679
|
+
frontier(e) {
|
|
1680
|
+
let t = this.frontiers.get(e);
|
|
1681
|
+
return t || (t = { readers: /* @__PURE__ */ new Map() }, this.frontiers.set(e, t)), t;
|
|
1682
|
+
}
|
|
1683
|
+
complete(e) {
|
|
1684
|
+
if (e.state !== "complete") {
|
|
1685
|
+
e.state = "complete", this.nodes.delete(e), this.running.delete(e.system), this.tails.get(e.system) === e && this.tails.delete(e.system), this.exclusiveTail === e && (this.exclusiveTail = void 0), this.creators.get(e.access) === e && this.creators.delete(e.access), this.creationReaders.get(e.access) === e && this.creationReaders.delete(e.access);
|
|
1686
|
+
for (let t of /* @__PURE__ */ new Set([
|
|
1687
|
+
...e.access.reads,
|
|
1688
|
+
...e.access.writes,
|
|
1689
|
+
...e.access.creates
|
|
1690
|
+
])) {
|
|
1691
|
+
let n = this.frontiers.get(t);
|
|
1692
|
+
n?.writer === e && (n.writer = void 0), n?.creator === e && (n.creator = void 0), n?.readers.get(e.system) === e && n.readers.delete(e.system), n && !n.writer && !n.creator && !n.readers.size && this.frontiers.delete(t);
|
|
1693
|
+
}
|
|
1694
|
+
for (let t of e.dependents) --t.dependencies === 0 && this.ready.push(t);
|
|
1695
|
+
e.dependents.length = 0;
|
|
1696
|
+
for (let t of e.publicationDependents) t.publicationDependencies--, t.publicationDependencies === 0 && t.effects && this.publicationReady.push(t);
|
|
1697
|
+
e.publicationDependents.length = 0, this.publish();
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
dispatch(e, t, n) {
|
|
1701
|
+
let r = t.system;
|
|
1702
|
+
if (!n && !e.systems.includes(r)) return this.complete(t), {};
|
|
1703
|
+
let i = this.generation, a = !0, o = !1, s = !1, c = null;
|
|
1704
|
+
if (e.emit(`system-${r.name}-started`), this.nodes.has(t) && this.dispatchAllowed(e)) {
|
|
1705
|
+
try {
|
|
1706
|
+
if (!r.withGameTime(t.gameTime, () => (a = n || r.shouldRun(), !this.nodes.has(t) || !this.dispatchAllowed(e) ? !1 : (a ? (t.state = "running", this.running.set(r, t), o = r.update(n ? 0 : t.elapsedTime), i === this.generation && !r.isCurrentlyRunning() && this.complete(t)) : this.complete(t), !0)))) return;
|
|
1707
|
+
} catch (n) {
|
|
1708
|
+
let a = n;
|
|
1709
|
+
console.error(a.message, a), s = !0, c = a, i === this.generation && (r.isCurrentlyRunning() ? (t.state = "running", this.running.set(r, t)) : this.complete(t)), e.emit("system-error", {
|
|
1710
|
+
system: r.name,
|
|
1711
|
+
error: a,
|
|
1712
|
+
phase: "run"
|
|
1713
|
+
});
|
|
1714
|
+
}
|
|
1715
|
+
return e.emit(`system-${r.name}-finished`, {
|
|
1716
|
+
ran: o,
|
|
1717
|
+
shouldRun: a,
|
|
1718
|
+
failed: s
|
|
1719
|
+
}), { lastSystemError: c };
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
prepare(e) {
|
|
1723
|
+
return this.dispatchAllowed(e) && e.prepareForSystemDispatch?.() !== !1;
|
|
1724
|
+
}
|
|
1725
|
+
dispatchAllowed(e) {
|
|
1726
|
+
return e.dispatchAllowed !== !1;
|
|
1727
|
+
}
|
|
1728
|
+
observesCreation(e, t) {
|
|
1729
|
+
for (let n of t.creationReads) if (e.creates.has(n)) return !0;
|
|
1730
|
+
return t.creationQueries?.some((t) => t.every((t) => e.creates.has(t))) ?? !1;
|
|
1731
|
+
}
|
|
1732
|
+
conflicts(e, t) {
|
|
1733
|
+
if (e.exclusive || t.exclusive) return !0;
|
|
1734
|
+
for (let n of e.writes) if (t.reads.has(n) || t.writes.has(n)) return !0;
|
|
1735
|
+
for (let n of t.writes) if (e.reads.has(n)) return !0;
|
|
1736
|
+
for (let n of e.creates) if (t.writes.has(n)) return !0;
|
|
1737
|
+
return e.creates.size > 0 && this.observesCreation(e, t);
|
|
1738
|
+
}
|
|
1739
|
+
};
|
|
1740
|
+
//#endregion
|
|
1132
1741
|
//#region src/entity-class.ts
|
|
1133
|
-
function
|
|
1742
|
+
function me(e, t) {
|
|
1134
1743
|
return t;
|
|
1135
1744
|
}
|
|
1136
|
-
function
|
|
1745
|
+
function Z(e, t) {
|
|
1137
1746
|
return t;
|
|
1138
1747
|
}
|
|
1139
1748
|
//#endregion
|
|
1140
1749
|
//#region src/actions/kill-entity.ts
|
|
1141
|
-
function
|
|
1750
|
+
function he(e) {
|
|
1142
1751
|
e.components.entity.dead = !0, e.emit("death");
|
|
1143
1752
|
}
|
|
1144
1753
|
//#endregion
|
|
1145
1754
|
//#region src/performance-timing.ts
|
|
1146
|
-
var
|
|
1755
|
+
var ge = 1e3, Q = {
|
|
1147
1756
|
avg: 0,
|
|
1148
1757
|
min: 0,
|
|
1149
1758
|
max: 0,
|
|
1150
1759
|
samples: 0
|
|
1151
1760
|
};
|
|
1152
|
-
function
|
|
1153
|
-
if (!e.length) return { ...
|
|
1761
|
+
function $(e) {
|
|
1762
|
+
if (!e.length) return { ...Q };
|
|
1154
1763
|
let t = 0, n = Infinity, r = 0;
|
|
1155
1764
|
for (let i of e) t += i, i < n && (n = i), i > r && (r = i);
|
|
1156
1765
|
return {
|
|
@@ -1160,13 +1769,13 @@ function J(e) {
|
|
|
1160
1769
|
samples: e.length
|
|
1161
1770
|
};
|
|
1162
1771
|
}
|
|
1163
|
-
var
|
|
1772
|
+
var _e = class extends C.default {
|
|
1164
1773
|
world;
|
|
1165
1774
|
ticksBetweenUpdates;
|
|
1166
1775
|
stats = {
|
|
1167
|
-
update: { ...
|
|
1776
|
+
update: { ...Q },
|
|
1168
1777
|
systems: [],
|
|
1169
|
-
events: { ...
|
|
1778
|
+
events: { ...Q }
|
|
1170
1779
|
};
|
|
1171
1780
|
autoUpdate;
|
|
1172
1781
|
ticks = 0;
|
|
@@ -1182,11 +1791,11 @@ var Y = class extends O.default {
|
|
|
1182
1791
|
}
|
|
1183
1792
|
reset() {
|
|
1184
1793
|
this.ticks = 0, this.updateTimes = [], this.systemTimings.forEach((e) => {
|
|
1185
|
-
e.run = [], e.events = [], e.eventStart = -1;
|
|
1794
|
+
e.run = [], e.events = [], e.eventStart = -1, e.pendingRun = 0, e.pendingEvents = 0;
|
|
1186
1795
|
}), this.stats = {
|
|
1187
|
-
update: { ...
|
|
1796
|
+
update: { ...Q },
|
|
1188
1797
|
systems: [],
|
|
1189
|
-
events: { ...
|
|
1798
|
+
events: { ...Q }
|
|
1190
1799
|
};
|
|
1191
1800
|
}
|
|
1192
1801
|
destroy() {
|
|
@@ -1210,11 +1819,13 @@ var Y = class extends O.default {
|
|
|
1210
1819
|
run: [],
|
|
1211
1820
|
events: [],
|
|
1212
1821
|
eventStart: -1,
|
|
1213
|
-
|
|
1214
|
-
|
|
1822
|
+
pendingRun: 0,
|
|
1823
|
+
pendingEvents: 0,
|
|
1824
|
+
onRunFinished: (e, n) => {
|
|
1825
|
+
(!n || n.first) && (t.pendingRun = 0, t.pendingEvents = 0), t.pendingRun += e, (!n || n.last) && (t.run.push(t.pendingRun), t.pendingRun = 0), t.eventStart = performance.now();
|
|
1215
1826
|
},
|
|
1216
|
-
onEventsFinished: () => {
|
|
1217
|
-
t.eventStart < 0 || (t.
|
|
1827
|
+
onEventsFinished: (e, n) => {
|
|
1828
|
+
t.eventStart < 0 || (t.pendingEvents += performance.now() - t.eventStart, (!n || n.last) && (t.events.push(t.pendingEvents), t.pendingEvents = 0), t.eventStart = -1);
|
|
1218
1829
|
}
|
|
1219
1830
|
};
|
|
1220
1831
|
this.world.on(`system-${e.name}-worker-finished`, t.onRunFinished), this.world.on(`system-${e.name}-worker-events-finished`, t.onEventsFinished), this.systemTimings.set(e.name, t);
|
|
@@ -1229,21 +1840,21 @@ var Y = class extends O.default {
|
|
|
1229
1840
|
let t = this.systemTimings.get(e.name);
|
|
1230
1841
|
return {
|
|
1231
1842
|
name: e.name,
|
|
1232
|
-
run:
|
|
1233
|
-
events:
|
|
1843
|
+
run: $(t?.run ?? []),
|
|
1844
|
+
events: $(t?.events ?? [])
|
|
1234
1845
|
};
|
|
1235
|
-
}), t = { ...
|
|
1846
|
+
}), t = { ...Q };
|
|
1236
1847
|
return e.forEach((e) => {
|
|
1237
1848
|
t.avg += e.events.avg, t.min += e.events.min, t.max += e.events.max, t.samples += e.events.samples;
|
|
1238
1849
|
}), this.stats = {
|
|
1239
|
-
update:
|
|
1850
|
+
update: $(this.updateTimes),
|
|
1240
1851
|
systems: e,
|
|
1241
1852
|
events: t
|
|
1242
1853
|
}, this.ticks = 0, this.updateTimes = [], this.systemTimings.forEach((e) => {
|
|
1243
1854
|
e.run = [], e.events = [];
|
|
1244
1855
|
}), this.emit("stats-updated", this.stats), this.stats;
|
|
1245
1856
|
}
|
|
1246
|
-
},
|
|
1857
|
+
}, ve = class extends j {
|
|
1247
1858
|
constructor(e, t) {
|
|
1248
1859
|
super(e, {
|
|
1249
1860
|
...t,
|
|
@@ -1259,6 +1870,6 @@ var Y = class extends O.default {
|
|
|
1259
1870
|
}
|
|
1260
1871
|
};
|
|
1261
1872
|
//#endregion
|
|
1262
|
-
export {
|
|
1873
|
+
export { M as BaseEntity, de as BaseWorld, n as CLASS_INDEX, f as Component, pe as ConflictScheduler, h as ConstantStringCache, c as DEAD_INDEX, ge as DEFAULT_TICKS_BETWEEN_UPDATES, Y as DefaultScheduler, G as EntityCompressor, N as EntityFactory, D as EntitySystem, k as EntitySystemWebWorker, j as EntityWorkerSystem, E as IterableSystem, g as MemoryComponent, _e as PerformanceTiming, te as STATIC_INDEX, w as System, r as TYPE_INDEX, O as WebWorker, ve as WorkerSystem, t as addComponentWorker, ce as compressEntities, p as createEntitySystemWorker, d as createEntityWorker, ee as createSystemWorker, J as decompressEntities, q as decompressEntity, me as defineEntityClasses, Z as defineEntityConfigs, i as entityDefinition, he as killEntity, m as killEntityWorker, s as removeComponentWorker };
|
|
1263
1874
|
|
|
1264
1875
|
//# sourceMappingURL=index.js.map
|