@daneren2005/shared-memory-ecs 1.8.1 → 1.9.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 +257 -16
- 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/index.d.ts +6 -2
- package/dist/index.js +675 -215
- package/dist/index.js.map +1 -1
- package/dist/performance-timing.d.ts +3 -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 +11 -5
- package/package.json +6 -6
- 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 h, u as g, v as _ } from "./create-system-worker-
|
|
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 h, u as g, v as _, y as v } from "./create-system-worker-CNpRs2FO.js";
|
|
2
|
+
import y from "@daneren2005/shared-memory-objects/memory-heap";
|
|
3
|
+
import { MAX_BYTE_OFFSET_LENGTH as b } 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 x = Object.create, S = Object.defineProperty, C = Object.getOwnPropertyDescriptor, w = Object.getOwnPropertyNames, T = Object.getPrototypeOf, E = Object.prototype.hasOwnProperty, D = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t.exports), O = (e, t, n, r) => {
|
|
6
|
+
if (t && typeof t == "object" || typeof t == "function") for (var i = w(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !E.call(e, s) && s !== n && S(e, s, {
|
|
7
7
|
get: ((e) => t[e]).bind(null, s),
|
|
8
|
-
enumerable: !(r =
|
|
8
|
+
enumerable: !(r = C(t, s)) || r.enumerable
|
|
9
9
|
});
|
|
10
10
|
return e;
|
|
11
|
-
},
|
|
11
|
+
}, k = /* @__PURE__ */ ((e, t, n) => (n = e == null ? {} : x(T(e)), O(t || !e || !e.__esModule || !E.call(e, "default") ? S(n, "default", {
|
|
12
12
|
value: e,
|
|
13
13
|
enumerable: !0
|
|
14
|
-
}) : n, e)))((/* @__PURE__ */
|
|
14
|
+
}) : n, e)))((/* @__PURE__ */ D(((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), A = class extends k.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 j(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 M = class extends A {
|
|
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
|
+
}, N = class e extends M {
|
|
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
|
+
j(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
|
+
}, P = class {
|
|
259
304
|
onmessage(e, t = []) {}
|
|
260
|
-
},
|
|
305
|
+
}, F = class extends P {
|
|
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
|
+
}, I = "___main", L = class e extends A {
|
|
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 F(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 F)) {
|
|
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(I, 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(I, 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(I, 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(I, 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
|
+
j(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(I, 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
|
+
}, R = class extends k.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
|
+
}, z = 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 !== R && !(n.prototype instanceof R)) 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 R(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 R(this.world, e);
|
|
803
984
|
}
|
|
804
985
|
get hasClasses() {
|
|
805
986
|
return this.allowedComponents.size > 0;
|
|
@@ -864,7 +1045,30 @@ 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
|
+
}, B = class {
|
|
1049
|
+
update(e, t) {
|
|
1050
|
+
let n = null;
|
|
1051
|
+
return e.systems.forEach((r) => {
|
|
1052
|
+
let i = !0, a = !1, o = !1;
|
|
1053
|
+
e.emit(`system-${r.name}-started`);
|
|
1054
|
+
try {
|
|
1055
|
+
i = r.shouldRun(), i && (a = r.update(t));
|
|
1056
|
+
} catch (t) {
|
|
1057
|
+
let i = t;
|
|
1058
|
+
console.error(i.message, i), o = !0, n = i, e.emit("system-error", {
|
|
1059
|
+
system: r.name,
|
|
1060
|
+
error: i,
|
|
1061
|
+
phase: "run"
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
e.emit(`system-${r.name}-finished`, {
|
|
1065
|
+
ran: a,
|
|
1066
|
+
shouldRun: i,
|
|
1067
|
+
failed: o
|
|
1068
|
+
});
|
|
1069
|
+
}), { lastSystemError: n };
|
|
1070
|
+
}
|
|
1071
|
+
}, V = b, H = 1e4, U = class extends k.default {
|
|
868
1072
|
heap;
|
|
869
1073
|
constantStrings;
|
|
870
1074
|
eidCounter;
|
|
@@ -872,10 +1076,11 @@ var j = class extends k {
|
|
|
872
1076
|
factory;
|
|
873
1077
|
entities = /* @__PURE__ */ new Map();
|
|
874
1078
|
systems = [];
|
|
1079
|
+
scheduler;
|
|
875
1080
|
gameTime = 0;
|
|
876
1081
|
playerTime = 0;
|
|
877
1082
|
timeScale = 1;
|
|
878
|
-
|
|
1083
|
+
isPaused = !1;
|
|
879
1084
|
destroyed = !1;
|
|
880
1085
|
pristine = !0;
|
|
881
1086
|
isBulkLoading = !1;
|
|
@@ -889,20 +1094,21 @@ var j = class extends k {
|
|
|
889
1094
|
waitingSystems: /* @__PURE__ */ new Set(),
|
|
890
1095
|
waitElapsed: 0
|
|
891
1096
|
};
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1097
|
+
clearing = !1;
|
|
1098
|
+
constructor(e, t = {}) {
|
|
1099
|
+
super(), this.scheduler = t.scheduler ?? new B(), this.heap = new y({ bufferSize: t.heapSize ?? V }), this.constantStrings = new _(this.heap), this.eidCounter = this.heap.allocUI32(1), this.heap.addOnGrowBufferHandlers((e) => this.emit("grow-buffer", e));
|
|
1100
|
+
let n = {
|
|
1101
|
+
...e,
|
|
896
1102
|
entity: i
|
|
897
|
-
},
|
|
898
|
-
for (let e of Object.keys(
|
|
899
|
-
let t =
|
|
900
|
-
|
|
1103
|
+
}, r = {};
|
|
1104
|
+
for (let e of Object.keys(n)) {
|
|
1105
|
+
let t = n[e];
|
|
1106
|
+
r[e] = {
|
|
901
1107
|
...t,
|
|
902
|
-
memoryComponent: new
|
|
1108
|
+
memoryComponent: new v(this.heap, t.type, t.size)
|
|
903
1109
|
};
|
|
904
1110
|
}
|
|
905
|
-
this.registry =
|
|
1111
|
+
this.registry = r, this.factory = t.factory ?? new z(), this.factory.setWorld(this);
|
|
906
1112
|
}
|
|
907
1113
|
allocateEid() {
|
|
908
1114
|
return Atomics.add(this.eidCounter.data, 0, 1) + 1;
|
|
@@ -919,13 +1125,13 @@ var j = class extends k {
|
|
|
919
1125
|
this.heap.buffers[e.bufferPosition] === void 0 && this.heap.addSharedBuffer(e), this.emit("grow-buffer", e);
|
|
920
1126
|
}
|
|
921
1127
|
get needsSpareBuffer() {
|
|
922
|
-
return this.systems.some((e) => e instanceof
|
|
1128
|
+
return this.systems.some((e) => e instanceof L && e.isWorkerThread && (!!e.options.createsEntities || !!e.options.addsComponents));
|
|
923
1129
|
}
|
|
924
1130
|
async init() {
|
|
925
1131
|
await Promise.all(this.systems.map((e) => e.init()).filter((e) => e instanceof Promise));
|
|
926
1132
|
}
|
|
927
|
-
finishLoadingSystems() {
|
|
928
|
-
|
|
1133
|
+
async finishLoadingSystems() {
|
|
1134
|
+
await Promise.all(this.systems.map((e) => e.finishLoading()).filter((e) => e instanceof Promise));
|
|
929
1135
|
}
|
|
930
1136
|
addEntity(e, t = !0) {
|
|
931
1137
|
return this.entities.set(e.eid, e), e.world = this, this.pristine = !1, e.on("component-added", (t) => {
|
|
@@ -960,9 +1166,9 @@ var j = class extends k {
|
|
|
960
1166
|
}
|
|
961
1167
|
}
|
|
962
1168
|
load(e) {
|
|
963
|
-
if (!this.pristine) {
|
|
1169
|
+
if (!this.pristine || this.scheduler.prepareEffects && this.systems.some((e) => e.isCurrentlyRunning())) {
|
|
964
1170
|
for (let e of Array.from(this.entities.values())) this.removeEntity(e);
|
|
965
|
-
this.systems.forEach((e) => e.clear()), this.consolidateFreeBuffersForReload();
|
|
1171
|
+
this.systems.forEach((e) => e.clear()), this.scheduler.reset?.(this), this.consolidateFreeBuffersForReload();
|
|
966
1172
|
}
|
|
967
1173
|
for (let e of Object.keys(this.factory.configs)) this.constantStrings.getOrCreate(e);
|
|
968
1174
|
for (let e of Object.keys(this.factory.classes)) this.constantStrings.getOrCreate(e);
|
|
@@ -975,14 +1181,19 @@ var j = class extends k {
|
|
|
975
1181
|
} finally {
|
|
976
1182
|
this.isBulkLoading = !1;
|
|
977
1183
|
}
|
|
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();
|
|
1184
|
+
let t = W(this.entities.values());
|
|
1185
|
+
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
1186
|
}
|
|
981
1187
|
async clear() {
|
|
982
|
-
if (!this.pristine) {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1188
|
+
if (!this.pristine || this.scheduler.beforeClear) {
|
|
1189
|
+
this.clearing = !0;
|
|
1190
|
+
try {
|
|
1191
|
+
this.scheduler.beforeClear?.(this), await Promise.all(this.systems.map((e) => e.waitForRunToComplete()).filter((e) => e instanceof Promise));
|
|
1192
|
+
for (let e of Array.from(this.entities.values())) this.removeEntity(e);
|
|
1193
|
+
this.systems.forEach((e) => e.clear()), this.scheduler.reset?.(this), this.freeAllPendingBuffers(), this.pristine = !0;
|
|
1194
|
+
} finally {
|
|
1195
|
+
this.clearing = !1;
|
|
1196
|
+
}
|
|
986
1197
|
}
|
|
987
1198
|
}
|
|
988
1199
|
removeEntity(e) {
|
|
@@ -1018,7 +1229,7 @@ var j = class extends k {
|
|
|
1018
1229
|
});
|
|
1019
1230
|
}
|
|
1020
1231
|
notifySystemRunCompleted(e) {
|
|
1021
|
-
this.activeFreeBuffer.waitingSystems.delete(e) && this.activeFreeBuffer.waitingSystems.size === 0 && this.processFreeBuffers();
|
|
1232
|
+
this.activeFreeBuffer.waitingSystems.delete(e) && this.activeFreeBuffer.waitingSystems.size === 0 && this.processFreeBuffers(), this.scheduler.runCompleted?.(this, e);
|
|
1022
1233
|
}
|
|
1023
1234
|
processFreeBuffers() {
|
|
1024
1235
|
for (; this.activeFreeBuffer.waitingSystems.size === 0 && (this.activeFreeBuffer.frees.length > 0 && this.performFrees(this.activeFreeBuffer), this.nextFreeBuffer.frees.length !== 0);) this.promoteNextFreeBuffer();
|
|
@@ -1042,22 +1253,22 @@ var j = class extends k {
|
|
|
1042
1253
|
}
|
|
1043
1254
|
checkFreeBufferTimeout(e) {
|
|
1044
1255
|
let t = this.activeFreeBuffer;
|
|
1045
|
-
if (t.waitingSystems.size !== 0 && (t.waitElapsed += e, t.waitElapsed >=
|
|
1256
|
+
if (t.waitingSystems.size !== 0 && (t.waitElapsed += e, t.waitElapsed >= H)) {
|
|
1046
1257
|
let e = Array.from(t.waitingSystems).map((e) => e.name).join(", ");
|
|
1047
|
-
console.warn(`shared-memory-ecs: deferred component free waited over ${
|
|
1258
|
+
console.warn(`shared-memory-ecs: deferred component free waited over ${H}ms on system(s): ${e}; freeing anyway`), t.waitingSystems.clear(), this.processFreeBuffers();
|
|
1048
1259
|
}
|
|
1049
1260
|
}
|
|
1050
1261
|
addSystem(e) {
|
|
1051
|
-
return this.systems.push(e), this.emit("system-added", e), e;
|
|
1262
|
+
return this.systems.push(e), this.scheduler.systemAdded?.(this, e), this.emit("system-added", e), e;
|
|
1052
1263
|
}
|
|
1053
1264
|
addSystemIfNotExists(e) {
|
|
1054
|
-
this.systems.findIndex((t) => e.name === t.name) === -1 && (this.systems.push(e), this.emit("system-added", e));
|
|
1265
|
+
this.systems.findIndex((t) => e.name === t.name) === -1 && (this.systems.push(e), this.scheduler.systemAdded?.(this, e), this.emit("system-added", e));
|
|
1055
1266
|
}
|
|
1056
1267
|
removeSystem(e) {
|
|
1057
1268
|
let t = this.systems.findIndex((t) => t.name === e);
|
|
1058
1269
|
if (t !== -1) {
|
|
1059
1270
|
let [e] = this.systems.splice(t, 1);
|
|
1060
|
-
this.emit("system-removed", e);
|
|
1271
|
+
this.scheduler.systemRemoved?.(this, e), this.emit("system-removed", e);
|
|
1061
1272
|
}
|
|
1062
1273
|
}
|
|
1063
1274
|
update(e) {
|
|
@@ -1069,41 +1280,35 @@ var j = class extends k {
|
|
|
1069
1280
|
if (this.playerTime += e, this.paused) return {};
|
|
1070
1281
|
let t = e;
|
|
1071
1282
|
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 };
|
|
1283
|
+
let n = this.scheduler.update(this, e);
|
|
1284
|
+
return this.checkFreeBufferTimeout(t), n;
|
|
1092
1285
|
}
|
|
1093
1286
|
pause() {
|
|
1094
1287
|
this.paused = !0;
|
|
1095
1288
|
}
|
|
1289
|
+
get paused() {
|
|
1290
|
+
return this.isPaused;
|
|
1291
|
+
}
|
|
1292
|
+
set paused(e) {
|
|
1293
|
+
this.isPaused !== e && (this.isPaused = e, e && this.scheduler.pause?.(this));
|
|
1294
|
+
}
|
|
1295
|
+
prepareForSystemDispatch() {
|
|
1296
|
+
return this.dispatchAllowed ? (this.needsSpareBuffer && this.heap.ensureSpareBuffer(), !0) : !1;
|
|
1297
|
+
}
|
|
1298
|
+
get dispatchAllowed() {
|
|
1299
|
+
return !this.clearing && !this.destroyed;
|
|
1300
|
+
}
|
|
1096
1301
|
resume() {
|
|
1097
1302
|
this.paused = !1;
|
|
1098
1303
|
}
|
|
1099
1304
|
addEntityToEntityWorkerSystem(e, t) {
|
|
1100
1305
|
this.isBulkLoading || this.systems.forEach((n) => {
|
|
1101
|
-
(n instanceof
|
|
1306
|
+
(n instanceof N && n.options.components?.includes(t) || n instanceof L && this.componentAffectsEntityWorkerSystem(n, t)) && n.checkAddEntity(e);
|
|
1102
1307
|
});
|
|
1103
1308
|
}
|
|
1104
1309
|
removeEntityFromEntityWorkerSystem(e, t) {
|
|
1105
1310
|
this.isBulkLoading || this.systems.forEach((n) => {
|
|
1106
|
-
n instanceof
|
|
1311
|
+
n instanceof N && n.options.components?.includes(t) ? n.removeEntity(e) : n instanceof L && this.componentAffectsEntityWorkerSystem(n, t) && n.checkAddEntity(e);
|
|
1107
1312
|
});
|
|
1108
1313
|
}
|
|
1109
1314
|
componentAffectsEntityWorkerSystem(e, t) {
|
|
@@ -1113,10 +1318,10 @@ var j = class extends k {
|
|
|
1113
1318
|
destroy() {
|
|
1114
1319
|
this.destroyed ||= (this.systems.forEach((e) => {
|
|
1115
1320
|
e.destroy();
|
|
1116
|
-
}), !0);
|
|
1321
|
+
}), this.scheduler.destroy?.(this), !0);
|
|
1117
1322
|
}
|
|
1118
1323
|
};
|
|
1119
|
-
function
|
|
1324
|
+
function W(e) {
|
|
1120
1325
|
let t = {
|
|
1121
1326
|
entities: [],
|
|
1122
1327
|
groupIndexes: [],
|
|
@@ -1129,28 +1334,279 @@ function H(e) {
|
|
|
1129
1334
|
return t;
|
|
1130
1335
|
}
|
|
1131
1336
|
//#endregion
|
|
1337
|
+
//#region src/scheduling/conflict-scheduler.ts
|
|
1338
|
+
var G = class {
|
|
1339
|
+
compiled = Object.freeze({
|
|
1340
|
+
order: Object.freeze([]),
|
|
1341
|
+
batches: Object.freeze([])
|
|
1342
|
+
});
|
|
1343
|
+
registeredSystems = [];
|
|
1344
|
+
access = /* @__PURE__ */ new Map();
|
|
1345
|
+
nodes = /* @__PURE__ */ new Set();
|
|
1346
|
+
tails = /* @__PURE__ */ new Map();
|
|
1347
|
+
frontiers = /* @__PURE__ */ new Map();
|
|
1348
|
+
creators = /* @__PURE__ */ new Map();
|
|
1349
|
+
creationReaders = /* @__PURE__ */ new Map();
|
|
1350
|
+
exclusiveTail;
|
|
1351
|
+
running = /* @__PURE__ */ new Map();
|
|
1352
|
+
ready = [];
|
|
1353
|
+
readyIndex = 0;
|
|
1354
|
+
gameTime = 0;
|
|
1355
|
+
pumping = !1;
|
|
1356
|
+
resumeQueued = !1;
|
|
1357
|
+
continuationTimer;
|
|
1358
|
+
generation = 0;
|
|
1359
|
+
publications = /* @__PURE__ */ new Set();
|
|
1360
|
+
publicationReady = [];
|
|
1361
|
+
publishing = !1;
|
|
1362
|
+
get schedule() {
|
|
1363
|
+
return this.compiled;
|
|
1364
|
+
}
|
|
1365
|
+
rebuild(e) {
|
|
1366
|
+
let t = Array.from(new Set(e.systems)), n = t.map((e) => {
|
|
1367
|
+
let t = e.readComponents, n = e.creationReadQueries;
|
|
1368
|
+
return {
|
|
1369
|
+
reads: new Set(t),
|
|
1370
|
+
creationReads: new Set(n === void 0 ? e.creationReadComponents : e.reads),
|
|
1371
|
+
creationQueries: n?.map((e) => Array.from(e)),
|
|
1372
|
+
writes: new Set(e.writes),
|
|
1373
|
+
creates: new Set(e.createdComponents),
|
|
1374
|
+
exclusive: e.requiresExclusiveScheduling || t === void 0 || e.writes === void 0
|
|
1375
|
+
};
|
|
1376
|
+
});
|
|
1377
|
+
this.access = new Map(t.map((e, t) => [e, n[t]]));
|
|
1378
|
+
let r = [], i = [];
|
|
1379
|
+
for (let e = 0; e < t.length; e++) {
|
|
1380
|
+
let a = 0;
|
|
1381
|
+
for (let t = 0; t < e; t++) this.conflicts(n[t], n[e]) && (a = Math.max(a, i[t] + 1));
|
|
1382
|
+
i.push(a), (r[a] ??= []).push(t[e]);
|
|
1383
|
+
}
|
|
1384
|
+
return this.registeredSystems = e.systems.slice(), this.compiled = Object.freeze({
|
|
1385
|
+
order: Object.freeze(r.flat()),
|
|
1386
|
+
batches: Object.freeze(r.map((e) => Object.freeze(e)))
|
|
1387
|
+
}), this.compiled;
|
|
1388
|
+
}
|
|
1389
|
+
systemAdded(e) {
|
|
1390
|
+
this.rebuild(e);
|
|
1391
|
+
}
|
|
1392
|
+
systemRemoved(e) {
|
|
1393
|
+
this.rebuild(e);
|
|
1394
|
+
}
|
|
1395
|
+
update(e, t) {
|
|
1396
|
+
if (this.pumping) throw Error("ConflictScheduler does not support reentrant updates");
|
|
1397
|
+
this.refreshMembership(e), this.gameTime = e.gameTime ?? this.gameTime + t;
|
|
1398
|
+
for (let n of new Set(e.systems)) this.enqueue(n, this.access.get(n), t, this.gameTime);
|
|
1399
|
+
return this.pump(e, !0);
|
|
1400
|
+
}
|
|
1401
|
+
runCompleted(e, t) {
|
|
1402
|
+
let n = this.running.get(t);
|
|
1403
|
+
if (!n || (this.complete(n), this.pumping || this.resumeQueued)) return;
|
|
1404
|
+
this.resumeQueued = !0;
|
|
1405
|
+
let r = this.generation;
|
|
1406
|
+
queueMicrotask(() => {
|
|
1407
|
+
r === this.generation && (this.resumeQueued = !1, this.pump(e, !1));
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
pause(e) {
|
|
1411
|
+
this.scheduleContinuation(e);
|
|
1412
|
+
}
|
|
1413
|
+
scheduleContinuation(e) {
|
|
1414
|
+
if (this.continuationTimer !== void 0 || !e.paused || !this.dispatchAllowed(e) || !Array.from(this.running.values()).some((e) => this.isSliced(e))) return;
|
|
1415
|
+
let t = this.generation;
|
|
1416
|
+
this.continuationTimer = setTimeout(() => {
|
|
1417
|
+
t === this.generation && (this.continuationTimer = void 0, e.paused && this.pump(e, "sliced"));
|
|
1418
|
+
}, 0);
|
|
1419
|
+
}
|
|
1420
|
+
isSliced(e) {
|
|
1421
|
+
return e.system instanceof M && e.system.remainingInstancesToRun.length > 0;
|
|
1422
|
+
}
|
|
1423
|
+
reset() {
|
|
1424
|
+
this.continuationTimer !== void 0 && (clearTimeout(this.continuationTimer), this.continuationTimer = void 0);
|
|
1425
|
+
let e = Array.from(this.publications, (e) => e.effects);
|
|
1426
|
+
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());
|
|
1427
|
+
}
|
|
1428
|
+
beforeClear() {
|
|
1429
|
+
this.reset();
|
|
1430
|
+
}
|
|
1431
|
+
prepareEffects(e, t) {
|
|
1432
|
+
let n = this.running.get(t), r = this.generation;
|
|
1433
|
+
return (e) => {
|
|
1434
|
+
if (!n || r !== this.generation || !this.nodes.has(n)) {
|
|
1435
|
+
e.discard();
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
n.effects = e, this.publications.add(n), n.publicationDependencies === 0 && this.publicationReady.push(n), this.publish();
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
publish() {
|
|
1442
|
+
if (this.publishing) return;
|
|
1443
|
+
this.publishing = !0;
|
|
1444
|
+
let e = this.generation;
|
|
1445
|
+
try {
|
|
1446
|
+
for (; this.publicationReady.length && e === this.generation;) {
|
|
1447
|
+
let e = this.publicationReady.pop();
|
|
1448
|
+
this.publications.delete(e);
|
|
1449
|
+
let t = e.effects;
|
|
1450
|
+
e.effects = void 0, t.apply();
|
|
1451
|
+
}
|
|
1452
|
+
} finally {
|
|
1453
|
+
this.publishing = !1;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
destroy() {
|
|
1457
|
+
this.reset();
|
|
1458
|
+
}
|
|
1459
|
+
refreshMembership(e) {
|
|
1460
|
+
(e.systems.length !== this.registeredSystems.length || e.systems.some((e, t) => e !== this.registeredSystems[t])) && this.rebuild(e);
|
|
1461
|
+
}
|
|
1462
|
+
pump(e, t) {
|
|
1463
|
+
this.pumping = !0;
|
|
1464
|
+
let n = null, r = this.generation;
|
|
1465
|
+
try {
|
|
1466
|
+
if (t) for (let i of Array.from(this.running.values())) {
|
|
1467
|
+
if (!i.system.isCurrentlyRunning() || t === "sliced" && !this.isSliced(i)) continue;
|
|
1468
|
+
if (!this.prepare(e)) return { lastSystemError: n };
|
|
1469
|
+
let a = this.dispatch(e, i, !0);
|
|
1470
|
+
if (n = a?.lastSystemError ?? n, !a || r !== this.generation) return { lastSystemError: n };
|
|
1471
|
+
}
|
|
1472
|
+
for (; this.readyIndex < this.ready.length && r === this.generation && this.prepare(e);) {
|
|
1473
|
+
let t = this.ready[this.readyIndex++], r = this.dispatch(e, t, !1);
|
|
1474
|
+
if (n = r?.lastSystemError ?? n, !r) {
|
|
1475
|
+
this.nodes.has(t) && t.state === "pending" && this.ready.push(t);
|
|
1476
|
+
break;
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
} finally {
|
|
1480
|
+
this.ready = this.ready.slice(this.readyIndex), this.readyIndex = 0, this.pumping = !1, this.scheduleContinuation(e);
|
|
1481
|
+
}
|
|
1482
|
+
return { lastSystemError: n };
|
|
1483
|
+
}
|
|
1484
|
+
enqueue(e, t, n, r) {
|
|
1485
|
+
let i = {
|
|
1486
|
+
system: e,
|
|
1487
|
+
access: t,
|
|
1488
|
+
elapsedTime: n,
|
|
1489
|
+
gameTime: r,
|
|
1490
|
+
state: "pending",
|
|
1491
|
+
dependencies: 0,
|
|
1492
|
+
dependents: [],
|
|
1493
|
+
publicationDependencies: 0,
|
|
1494
|
+
publicationDependents: []
|
|
1495
|
+
}, a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), s = (e) => {
|
|
1496
|
+
e && e.state !== "complete" && a.add(e);
|
|
1497
|
+
};
|
|
1498
|
+
if (s(this.tails.get(e)), s(this.exclusiveTail), t.exclusive) this.tails.forEach(s), this.exclusiveTail = i;
|
|
1499
|
+
else {
|
|
1500
|
+
let n = (e) => {
|
|
1501
|
+
e && e.state !== "complete" && o.add(e);
|
|
1502
|
+
};
|
|
1503
|
+
for (let e of t.creates) {
|
|
1504
|
+
let t = this.frontier(e);
|
|
1505
|
+
n(t.writer), n(t.creator);
|
|
1506
|
+
}
|
|
1507
|
+
if (t.creates.size) for (let e of this.creationReaders.values()) this.observesCreation(t, e.access) && n(e);
|
|
1508
|
+
for (let n of t.reads) if (!t.writes.has(n)) {
|
|
1509
|
+
let t = this.frontier(n);
|
|
1510
|
+
s(t.writer), t.readers.set(e, i);
|
|
1511
|
+
}
|
|
1512
|
+
for (let e of this.creators.values()) this.observesCreation(e.access, t) && s(e);
|
|
1513
|
+
(t.creationReads.size || t.creationQueries?.length) && this.creationReaders.set(t, i);
|
|
1514
|
+
for (let e of t.writes) {
|
|
1515
|
+
let t = this.frontier(e);
|
|
1516
|
+
s(t.writer), s(t.creator), t.readers.forEach(s), t.readers.clear(), t.writer = i;
|
|
1517
|
+
}
|
|
1518
|
+
for (let e of t.creates) this.frontier(e).creator = i;
|
|
1519
|
+
t.creates.size && this.creators.set(t, i);
|
|
1520
|
+
}
|
|
1521
|
+
for (let e of a) e.dependents.push(i);
|
|
1522
|
+
i.dependencies = a.size;
|
|
1523
|
+
for (let e of o) e.publicationDependents.push(i);
|
|
1524
|
+
i.publicationDependencies = o.size, this.nodes.add(i), this.tails.set(e, i), i.dependencies || this.ready.push(i);
|
|
1525
|
+
}
|
|
1526
|
+
frontier(e) {
|
|
1527
|
+
let t = this.frontiers.get(e);
|
|
1528
|
+
return t || (t = { readers: /* @__PURE__ */ new Map() }, this.frontiers.set(e, t)), t;
|
|
1529
|
+
}
|
|
1530
|
+
complete(e) {
|
|
1531
|
+
if (e.state !== "complete") {
|
|
1532
|
+
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);
|
|
1533
|
+
for (let t of /* @__PURE__ */ new Set([
|
|
1534
|
+
...e.access.reads,
|
|
1535
|
+
...e.access.writes,
|
|
1536
|
+
...e.access.creates
|
|
1537
|
+
])) {
|
|
1538
|
+
let n = this.frontiers.get(t);
|
|
1539
|
+
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);
|
|
1540
|
+
}
|
|
1541
|
+
for (let t of e.dependents) --t.dependencies === 0 && this.ready.push(t);
|
|
1542
|
+
e.dependents.length = 0;
|
|
1543
|
+
for (let t of e.publicationDependents) t.publicationDependencies--, t.publicationDependencies === 0 && t.effects && this.publicationReady.push(t);
|
|
1544
|
+
e.publicationDependents.length = 0, this.publish();
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
dispatch(e, t, n) {
|
|
1548
|
+
let r = t.system;
|
|
1549
|
+
if (!n && !e.systems.includes(r)) return this.complete(t), {};
|
|
1550
|
+
let i = this.generation, a = !0, o = !1, s = !1, c = null;
|
|
1551
|
+
if (e.emit(`system-${r.name}-started`), this.nodes.has(t) && this.dispatchAllowed(e)) {
|
|
1552
|
+
try {
|
|
1553
|
+
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;
|
|
1554
|
+
} catch (n) {
|
|
1555
|
+
let a = n;
|
|
1556
|
+
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", {
|
|
1557
|
+
system: r.name,
|
|
1558
|
+
error: a,
|
|
1559
|
+
phase: "run"
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
return e.emit(`system-${r.name}-finished`, {
|
|
1563
|
+
ran: o,
|
|
1564
|
+
shouldRun: a,
|
|
1565
|
+
failed: s
|
|
1566
|
+
}), { lastSystemError: c };
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
prepare(e) {
|
|
1570
|
+
return this.dispatchAllowed(e) && e.prepareForSystemDispatch?.() !== !1;
|
|
1571
|
+
}
|
|
1572
|
+
dispatchAllowed(e) {
|
|
1573
|
+
return e.dispatchAllowed !== !1;
|
|
1574
|
+
}
|
|
1575
|
+
observesCreation(e, t) {
|
|
1576
|
+
for (let n of t.creationReads) if (e.creates.has(n)) return !0;
|
|
1577
|
+
return t.creationQueries?.some((t) => t.every((t) => e.creates.has(t))) ?? !1;
|
|
1578
|
+
}
|
|
1579
|
+
conflicts(e, t) {
|
|
1580
|
+
if (e.exclusive || t.exclusive) return !0;
|
|
1581
|
+
for (let n of e.writes) if (t.reads.has(n) || t.writes.has(n)) return !0;
|
|
1582
|
+
for (let n of t.writes) if (e.reads.has(n)) return !0;
|
|
1583
|
+
for (let n of e.creates) if (t.writes.has(n)) return !0;
|
|
1584
|
+
return e.creates.size > 0 && this.observesCreation(e, t);
|
|
1585
|
+
}
|
|
1586
|
+
};
|
|
1587
|
+
//#endregion
|
|
1132
1588
|
//#region src/entity-class.ts
|
|
1133
|
-
function
|
|
1589
|
+
function K(e, t) {
|
|
1134
1590
|
return t;
|
|
1135
1591
|
}
|
|
1136
|
-
function
|
|
1592
|
+
function q(e, t) {
|
|
1137
1593
|
return t;
|
|
1138
1594
|
}
|
|
1139
1595
|
//#endregion
|
|
1140
1596
|
//#region src/actions/kill-entity.ts
|
|
1141
|
-
function
|
|
1597
|
+
function J(e) {
|
|
1142
1598
|
e.components.entity.dead = !0, e.emit("death");
|
|
1143
1599
|
}
|
|
1144
1600
|
//#endregion
|
|
1145
1601
|
//#region src/performance-timing.ts
|
|
1146
|
-
var
|
|
1602
|
+
var Y = 1e3, X = {
|
|
1147
1603
|
avg: 0,
|
|
1148
1604
|
min: 0,
|
|
1149
1605
|
max: 0,
|
|
1150
1606
|
samples: 0
|
|
1151
1607
|
};
|
|
1152
|
-
function
|
|
1153
|
-
if (!e.length) return { ...
|
|
1608
|
+
function Z(e) {
|
|
1609
|
+
if (!e.length) return { ...X };
|
|
1154
1610
|
let t = 0, n = Infinity, r = 0;
|
|
1155
1611
|
for (let i of e) t += i, i < n && (n = i), i > r && (r = i);
|
|
1156
1612
|
return {
|
|
@@ -1160,32 +1616,33 @@ function J(e) {
|
|
|
1160
1616
|
samples: e.length
|
|
1161
1617
|
};
|
|
1162
1618
|
}
|
|
1163
|
-
var
|
|
1619
|
+
var Q = class extends k.default {
|
|
1164
1620
|
world;
|
|
1165
1621
|
ticksBetweenUpdates;
|
|
1166
1622
|
stats = {
|
|
1167
|
-
update: { ...
|
|
1623
|
+
update: { ...X },
|
|
1168
1624
|
systems: [],
|
|
1169
|
-
events: { ...
|
|
1625
|
+
events: { ...X }
|
|
1170
1626
|
};
|
|
1627
|
+
autoUpdate;
|
|
1171
1628
|
ticks = 0;
|
|
1172
1629
|
updateStart = 0;
|
|
1173
1630
|
updateTimes = [];
|
|
1174
1631
|
systemTimings = /* @__PURE__ */ new Map();
|
|
1175
1632
|
destroyed = !1;
|
|
1176
1633
|
constructor(e, t = {}) {
|
|
1177
|
-
super(), this.world = e, this.ticksBetweenUpdates = t.ticksBetweenUpdates ?? 1e3, e.on("update-started", this.onUpdateStarted), e.on("update-finished", this.onUpdateFinished), e.on("system-added", this.onSystemAdded), e.on("system-removed", this.onSystemRemoved), e.systems.forEach((e) => this.trackSystem(e));
|
|
1634
|
+
super(), this.world = e, this.autoUpdate = t.autoUpdate ?? !0, this.ticksBetweenUpdates = t.ticksBetweenUpdates ?? 1e3, e.on("update-started", this.onUpdateStarted), e.on("update-finished", this.onUpdateFinished), e.on("system-added", this.onSystemAdded), e.on("system-removed", this.onSystemRemoved), e.systems.forEach((e) => this.trackSystem(e));
|
|
1178
1635
|
}
|
|
1179
1636
|
getSystemStats(e) {
|
|
1180
1637
|
return this.stats.systems.find((t) => t.name === e);
|
|
1181
1638
|
}
|
|
1182
1639
|
reset() {
|
|
1183
1640
|
this.ticks = 0, this.updateTimes = [], this.systemTimings.forEach((e) => {
|
|
1184
|
-
e.run = [], e.events = [], e.eventStart = -1;
|
|
1641
|
+
e.run = [], e.events = [], e.eventStart = -1, e.pendingRun = 0, e.pendingEvents = 0;
|
|
1185
1642
|
}), this.stats = {
|
|
1186
|
-
update: { ...
|
|
1643
|
+
update: { ...X },
|
|
1187
1644
|
systems: [],
|
|
1188
|
-
events: { ...
|
|
1645
|
+
events: { ...X }
|
|
1189
1646
|
};
|
|
1190
1647
|
}
|
|
1191
1648
|
destroy() {
|
|
@@ -1195,7 +1652,7 @@ var Y = class extends O.default {
|
|
|
1195
1652
|
this.updateStart = performance.now();
|
|
1196
1653
|
};
|
|
1197
1654
|
onUpdateFinished = (e) => {
|
|
1198
|
-
this.world.paused || (this.updateTimes.push(performance.now() - this.updateStart), this.ticks += e, this.ticks >= this.ticksBetweenUpdates && this.
|
|
1655
|
+
this.world.paused || (this.updateTimes.push(performance.now() - this.updateStart), this.ticks += e, this.autoUpdate && this.ticks >= this.ticksBetweenUpdates && this.flush());
|
|
1199
1656
|
};
|
|
1200
1657
|
onSystemAdded = (e) => {
|
|
1201
1658
|
this.trackSystem(e);
|
|
@@ -1209,11 +1666,13 @@ var Y = class extends O.default {
|
|
|
1209
1666
|
run: [],
|
|
1210
1667
|
events: [],
|
|
1211
1668
|
eventStart: -1,
|
|
1212
|
-
|
|
1213
|
-
|
|
1669
|
+
pendingRun: 0,
|
|
1670
|
+
pendingEvents: 0,
|
|
1671
|
+
onRunFinished: (e, n) => {
|
|
1672
|
+
(!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();
|
|
1214
1673
|
},
|
|
1215
|
-
onEventsFinished: () => {
|
|
1216
|
-
t.eventStart < 0 || (t.
|
|
1674
|
+
onEventsFinished: (e, n) => {
|
|
1675
|
+
t.eventStart < 0 || (t.pendingEvents += performance.now() - t.eventStart, (!n || n.last) && (t.events.push(t.pendingEvents), t.pendingEvents = 0), t.eventStart = -1);
|
|
1217
1676
|
}
|
|
1218
1677
|
};
|
|
1219
1678
|
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);
|
|
@@ -1222,26 +1681,27 @@ var Y = class extends O.default {
|
|
|
1222
1681
|
let t = this.systemTimings.get(e);
|
|
1223
1682
|
t && (this.world.off(`system-${e}-worker-finished`, t.onRunFinished), this.world.off(`system-${e}-worker-events-finished`, t.onEventsFinished), this.systemTimings.delete(e));
|
|
1224
1683
|
}
|
|
1225
|
-
|
|
1684
|
+
flush() {
|
|
1685
|
+
if (this.destroyed) return this.stats;
|
|
1226
1686
|
let e = this.world.systems.map((e) => {
|
|
1227
1687
|
let t = this.systemTimings.get(e.name);
|
|
1228
1688
|
return {
|
|
1229
1689
|
name: e.name,
|
|
1230
|
-
run:
|
|
1231
|
-
events:
|
|
1690
|
+
run: Z(t?.run ?? []),
|
|
1691
|
+
events: Z(t?.events ?? [])
|
|
1232
1692
|
};
|
|
1233
|
-
}), t = { ...
|
|
1234
|
-
e.forEach((e) => {
|
|
1693
|
+
}), t = { ...X };
|
|
1694
|
+
return e.forEach((e) => {
|
|
1235
1695
|
t.avg += e.events.avg, t.min += e.events.min, t.max += e.events.max, t.samples += e.events.samples;
|
|
1236
1696
|
}), this.stats = {
|
|
1237
|
-
update:
|
|
1697
|
+
update: Z(this.updateTimes),
|
|
1238
1698
|
systems: e,
|
|
1239
1699
|
events: t
|
|
1240
1700
|
}, this.ticks = 0, this.updateTimes = [], this.systemTimings.forEach((e) => {
|
|
1241
1701
|
e.run = [], e.events = [];
|
|
1242
|
-
}), this.emit("stats-updated", this.stats);
|
|
1702
|
+
}), this.emit("stats-updated", this.stats), this.stats;
|
|
1243
1703
|
}
|
|
1244
|
-
},
|
|
1704
|
+
}, $ = class extends L {
|
|
1245
1705
|
constructor(e, t) {
|
|
1246
1706
|
super(e, {
|
|
1247
1707
|
...t,
|
|
@@ -1257,6 +1717,6 @@ var Y = class extends O.default {
|
|
|
1257
1717
|
}
|
|
1258
1718
|
};
|
|
1259
1719
|
//#endregion
|
|
1260
|
-
export {
|
|
1720
|
+
export { R as BaseEntity, U as BaseWorld, n as CLASS_INDEX, f as Component, G as ConflictScheduler, _ as ConstantStringCache, c as DEAD_INDEX, Y as DEFAULT_TICKS_BETWEEN_UPDATES, B as DefaultScheduler, z as EntityFactory, N as EntitySystem, F as EntitySystemWebWorker, L as EntityWorkerSystem, M as IterableSystem, v as MemoryComponent, Q as PerformanceTiming, g as STATIC_INDEX, A as System, r as TYPE_INDEX, P as WebWorker, $ as WorkerSystem, t as addComponentWorker, p as createEntitySystemWorker, d as createEntityWorker, h as createSystemWorker, K as defineEntityClasses, q as defineEntityConfigs, i as entityDefinition, J as killEntity, m as killEntityWorker, s as removeComponentWorker };
|
|
1261
1721
|
|
|
1262
1722
|
//# sourceMappingURL=index.js.map
|