@daneren2005/shared-memory-ecs 1.10.1 → 1.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/world.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -514,7 +514,7 @@ var T = class extends C {
|
|
|
514
514
|
else if (n.type === "grow-buffer-from-worker") this.world.addGrownBuffer(n.buffer);
|
|
515
515
|
else if (n.type === "run-complete") {
|
|
516
516
|
if (n.generation !== this.generation) {
|
|
517
|
-
this.world.scheduler.prepareEffects && this.discardWorkerAllocations(n);
|
|
517
|
+
this.world.scheduler.prepareEffects && this.discardWorkerAllocations(n), this.world.notifyAbandonedRunFinished(this);
|
|
518
518
|
return;
|
|
519
519
|
}
|
|
520
520
|
let e = this.timingBatch && {
|
|
@@ -1321,8 +1321,9 @@ var Y = class {
|
|
|
1321
1321
|
}
|
|
1322
1322
|
load(e) {
|
|
1323
1323
|
if (!this.pristine || this.scheduler.prepareEffects && this.systems.some((e) => e.isCurrentlyRunning())) {
|
|
1324
|
+
let e = this.systems.filter((e) => e.isCurrentlyRunning());
|
|
1324
1325
|
for (let e of Array.from(this.entities.values())) this.removeEntity(e);
|
|
1325
|
-
this.systems.forEach((e) => e.clear()), this.scheduler.reset?.(this), this.consolidateFreeBuffersForReload();
|
|
1326
|
+
this.systems.forEach((e) => e.clear()), this.scheduler.reset?.(this), this.consolidateFreeBuffersForReload(e);
|
|
1326
1327
|
}
|
|
1327
1328
|
for (let e of Object.keys(this.factory.configs)) this.constantStrings.getOrCreate(e);
|
|
1328
1329
|
for (let e of Object.keys(this.factory.classes)) this.constantStrings.getOrCreate(e);
|
|
@@ -1385,6 +1386,9 @@ var Y = class {
|
|
|
1385
1386
|
notifySystemRunCompleted(e) {
|
|
1386
1387
|
this.activeFreeBuffer.waitingSystems.delete(e) && this.activeFreeBuffer.waitingSystems.size === 0 && this.processFreeBuffers(), this.scheduler.runCompleted?.(this, e);
|
|
1387
1388
|
}
|
|
1389
|
+
notifyAbandonedRunFinished(e) {
|
|
1390
|
+
e.isCurrentlyRunning() || this.activeFreeBuffer.waitingSystems.delete(e) && this.activeFreeBuffer.waitingSystems.size === 0 && this.processFreeBuffers();
|
|
1391
|
+
}
|
|
1388
1392
|
processFreeBuffers() {
|
|
1389
1393
|
for (; this.activeFreeBuffer.waitingSystems.size === 0 && (this.activeFreeBuffer.frees.length > 0 && this.performFrees(this.activeFreeBuffer), this.nextFreeBuffer.frees.length !== 0);) this.promoteNextFreeBuffer();
|
|
1390
1394
|
}
|
|
@@ -1393,10 +1397,11 @@ var Y = class {
|
|
|
1393
1397
|
this.activeFreeBuffer = this.nextFreeBuffer, this.nextFreeBuffer = e;
|
|
1394
1398
|
let t = this.activeFreeBuffer;
|
|
1395
1399
|
t.waitElapsed = 0, t.waitingSystems.clear();
|
|
1396
|
-
for (let e of this.systems)
|
|
1400
|
+
for (let e of this.systems) e.isCurrentlyRunning() && t.waitingSystems.add(e);
|
|
1397
1401
|
}
|
|
1398
|
-
consolidateFreeBuffersForReload() {
|
|
1399
|
-
|
|
1402
|
+
consolidateFreeBuffersForReload(e) {
|
|
1403
|
+
let t = this.activeFreeBuffer;
|
|
1404
|
+
t.frees.push(...this.nextFreeBuffer.frees), this.nextFreeBuffer.frees.length = 0, t.waitingSystems.clear(), e.forEach((e) => t.waitingSystems.add(e)), t.waitElapsed = 0;
|
|
1400
1405
|
}
|
|
1401
1406
|
freeAllPendingBuffers() {
|
|
1402
1407
|
this.performFrees(this.activeFreeBuffer), this.performFrees(this.nextFreeBuffer), this.activeFreeBuffer.waitingSystems.clear(), this.activeFreeBuffer.waitElapsed = 0, this.nextFreeBuffer.waitingSystems.clear(), this.nextFreeBuffer.waitElapsed = 0;
|
|
@@ -1422,7 +1427,7 @@ var Y = class {
|
|
|
1422
1427
|
let t = this.systems.findIndex((t) => t.name === e);
|
|
1423
1428
|
if (t !== -1) {
|
|
1424
1429
|
let [e] = this.systems.splice(t, 1);
|
|
1425
|
-
this.scheduler.systemRemoved?.(this, e), this.emit("system-removed", e);
|
|
1430
|
+
this.scheduler.systemRemoved?.(this, e), this.emit("system-removed", e), this.activeFreeBuffer.waitingSystems.delete(e) && this.activeFreeBuffer.waitingSystems.size === 0 && this.processFreeBuffers();
|
|
1426
1431
|
}
|
|
1427
1432
|
}
|
|
1428
1433
|
update(e) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../node_modules/eventemitter3/index.js","../node_modules/eventemitter3/index.mjs","../src/systems/system.ts","../src/systems/iterable-system.ts","../src/systems/entity-system.ts","../src/systems/workers/web-worker.ts","../src/systems/workers/entity-system-web-worker.ts","../src/systems/entity-worker-system.ts","../src/entity.ts","../src/entity-factory.ts","../src/entity-compression.ts","../src/scheduling/default-scheduler.ts","../src/world.ts","../src/scheduling/conflict-scheduler.ts","../src/entity-class.ts","../src/actions/kill-entity.ts","../src/performance-timing.ts","../src/systems/worker-system.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","import EventEmitter from './index.js'\n\nexport { EventEmitter }\nexport default EventEmitter\n","import { EventEmitter } from 'eventemitter3';\nimport type BaseWorld from '../world';\nimport type BaseEntity from '../entity';\nimport type { ComponentDefinitionMap, ComponentMap } from '../component-definition';\n\n// Base system: runs on an optional fixed timestep (deltaBetweenRuns), driven by BaseWorld#update.\nexport default abstract class System<C extends ComponentMap = ComponentMap> extends EventEmitter {\n\tworld: BaseWorld<ComponentDefinitionMap, C>;\n\tname: string;\n\tcurrentDelta: number = 0;\n\tdeltaBetweenRuns: number;\n\tfirstRun: boolean;\n\treadonly reads?: ReadonlyArray<PropertyKey>;\n\treadonly writes?: ReadonlyArray<PropertyKey>;\n\tprivate readonly exclusive: boolean;\n\tprivate scheduledGameTime: number | undefined;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: SystemConfig<C> = { name: 'System' }) {\n\t\tsuper();\n\n\t\tthis.name = options.name;\n\t\tthis.world = world;\n\t\tthis.reads = options.reads;\n\t\tthis.writes = options.writes;\n\t\tthis.exclusive = options.exclusive ?? false;\n\n\t\tthis.deltaBetweenRuns = options.deltaBetweenRuns ?? 0;\n\t\tthis.firstRun = options.firstRun !== undefined ? options.firstRun : false;\n\t}\n\n\tinit(): void | Promise<void> {}\n\n\tclear() {\n\t\tthis.currentDelta = 0;\n\t}\n\t// Called once the world's entities all exist: the point a system hands its startup data off (see EntityWorkerSystem).\n\tfinishLoading(): void | Promise<void> {}\n\t// world.load() joins its whole batch here instead of one entity-added at a time.\n\taddEntities(batch: EntityBatch<C>): void {}\n\n\tget gameTime(): number {\n\t\treturn this.scheduledGameTime ?? this.world.gameTime;\n\t}\n\twithGameTime<T>(gameTime: number, update: () => T): T {\n\t\tconst previous = this.scheduledGameTime;\n\t\tthis.scheduledGameTime = gameTime;\n\t\ttry {\n\t\t\treturn update();\n\t\t} finally {\n\t\t\tthis.scheduledGameTime = previous;\n\t\t}\n\t}\n\tupdate(elapsedTime: number): boolean {\n\t\tthis.currentDelta += elapsedTime;\n\n\t\tif(this.currentDelta >= this.deltaBetweenRuns || this.firstRun) {\n\t\t\tlet leftOverDelta = 0;\n\t\t\tif(this.deltaBetweenRuns > 0) {\n\t\t\t\t// Carry the remainder so a run that overshoots its timestep doesn't drift the next one later.\n\t\t\t\tleftOverDelta = this.currentDelta % this.deltaBetweenRuns;\n\t\t\t}\n\n\t\t\tthis.run(this.currentDelta - leftOverDelta);\n\t\t\tthis.currentDelta = leftOverDelta;\n\t\t\tthis.firstRun = false;\n\t\t\tthis.onRunFinished();\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\tabstract run(elapsedTime: number): void;\n\n\t// Logs and surfaces an error thrown by user code (an update body, preRun, etc.) on the main thread: a\n\t// `system-error` event carrying the system name, so a run keeps going past one failure instead of aborting.\n\tprotected onError(error: Error, context: { entityId?: number, phase?: SystemErrorPhase } = {}) {\n\t\tconst where = context.entityId !== undefined ? ` (entity ${context.entityId})` : '';\n\t\tconsole.error(`Error in system ${this.name}${where}: ${error.message}`, error);\n\t\tconst payload: SystemError = { system: this.name, error, entityId: context.entityId, phase: context.phase };\n\t\tthis.world.emit('system-error', payload);\n\t}\n\n\t// Marks one run as fully applied. Synchronous systems finish inside update(); subclasses whose work is\n\t// deferred (spread across frames, or off-thread) override this and call it at their real completion point.\n\tprotected onRunFinished() {\n\t\tthis.world.notifySystemRunCompleted(this);\n\t}\n\t// True while a run is still in progress between update() calls (a worker round-trip, or an iteration spread\n\t// across frames). Used by the world to keep waiting on a system that is mid-run over memory it may free.\n\tisCurrentlyRunning(): boolean {\n\t\treturn false;\n\t}\n\t// Resolves once any in-flight run has finished, so the world's clear() knows nothing is still reading memory\n\twaitForRunToComplete(): void | Promise<void> {}\n\n\tshouldRun(): boolean {\n\t\treturn true;\n\t}\n\tget readComponents(): ReadonlyArray<PropertyKey> | undefined {\n\t\treturn this.reads;\n\t}\n\tget requiresExclusiveScheduling(): boolean {\n\t\treturn this.exclusive;\n\t}\n\tget createdComponents(): ReadonlyArray<PropertyKey> {\n\t\treturn [];\n\t}\n\tget creationReadComponents(): ReadonlyArray<PropertyKey> | undefined {\n\t\treturn this.readComponents;\n\t}\n\tget creationReadQueries(): ReadonlyArray<ReadonlyArray<PropertyKey>> | undefined {\n\t\treturn undefined;\n\t}\n\n\tdestroy() {\n\t\tthis.removeAllListeners();\n\t}\n}\n\n// A load batch in load order. Entities with identical component keys share a group, so a query's component test is\n// answered once per group rather than once per entity.\nexport interface EntityBatch<C extends ComponentMap = ComponentMap> {\n\tentities: Array<BaseEntity<C>>\n\t// Per entity, its index into `groups`.\n\tgroupIndexes: Array<number>\n\t// One representative entity per distinct component-key set.\n\tgroups: Array<BaseEntity<C>>\n}\n\n// Visits, in load order, each entity whose group passes `matchesGroup`.\nexport function forEachInMatchingGroups<C extends ComponentMap>(batch: EntityBatch<C>, matchesGroup: (representative: BaseEntity<C>) => boolean, callback: (entity: BaseEntity<C>) => void) {\n\tconst matches = batch.groups.map(matchesGroup);\n\tfor(let i = 0; i < batch.entities.length; i++) {\n\t\tif(matches[batch.groupIndexes[i]]) {\n\t\t\tcallback(batch.entities[i]);\n\t\t}\n\t}\n}\n\nexport interface SystemConfig<C extends ComponentMap = ComponentMap> {\n\tname: string\n\tdeltaBetweenRuns?: number\n\tfirstRun?: boolean\n\treads?: ReadonlyArray<keyof C>\n\twrites?: ReadonlyArray<keyof C>\n\texclusive?: boolean\n}\n\n// Which part of a run threw, for the `system-error` event.\nexport type SystemErrorPhase = 'queryChanged' | 'preRun' | 'preBatch' | 'update' | 'entityRemoved' | 'run' | 'died';\nexport interface SystemError {\n\tsystem: string\n\terror: Error\n\tentityId?: number\n\tphase?: SystemErrorPhase\n}\n","import type BaseWorld from '../world';\nimport type { ComponentDefinitionMap, ComponentMap } from '../component-definition';\nimport System, { type SystemConfig } from './system';\n\nexport default abstract class IterableSystem<C extends ComponentMap, T> extends System<C> {\n\tremainingInstancesToRun: Array<T> = [];\n\tremainingInstancesStartTime: number | null = null;\n\titerationsPerCheck: number;\n\tmaxMsPerFrame: number;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: IterableSystemConfig<C>) {\n\t\tsuper(world, options);\n\n\t\tthis.iterationsPerCheck = options.iterationsPerCheck ?? 1;\n\t\tthis.maxMsPerFrame = options.maxMsPerFrame ?? 10;\n\t}\n\n\tclear() {\n\t\tsuper.clear();\n\n\t\tthis.remainingInstancesToRun = [];\n\t\tthis.remainingInstancesStartTime = null;\n\t}\n\n\tupdate(elapsedTime: number): boolean {\n\t\tif(this.remainingInstancesToRun.length) {\n\t\t\tthis.runIterables(this.remainingInstancesToRun, this.remainingInstancesStartTime ?? 0);\n\t\t\tthis.currentDelta += elapsedTime;\n\t\t\tif(!this.remainingInstancesToRun.length) {\n\t\t\t\tthis.onRunFinished();\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn super.update(elapsedTime);\n\t\t}\n\t}\n\trun(elapsedTime: number): void {\n\t\tlet iterables = this.getIterables();\n\t\tthis.runIterables(iterables, elapsedTime);\n\t}\n\t// A run that overflowed onto a later frame isn't finished yet; only count it once the queue drains (handled\n\t// by update() when it empties remainingInstancesToRun).\n\tprotected onRunFinished() {\n\t\tif(this.remainingInstancesToRun.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tsuper.onRunFinished();\n\t}\n\tisCurrentlyRunning(): boolean {\n\t\treturn this.remainingInstancesToRun.length > 0;\n\t}\n\n\trunIterables(iterables: Array<T>, elapsedTime: number) {\n\t\tlet started = performance.now();\n\t\ttry {\n\t\t\tthis.beforeRunIterables();\n\t\t} catch(e) {\n\t\t\t// preRun failed: skip the iteration this frame rather than run over half-prepared state.\n\t\t\tthis.onError(e as Error, { phase: 'preRun' });\n\t\t\tthis.remainingInstancesToRun = [];\n\t\t\tthis.remainingInstancesStartTime = null;\n\t\t\treturn;\n\t\t}\n\t\tfor(let i = 0; i < iterables.length; i++) {\n\t\t\ttry {\n\t\t\t\tthis.updateIterable(iterables[i], elapsedTime);\n\t\t\t} catch(e) {\n\t\t\t\t// One iterable failing must not stop the rest of the run.\n\t\t\t\tthis.onError(e as Error, { phase: 'update', entityId: this.getIterableEntityId(iterables[i]) });\n\t\t\t}\n\n\t\t\tif(i % this.iterationsPerCheck === 0) {\n\t\t\t\tlet now = performance.now();\n\t\t\t\tif(now - started >= this.maxMsPerFrame) {\n\t\t\t\t\tthis.remainingInstancesToRun = iterables.slice(i + 1);\n\t\t\t\t\tthis.remainingInstancesStartTime = elapsedTime;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.remainingInstancesToRun = [];\n\t\tthis.remainingInstancesStartTime = null;\n\t}\n\tbeforeRunIterables() {}\n\t// Best-effort eid for a failed iterable, so `system-error` can name it. Subclasses whose T carries an eid override.\n\tprotected getIterableEntityId(_iterable: T): number | undefined {\n\t\treturn undefined;\n\t}\n\n\tabstract getIterables(): Array<T>;\n\tabstract updateIterable(iterable: T, elapsedTime: number): void;\n}\n\nexport interface IterableSystemConfig<C extends ComponentMap = ComponentMap> extends SystemConfig<C> {\n\titerationsPerCheck?: number\n\tmaxMsPerFrame?: number\n}\n","import type BaseWorld from '../world';\nimport type BaseEntity from '../entity';\nimport type { ComponentDefinitionMap, ComponentMap } from '../component-definition';\nimport IterableSystem, { type IterableSystemConfig } from './iterable-system';\nimport { forEachInMatchingGroups, type EntityBatch } from './system';\n\n// Iterates the entities owning a given set of components on the main thread; membership tracks world events.\nexport default abstract class EntitySystem<C extends ComponentMap, T extends BaseEntity<C> = BaseEntity<C>> extends IterableSystem<C, T> {\n\tentities: Map<number, T> = new Map();\n\toptions: EntitySystemConfig<C>;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: EntitySystemConfig<C> = { name: 'EntitySystem' }) {\n\t\tif(!options.iterationsPerCheck) {\n\t\t\toptions.iterationsPerCheck = 10;\n\t\t}\n\t\tif(!options.maxMsPerFrame) {\n\t\t\toptions.maxMsPerFrame = 4;\n\t\t}\n\n\t\tsuper(world, options);\n\t\tthis.options = options;\n\n\t\tworld.on('entity-added', (entity: BaseEntity<C>) => {\n\t\t\tif(!world.isBulkLoading) {\n\t\t\t\tthis.onEntityAdded(entity);\n\t\t\t}\n\t\t});\n\t\tworld.on('entity-removed', (entity: BaseEntity<C>) => {\n\t\t\tthis.removeEntity(entity);\n\t\t});\n\n\t\tworld.entities.forEach(entity => {\n\t\t\tthis.checkAddEntity(entity);\n\t\t});\n\t}\n\n\tgetIterables(): Array<T> {\n\t\tconst iterables: Array<T> = [];\n\t\tthis.entities.forEach(entity => {\n\t\t\tif(!entity.components.entity.dead) {\n\t\t\t\titerables.push(entity);\n\t\t\t}\n\t\t});\n\n\t\treturn iterables;\n\t}\n\tupdateIterable(entity: T, elapsedTime: number): void {\n\t\t// A multi-frame snapshot can outlive query membership. Revalidate the exact instance before touching it.\n\t\tif(entity.components.entity.dead || this.entities.get(entity.eid) !== entity) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateEntity(entity, elapsedTime);\n\t}\n\tfilterEntity(entity: BaseEntity<C>): boolean {\n\t\treturn !entity.components.entity.isStatic;\n\t}\n\tprotected getIterableEntityId(entity: T): number {\n\t\treturn entity.eid;\n\t}\n\tisEntityInSystem(entity: BaseEntity<C>) {\n\t\treturn this.entities.has(entity.eid);\n\t}\n\tabstract updateEntity(entity: T, elapsedTime: number): void;\n\n\tprivate onEntityAdded(entity: BaseEntity<C>) {\n\t\tif(this.checkAddEntity(entity) && this.options.updateEntityOnAdd) {\n\t\t\tthis.updateEntity(entity as T, 0);\n\t\t}\n\t}\n\taddEntities(batch: EntityBatch<C>): void {\n\t\t// A subclass with its own membership rule gets it applied per entity, exactly as entity-added would.\n\t\tif(this.checkAddEntity !== EntitySystem.prototype.checkAddEntity) {\n\t\t\tbatch.entities.forEach(entity => this.onEntityAdded(entity));\n\t\t\treturn;\n\t\t}\n\n\t\tforEachInMatchingGroups(batch, entity => this.hasComponents(entity), entity => {\n\t\t\tif(this.filterEntity(entity)) {\n\t\t\t\tthis.entities.set(entity.eid, entity as T);\n\t\t\t\tif(this.options.updateEntityOnAdd) {\n\t\t\t\t\tthis.updateEntity(entity as T, 0);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tprivate hasComponents(entity: BaseEntity<C>): boolean {\n\t\treturn !this.options.components || this.options.components.every(component => !!entity.components[component]);\n\t}\n\n\tcheckAddEntity(entity: BaseEntity<C>): boolean {\n\t\tif(!this.hasComponents(entity)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.filterEntity(entity)) {\n\t\t\tthis.entities.set(entity.eid, entity as T);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\tremoveEntity(entity: BaseEntity<C>) {\n\t\tthis.entities.delete(entity.eid);\n\t}\n\n\tshouldRun(): boolean {\n\t\t// A continuation must drain even if every live member left since the previous frame.\n\t\treturn this.isCurrentlyRunning() || this.entities.size > 0;\n\t}\n\tget creationReadComponents(): ReadonlyArray<PropertyKey> | undefined {\n\t\tif(!this.options.components) {\n\t\t\treturn this.reads ? ['entity', ...this.reads] : undefined;\n\t\t}\n\t\tconst required = this.options.components.filter(component => component !== 'entity');\n\t\treturn [...this.reads ?? [], ...required.length ? required : ['entity']];\n\t}\n\tget creationReadQueries(): ReadonlyArray<ReadonlyArray<PropertyKey>> | undefined {\n\t\tif(this.checkAddEntity !== EntitySystem.prototype.checkAddEntity) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [this.options.components ?? []];\n\t}\n\tget readComponents(): ReadonlyArray<PropertyKey> | undefined {\n\t\tconst components = this.options.components ?? this.reads;\n\t\treturn components ? ['entity', ...components, ...this.reads ?? []] : undefined;\n\t}\n}\n\nexport interface EntitySystemConfig<C extends ComponentMap> extends IterableSystemConfig<C> {\n\tcomponents?: Array<keyof C>\n\tupdateEntityOnAdd?: boolean\n}\n","// Minimal Worker-like base for the main-thread fallback. Loose params: this mirrors the DOM Worker boundary.\nexport default abstract class WebWorker {\n\tabstract postMessage(message: any): void | Promise<void>;\n\tonmessage(message: any, transferrables: Array<any> = []): void {\n\n\t}\n}\n","import WebWorker from './web-worker';\nimport QueryMembership from './query-membership';\nimport EntityWorkBatchState from './entity-work-batch';\nimport type EntitySystemWorkerMessage from './entity-system-worker-message';\nimport type { EntityEvent, SystemEvents, WorkerRunError } from './entity-system-worker-message';\nimport type BaseWorld from '../../world';\nimport type { ComponentDefinitionMap, ComponentMap, RegisteredComponentRegistry } from '../../component-definition';\nimport type {\n\tEntityWorkerSystemCallbacks, EntityWorkerSystemWorld, EntityQueryComponents, EntityUpdateComponents,\n\tEntityUpdateFunction, QueryDelta, WorkerAllocator, WorkerComponentChange, WorkerCreatedEntity,\n} from '../entity-worker-system';\nimport { buildWorkerComponent, buildWorkerEntity, type WorkerCreateRegistry } from '../../actions/build-worker-entity';\n\n// Main-thread fallback that runs the update function synchronously, mirroring the real worker's behavior.\nexport default class EntitySystemWebWorker<C extends ComponentMap, T extends EntityUpdateComponents<C>, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld, D = unknown> extends WebWorker {\n\tprivate updateFunction: EntityUpdateFunction<C, T, W, D>;\n\tprivate entities = new QueryMembership<T>();\n\tprivate workState = new EntityWorkBatchState<T, W>();\n\tprivate queryEntities: { [key: string]: QueryMembership<T> } = {};\n\t// Mirrors createEntitySystemWorker: updateFunction.init's result, merged onto `world` each run.\n\tprivate worldExtension: Partial<W> | undefined;\n\t// Running on the main thread, this shares the world (its string cache, registry pools, eid counter) directly.\n\tprivate world: BaseWorld<ComponentDefinitionMap, C>;\n\tprivate allocator: WorkerAllocator;\n\tprivate createsEntities: boolean;\n\tprivate addsComponents: boolean;\n\n\tconstructor(\n\t\tupdateFunction: EntityUpdateFunction<C, T, W, D>,\n\t\tworld: BaseWorld<ComponentDefinitionMap, C>,\n\t\tcreatesEntities = false,\n\t\taddsComponents = false,\n\t) {\n\t\tsuper();\n\t\tthis.updateFunction = updateFunction;\n\t\tthis.world = world;\n\t\tthis.createsEntities = createsEntities;\n\t\tthis.addsComponents = addsComponents;\n\t\tconst registry = world.registry as RegisteredComponentRegistry<C>;\n\t\tthis.allocator = {\n\t\t\tallocateEid: () => world.allocateEid(),\n\t\t\tallocateComponentBlock: (name, values) => registry[name as keyof C].memoryComponent.create(values),\n\t\t};\n\t}\n\n\tprivate getString = (pointer: number): string => this.world.constantStrings.getString(pointer) ?? '';\n\n\tpostMessage(message: EntitySystemWorkerMessage<W, D>): void {\n\t\tif(message.type === 'init') {\n\t\t\tthis.onMessageTyped({\n\t\t\t\ttype: 'init-complete',\n\t\t\t});\n\t\t} else if(message.type === 'load') {\n\t\t\tthis.entities.apply(message.entities as QueryDelta<T>);\n\t\t\tconst queries = this.applyQueryDeltas(message.queries);\n\t\t\tconst world = { gameTime: message.gameTime, getString: this.getString, heap: this.world.heap };\n\t\t\tthis.worldExtension = this.updateFunction.init?.(world, message.data, this.entities.entries, queries) ?? undefined;\n\t\t\tthis.onMessageTyped({\n\t\t\t\ttype: 'loaded',\n\t\t\t});\n\t\t} else if(message.type === 'reset') {\n\t\t\tthis.workState.clear();\n\t\t\t// Drop the persistent lists so a reused world starts empty; worldExtension is refreshed by the next load.\n\t\t\tthis.entities.clear();\n\t\t\tthis.queryEntities = {};\n\t\t} else if(message.type === 'run') {\n\t\t\tmessage.world = this.workState.getWorld(message.world, message.workBatch);\n\t\t\tif(this.worldExtension) {\n\t\t\t\tObject.assign(message.world, this.worldExtension);\n\t\t\t}\n\t\t\tmessage.world.getString = this.getString;\n\t\t\tmessage.world.heap = this.world.heap;\n\t\t\tmessage.world.allocate = this.allocator;\n\t\t\tif(this.createsEntities) {\n\t\t\t\tconst registry: WorkerCreateRegistry = this.world.registry;\n\t\t\t\tmessage.world.buildEntityDescriptor = config => buildWorkerEntity(\n\t\t\t\t\tconfig,\n\t\t\t\t\tthis.world.factory.configs,\n\t\t\t\t\tregistry,\n\t\t\t\t\tthis.allocator,\n\t\t\t\t\tthis.world.factory.getWorkerClasses(),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif(this.addsComponents) {\n\t\t\t\tconst registry: WorkerCreateRegistry = this.world.registry;\n\t\t\t\tmessage.world.buildComponentDescriptor = (name, config) => buildWorkerComponent(name, config, registry, this.allocator);\n\t\t\t}\n\t\t\t// Timed like the real worker so a forceMainThread system reports a real run cost, not zero.\n\t\t\tconst start = performance.now();\n\t\t\tlet entityEvents: Array<EntityEvent> = [];\n\t\t\tlet systemEvents: SystemEvents = {};\n\t\t\tlet createdEntities: Array<WorkerCreatedEntity> = [];\n\t\t\tlet componentChanges: Array<WorkerComponentChange> = [];\n\t\t\tlet errors: Array<WorkerRunError> = [];\n\n\t\t\tthis.entities.apply(message.entities as QueryDelta<T>);\n\t\t\tconst runEntities = this.workState.getEntities(this.entities.entries, message.entities as QueryDelta<T>, message.workBatch);\n\t\t\tconst queries = this.applyQueryDeltas(message.queries);\n\n\t\t\tlet callbacks: EntityWorkerSystemCallbacks<C> = {\n\t\t\t\tentityComponentChanged<K extends keyof C, P extends keyof C[K]>(entityId: number, componentName: K, prop: P, value: C[K][P]) {\n\t\t\t\t\tentityEvents.push({\n\t\t\t\t\t\tentityId,\n\t\t\t\t\t\tevent: 'component-property-updated',\n\t\t\t\t\t\targs: [componentName, prop, value],\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\temitEntityEvent(entityId: number, event: string, ...args: Array<unknown>) {\n\t\t\t\t\tentityEvents.push({\n\t\t\t\t\t\tentityId,\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\targs,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\temitSystemEvent(event: string, entityId: number) {\n\t\t\t\t\t(systemEvents[event] ?? (systemEvents[event] = [])).push(entityId);\n\t\t\t\t},\n\t\t\t\tentityDied(entityId: number) {\n\t\t\t\t\tentityEvents.push({\n\t\t\t\t\t\tentityId,\n\t\t\t\t\t\tevent: 'death',\n\t\t\t\t\t\targs: [],\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tcreateEntity(entity: WorkerCreatedEntity) {\n\t\t\t\t\tcreatedEntities.push(entity);\n\t\t\t\t},\n\t\t\t\taddComponent(entityId, component) {\n\t\t\t\t\tcomponentChanges.push({ type: 'add', entityId, component });\n\t\t\t\t},\n\t\t\t\tremoveComponent(entityId, componentName) {\n\t\t\t\t\tcomponentChanges.push({ type: 'remove', entityId, componentName: String(componentName) });\n\t\t\t\t},\n\t\t\t};\n\t\t\tif(this.updateFunction.queryChanged) {\n\t\t\t\tfor(const [queryName, delta] of Object.entries(message.queries)) {\n\t\t\t\t\tif(!delta.added.length && !delta.removed.length) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.updateFunction.queryChanged(message.world, queryName, delta, callbacks);\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\terrors.push({ error: e as Error, phase: 'queryChanged' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet preRunFailed = false;\n\t\t\tif(this.updateFunction.preRun && (!message.workBatch || message.workBatch.first)) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.updateFunction.preRun(message.world, this.entities.entries, queries, callbacks);\n\t\t\t\t} catch(e) {\n\t\t\t\t\tpreRunFailed = true;\n\t\t\t\t\terrors.push({ error: e as Error, phase: 'preRun' });\n\t\t\t\t}\n\t\t\t}\n\t\t\t// preRun sets up the run's state; if it threw, skip the entity loop rather than run over half-prepared data.\n\t\t\tif(!preRunFailed && this.updateFunction.preBatch) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.updateFunction.preBatch(message.world, runEntities, queries, callbacks);\n\t\t\t\t} catch(e) {\n\t\t\t\t\tpreRunFailed = true;\n\t\t\t\t\terrors.push({ error: e as Error, phase: 'preBatch' });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!preRunFailed) {\n\t\t\t\trunEntities.forEach(entity => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.updateFunction(message.world, entity.entityId, entity.components, queries, callbacks);\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t// One entity failing must not stop the rest of the run.\n\t\t\t\t\t\terrors.push({ error: e as Error, phase: 'update', entityId: entity.entityId });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif(this.updateFunction.entityRemoved) {\n\t\t\t\tfor(let entityId of message.entities.removed) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.updateFunction.entityRemoved(message.world, entityId, callbacks);\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\terrors.push({ error: e as Error, phase: 'entityRemoved', entityId });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst runTime = performance.now() - start;\n\t\t\tthis.workState.finish(message.workBatch, preRunFailed);\n\n\t\t\tthis.onMessageTyped({\n\t\t\t\ttype: 'run-complete',\n\t\t\t\tgeneration: message.generation,\n\t\t\t\trunTime,\n\t\t\t\tevents: entityEvents,\n\t\t\t\tsystemEvents,\n\t\t\t\tcreated: createdEntities,\n\t\t\t\tcomponentChanges,\n\t\t\t\terrors,\n\t\t\t\tworkFailed: preRunFailed,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate applyQueryDeltas(deltas: { [key: string]: QueryDelta }): EntityQueryComponents<C> {\n\t\tconst queries: EntityQueryComponents<C> = {};\n\t\tfor(const [queryKey, delta] of Object.entries(deltas)) {\n\t\t\tconst membership = this.queryEntities[queryKey] ??= new QueryMembership<T>();\n\t\t\tmembership.apply(delta as QueryDelta<T>);\n\t\t\tqueries[queryKey] = membership.entries;\n\t\t}\n\t\treturn queries;\n\t}\n\n\tonMessageTyped(message: EntitySystemWorkerMessage<W, D>) {\n\t\tthis.onmessage({\n\t\t\tdata: message,\n\t\t});\n\t}\n}\n","import type MemoryHeap from '@daneren2005/shared-memory-objects/memory-heap';\nimport type { GrowBufferData } from '@daneren2005/shared-memory-objects/memory-heap';\nimport type BaseWorld from '../world';\nimport type BaseEntity from '../entity';\nimport type { BaseComponent, ComponentDefinitionMap, ComponentMap } from '../component-definition';\nimport type { ComponentTypedArray } from '../memory-component';\nimport System, { forEachInMatchingGroups, type EntityBatch, type SystemConfig } from './system';\nimport type EntitySystemWorkerMessage from './workers/entity-system-worker-message';\nimport type { EntityWorkBatch } from './workers/entity-system-worker-message';\nimport EntitySystemWebWorker from './workers/entity-system-web-worker';\nimport type { SchedulerEffects } from '../scheduling/scheduler';\n\nconst MAIN_QUERY_NAME = '___main';\n\n// Runs an update function over the raw shared-memory blocks of its matched entities. Uses getWorker() when\n// Web Workers + SharedArrayBuffer exist, else falls back to EntitySystemWebWorker on the main thread. No game\n// concepts; games inject per-run data via addDataToWorld.\nexport default abstract class EntityWorkerSystem<\n\tC extends ComponentMap,\n\tT extends EntityUpdateComponents<C>,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> extends System<C> {\n\tentities: Map<number, BaseEntity<C>> = new Map();\n\toptions: EntityWorkerSystemConfig<C, T, W, D>;\n\n\tworker: Worker | EntitySystemWebWorker<C, T, W, D>;\n\tisWorkerThread: boolean;\n\n\tprivate initialized = false;\n\tprivate initPromise: PromiseWithResolvers<void> | null = null;\n\tprivate initError: Error | null = null;\n\tprivate loadingPromise: Resolvable | null = null;\n\tprivate runCompletePromise: Resolvable | null = null;\n\tprivate isRunning = false;\n\tprivate workPass: { entities: Array<BaseEntity<C>>, cursor: number, elapsedTime: number, gameTime: number } | undefined;\n\tprivate timingBatch: Pick<EntityWorkBatch, 'first' | 'last'> | undefined;\n\tprivate pendingEffects: SchedulerEffects | undefined;\n\tprivate completeEffects: ((effects: SchedulerEffects) => void) | undefined;\n\t// Bumped by clear(); checked on each event to make certain we are dealing with the correct world\n\tprivate generation = 0;\n\tprotected queryEntities: { [key: string]: Map<number, BaseEntity<C>> } = {};\n\t// Membership changes since the last run(), flushed each run as a delta so a steady-state run sends empty\n\t// arrays rather than re-transmitting every eid. The worker applies these to its own list (see applyQueryDelta).\n\tprivate queryDeltas: { [key: string]: MembershipDelta<C> } = {};\n\n\taddDataToWorld?(world: W): void;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: EntityWorkerSystemConfig<C, T, W, D>) {\n\t\tsuper(world, options);\n\t\tif(options.workBatchSize !== undefined && (!Number.isSafeInteger(options.workBatchSize) || options.workBatchSize <= 0)) {\n\t\t\tthrow new Error('workBatchSize must be a positive safe integer');\n\t\t}\n\t\tthis.options = options;\n\t\tObject.keys(this.options.queries ?? {}).forEach(queryName => {\n\t\t\tthis.queryEntities[queryName] = new Map();\n\t\t});\n\n\t\tworld.on('entity-added', (entity: BaseEntity<C>) => {\n\t\t\tif(!world.isBulkLoading) {\n\t\t\t\tthis.checkAddEntity(entity);\n\t\t\t}\n\t\t});\n\t\tworld.on('entity-removed', (entity: BaseEntity<C>) => {\n\t\t\tthis.removeEntity(entity);\n\t\t});\n\n\t\tworld.entities.forEach(entity => {\n\t\t\tthis.checkAddEntity(entity);\n\t\t});\n\n\t\tif(!options.forceMainThread && typeof globalThis.Worker !== 'undefined' && typeof globalThis.SharedArrayBuffer !== 'undefined') {\n\t\t\tthis.worker = options.getWorker();\n\t\t\tthis.isWorkerThread = true;\n\t\t\t// Forward heap growth so the worker's reconstructed heap can resolve pointers into new buffers.\n\t\t\tworld.on('grow-buffer', (buffer: GrowBufferData) => {\n\t\t\t\tthis.worker.postMessage({ type: 'grow-buffer', buffer });\n\t\t\t});\n\t\t} else {\n\t\t\tthis.worker = new EntitySystemWebWorker(options.updateFunction, world, !!options.createsEntities, !!options.addsComponents);\n\t\t\tthis.isWorkerThread = false;\n\t\t}\n\n\t\tthis.initWorker();\n\t}\n\n\tprivate initWorker() {\n\t\tconst onWorkerError = (error: Error) => {\n\t\t\tconsole.error(error, error.cause);\n\t\t\tif(!this.initialized) {\n\t\t\t\tthis.initError = error;\n\t\t\t\tthis.initPromise?.reject(error);\n\t\t\t}\n\t\t};\n\t\tif(!(this.worker instanceof EntitySystemWebWorker)) {\n\t\t\tconst onErrorEvent = (event: ErrorEvent | MessageEvent) => {\n\t\t\t\tonWorkerError(new Error(`Worker ${this.name} failed to load`, { cause: event }));\n\t\t\t};\n\t\t\tthis.worker.onerror = onErrorEvent;\n\t\t\tthis.worker.onmessageerror = onErrorEvent;\n\t\t}\n\n\t\tthis.worker.onmessage = (e: MessageEvent) => {\n\t\t\tlet message = e.data as EntitySystemWorkerMessage;\n\t\t\tif(message.type === 'unhandled-rejection') {\n\t\t\t\tonWorkerError(new Error(`Worker ${this.name} had an unhandled promise rejection`, { cause: message.error }));\n\t\t\t} else if(message.type === 'init-complete') {\n\t\t\t\tthis.initialized = true;\n\t\t\t\tif(this.initPromise) {\n\t\t\t\t\tthis.initPromise.resolve();\n\t\t\t\t\tthis.initPromise = null;\n\t\t\t\t}\n\t\t\t} else if(message.type === 'loaded') {\n\t\t\t\tif(this.loadingPromise) {\n\t\t\t\t\tthis.loadingPromise.resolve();\n\t\t\t\t\tthis.loadingPromise = null;\n\t\t\t\t}\n\t\t\t} else if(message.type === 'grow-buffer-from-worker') {\n\t\t\t\t// A buffer this worker grew while allocating: adopt into the main heap and fan out to sibling workers.\n\t\t\t\tthis.world.addGrownBuffer(message.buffer);\n\t\t\t} else if(message.type === 'run-complete') {\n\t\t\t\t// A reply from a run that started before a clear(): the world it ran over is gone, so drop it whole.\n\t\t\t\tif(message.generation !== this.generation) {\n\t\t\t\t\tif(this.world.scheduler.prepareEffects) {\n\t\t\t\t\t\tthis.discardWorkerAllocations(message);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst timingBatch = this.timingBatch && { ...this.timingBatch, last: this.timingBatch.last || !!message.workFailed };\n\t\t\t\tif(message.workFailed) {\n\t\t\t\t\tthis.workPass = undefined;\n\t\t\t\t}\n\n\t\t\t\tif(!this.completeEffects) {\n\t\t\t\t\tthis.applyWorkerEffects(message, true, timingBatch);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.world.emit(`system-${this.name}-worker-finished`, message.runTime, timingBatch);\n\t\t\t\tconst generation = this.generation;\n\t\t\t\tlet settled = false;\n\t\t\t\tconst finish = () => {\n\t\t\t\t\tthis.pendingEffects = undefined;\n\t\t\t\t\tthis.isRunning = false;\n\t\t\t\t\tthis.runCompletePromise?.resolve();\n\t\t\t\t\tthis.runCompletePromise = null;\n\t\t\t\t};\n\t\t\t\tconst effects: SchedulerEffects = {\n\t\t\t\t\tapply: () => {\n\t\t\t\t\t\tif(settled) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(generation !== this.generation) {\n\t\t\t\t\t\t\teffects.discard();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tthis.pendingEffects = undefined;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tthis.applyWorkerEffects(message, false, timingBatch);\n\t\t\t\t\t\t} catch(error) {\n\t\t\t\t\t\t\tthis.onError(error as Error, { phase: 'run' });\n\t\t\t\t\t\t\tthis.world.notifySystemRunCompleted(this);\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tfinish();\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tdiscard: () => {\n\t\t\t\t\t\tif(settled) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tthis.discardWorkerAllocations(message);\n\t\t\t\t\t\tfinish();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tthis.pendingEffects = effects;\n\t\t\t\tthis.completeEffects(effects);\n\t\t\t}\n\t\t};\n\n\t\tconst message: EntitySystemWorkerMessage<W, D> = {\n\t\t\ttype: 'init',\n\t\t};\n\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tprivate applyWorkerEffects(message: WorkerRunCompletion, emitWorkerFinished: boolean, timingBatch: Pick<EntityWorkBatch, 'first' | 'last'> | undefined): void {\n\t\tthis.isRunning = false;\n\t\tif(emitWorkerFinished) {\n\t\t\tthis.world.emit(`system-${this.name}-worker-finished`, message.runTime, timingBatch);\n\t\t}\n\n\t\t// User-code errors caught inside the run: log + emit on the main thread, one per failure.\n\t\tmessage.errors.forEach(({ error, entityId, phase }) => {\n\t\t\tthis.onError(error, { entityId, phase });\n\t\t});\n\n\t\t// Structural changes are applied only after the worker has finished iterating its snapshot. Attaching emits\n\t\t// the same entity events as a main-thread mutation, which rechecks every affected system/query and queues\n\t\t// refreshed component bundles for their next run.\n\t\t(message.componentChanges ?? []).forEach(change => {\n\t\t\tconst entity = this.world.getEntityByEid(change.entityId);\n\t\t\tif(change.type === 'add') {\n\t\t\t\tconst definition = this.world.registry[change.component.name as keyof C];\n\t\t\t\tif(!entity || !definition || change.component.name === 'entity') {\n\t\t\t\t\tdefinition?.memoryComponent.delete(change.component.index);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst componentName = change.component.name as keyof C;\n\t\t\t\tentity.removeComponent(componentName);\n\t\t\t\tentity.attachComponent(componentName, change.component.index, true);\n\t\t\t} else if(entity && change.componentName !== 'entity') {\n\t\t\t\tentity.removeComponent(change.componentName);\n\t\t\t}\n\t\t});\n\n\t\t// Before the per-entity events: an entity killed this run is still in the world here, since `death`\n\t\t// is dispatched below and removes it.\n\t\tfor(const event of Object.keys(message.systemEvents)) {\n\t\t\tthis.emit(event, message.systemEvents[event]);\n\t\t}\n\n\t\tmessage.events.forEach(event => {\n\t\t\t// Look up on the world, not the query cache, so events for sub-query-only entities still route.\n\t\t\tconst entity = this.world.getEntityByEid(event.entityId);\n\t\t\tif(!entity) {\n\t\t\t\tconsole.warn(`${this.name}-event ${event.event}: Could not find entity with id ${event.entityId}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tentity.emit(event.event, ...event.args);\n\t\t});\n\n\t\t// After deaths, so an entity created this run isn't immediately removed. Adopts the blocks the worker\n\t\t// already allocated + wrote, rather than re-creating them.\n\t\tmessage.created.forEach(descriptor => {\n\t\t\tthis.world.adoptEntity(descriptor);\n\t\t});\n\n\t\tthis.world.emit(`system-${this.name}-worker-events-finished`, message.runTime, timingBatch);\n\t\tthis.world.notifySystemRunCompleted(this);\n\n\t\tif(this.runCompletePromise) {\n\t\t\tthis.runCompletePromise.resolve();\n\t\t\tthis.runCompletePromise = null;\n\t\t}\n\t}\n\n\tprivate discardWorkerAllocations(message: WorkerRunCompletion): void {\n\t\tfor(const entity of message.created) {\n\t\t\tfor(const [name, index] of Object.entries(entity.components)) {\n\t\t\t\tthis.world.registry[name as keyof C]?.memoryComponent.delete(index);\n\t\t\t}\n\t\t}\n\t\tfor(const change of message.componentChanges ?? []) {\n\t\t\tif(change.type === 'add') {\n\t\t\t\tthis.world.registry[change.component.name as keyof C]?.memoryComponent.delete(change.component.index);\n\t\t\t}\n\t\t}\n\t}\n\n\tinit(): Promise<void> | void {\n\t\tif(this.initError) {\n\t\t\treturn Promise.reject(this.initError);\n\t\t}\n\t\tif(this.initialized) {\n\t\t\treturn;\n\t\t} else if(this.initPromise) {\n\t\t\treturn this.initPromise.promise;\n\t\t}\n\n\t\tthis.initPromise = Promise.withResolvers<void>();\n\t\treturn this.initPromise.promise;\n\t}\n\n\t// Sends the init data plus pending membership over, so the worker caches every loaded entity before reporting loaded\n\tfinishLoading(): Promise<void> {\n\t\tlet { promise, resolve } = Promise.withResolvers<void>();\n\t\t// Assigned before posting: the main-thread fallback replies synchronously from inside postMessage.\n\t\tthis.loadingPromise = {\n\t\t\tpromise,\n\t\t\tresolve,\n\t\t};\n\n\t\tconst queries: { [key: string]: QueryDelta<T> } = {};\n\t\tObject.entries(this.options.queries ?? {}).forEach(([queryKey, query]) => {\n\t\t\tqueries[queryKey] = this.buildQueryDelta(queryKey, query);\n\t\t});\n\t\tconst message: EntitySystemWorkerMessage<W, D> = {\n\t\t\ttype: 'load',\n\t\t\tdata: this.options.getInitData?.(),\n\t\t\tgameTime: this.gameTime,\n\t\t\tentities: this.buildQueryDelta(MAIN_QUERY_NAME, this.options),\n\t\t\tqueries,\n\t\t\t// Only a real worker needs the buffers to rebuild a heap, plus the pools + eid counter to allocate off-thread.\n\t\t\theap: this.isWorkerThread ? this.world.heap.getSharedMemory() : undefined,\n\t\t\tsharedMemory: this.isWorkerThread ? this.world.getSharedComponentMemory() : undefined,\n\t\t\t// Factory templates only go to workers that create entities.\n\t\t\tfactoryConfigs: this.isWorkerThread && this.options.createsEntities ? this.world.factory.configs : undefined,\n\t\t\tfactoryClasses: this.isWorkerThread && this.options.createsEntities ? this.world.factory.getWorkerClasses() : undefined,\n\t\t\taddsComponents: !!this.options.addsComponents,\n\t\t};\n\t\tthis.worker.postMessage(message);\n\n\t\treturn promise;\n\t}\n\n\t// Un-initializes the system so its world can be reused\n\tclear() {\n\t\tsuper.clear();\n\t\tthis.pendingEffects?.discard();\n\n\t\tif(this.isRunning) {\n\t\t\tif(!this.runCompletePromise) {\n\t\t\t\tconst { promise, resolve } = Promise.withResolvers<void>();\n\t\t\t\tthis.runCompletePromise = { promise, resolve };\n\t\t\t}\n\t\t}\n\t\tthis.isRunning = false;\n\t\tthis.generation++;\n\n\t\tthis.entities.clear();\n\t\tObject.values(this.queryEntities).forEach(list => list.clear());\n\t\tthis.queryDeltas = {};\n\t\tthis.workPass = undefined;\n\t\tthis.timingBatch = undefined;\n\n\t\tconst message: EntitySystemWorkerMessage = { type: 'reset' };\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tupdate(elapsedTime: number): boolean {\n\t\tif(this.isRunning) {\n\t\t\tthis.currentDelta += elapsedTime;\n\n\t\t\treturn false;\n\t\t} else if(this.workPass) {\n\t\t\tthis.currentDelta += elapsedTime;\n\t\t\tthis.run(this.workPass.elapsedTime);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn super.update(elapsedTime);\n\t\t}\n\t}\n\t// A run finishes off-thread, not when update() returns; completedRuns is bumped on the worker's run-complete.\n\tprotected onRunFinished() {}\n\tisCurrentlyRunning(): boolean {\n\t\treturn this.isRunning;\n\t}\n\tget readComponents(): ReadonlyArray<PropertyKey> {\n\t\tconst queries = [this.options, ...Object.values(this.options.queries ?? {})];\n\t\treturn ['entity', ...this.reads ?? [], ...queries.flatMap(query => [...query.required, ...query.optional ?? []])];\n\t}\n\tget requiresExclusiveScheduling(): boolean {\n\t\treturn super.requiresExclusiveScheduling || this.options.createsEntities === true || !!this.options.addsComponents;\n\t}\n\tget createdComponents(): ReadonlyArray<PropertyKey> {\n\t\tconst components = this.options.createsEntities;\n\t\treturn components && typeof components !== 'boolean' ? ['entity', ...components] : [];\n\t}\n\tget creationReadComponents(): ReadonlyArray<PropertyKey> {\n\t\tconst queries = Object.values(this.options.queries ?? {});\n\t\tif(this.tracksMainQuery) {\n\t\t\tqueries.push(this.options);\n\t\t}\n\t\treturn [...this.reads ?? [], ...queries.flatMap(query => {\n\t\t\tconst required = query.required.filter(component => component !== 'entity');\n\t\t\tconst optional = query.optional?.filter(component => component !== 'entity') ?? [];\n\t\t\t// With another required component, reading dead flags does not make this an all-entity query.\n\t\t\treturn [...required.length ? required : ['entity'], ...optional, ...query.not ?? []];\n\t\t})];\n\t}\n\tget creationReadQueries(): ReadonlyArray<ReadonlyArray<PropertyKey>> | undefined {\n\t\tif(this.checkAddEntity !== EntityWorkerSystem.prototype.checkAddEntity || this.matchesQuery !== EntityWorkerSystem.prototype.matchesQuery) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst queries = Object.values(this.options.queries ?? {});\n\t\tif(this.tracksMainQuery) {\n\t\t\tqueries.push(this.options);\n\t\t}\n\t\treturn queries.map(query => query.required);\n\t}\n\twaitForRunToComplete(): void | Promise<void> {\n\t\tif(!this.isRunning) {\n\t\t\treturn;\n\t\t}\n\t\tif(!this.runCompletePromise) {\n\t\t\tconst { promise, resolve } = Promise.withResolvers<void>();\n\t\t\tthis.runCompletePromise = { promise, resolve };\n\t\t}\n\t\treturn this.runCompletePromise.promise;\n\t}\n\trun(elapsedTime: number): void {\n\t\tlet workBatch: Extract<EntitySystemWorkerMessage, { type: 'run' }>['workBatch'];\n\t\tlet gameTime = this.gameTime;\n\t\tif(this.options.workBatchSize !== undefined && this.tracksMainQuery) {\n\t\t\tconst first = !this.workPass;\n\t\t\tconst pass = this.workPass ??= { entities: Array.from(this.entities.values()), cursor: 0, elapsedTime, gameTime };\n\t\t\tgameTime = pass.gameTime;\n\t\t\telapsedTime = pass.elapsedTime;\n\t\t\tconst end = Math.min(pass.cursor + this.options.workBatchSize, pass.entities.length);\n\t\t\tconst entityIds: Array<number> = [];\n\t\t\tfor(; pass.cursor < end; pass.cursor++) {\n\t\t\t\tconst entity = pass.entities[pass.cursor];\n\t\t\t\tif(this.entities.get(entity.eid) === entity) {\n\t\t\t\t\tentityIds.push(entity.eid);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst last = pass.cursor === pass.entities.length;\n\t\t\tworkBatch = { entityIds, first, last };\n\t\t\tif(last) {\n\t\t\t\tthis.workPass = undefined;\n\t\t\t}\n\t\t}\n\t\tconst world = {\n\t\t\tgameTime,\n\t\t\telapsedTime,\n\t\t} as W;\n\t\tif(!workBatch || workBatch.first) {\n\t\t\tthis.addDataToWorld?.(world);\n\t\t}\n\n\t\tthis.timingBatch = workBatch && { first: workBatch.first, last: workBatch.last };\n\t\tthis.isRunning = true;\n\t\tthis.completeEffects = this.world.scheduler.prepareEffects?.(this.world, this);\n\t\tlet entities = this.buildQueryDelta(MAIN_QUERY_NAME, this.options);\n\t\tlet queries: { [key: string]: QueryDelta<T> } = {};\n\t\tObject.entries(this.options.queries ?? {}).forEach(([queryKey, query]) => {\n\t\t\tqueries[queryKey] = this.buildQueryDelta(queryKey, query);\n\t\t});\n\t\tlet message: EntitySystemWorkerMessage<W> = {\n\t\t\ttype: 'run',\n\t\t\tgeneration: this.generation,\n\t\t\tworld,\n\t\t\tentities,\n\t\t\tqueries,\n\t\t\tworkBatch,\n\t\t};\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tprivate buildQueryDelta(queryName: string, query: EntityWorkerSystemQuery<C>): QueryDelta<T> {\n\t\tconst delta = this.getQueryDelta(queryName);\n\t\tconst added: Array<UpdateEntityConfigObject<T>> = [];\n\t\tdelta.added.forEach(entity => {\n\t\t\tadded.push({\n\t\t\t\tentityId: entity.eid,\n\t\t\t\tcomponents: this.buildComponents(entity, query),\n\t\t\t});\n\t\t});\n\t\tconst removed = Array.from(delta.removed);\n\t\tthis.queryDeltas[queryName] = { added: new Set(), removed: new Set() };\n\n\t\treturn { added, removed };\n\t}\n\tprivate buildComponents(entity: BaseEntity<C>, query: EntityWorkerSystemQuery<C>): T {\n\t\tconst components = {} as T;\n\t\t[\n\t\t\t...query.required,\n\t\t\t...query.optional ?? [],\n\t\t].forEach(componentName => {\n\t\t\t// Reuse the view cached on the accessor at attach: getBlock allocates a fresh subarray every call and an\n\t\t\t// entity joins many systems, so re-looking it up here per system was a measurable spawn-time cost.\n\t\t\tconst block = entity.components[componentName]?.block;\n\t\t\tif(block) {\n\t\t\t\tcomponents[componentName] = block as T[typeof componentName];\n\t\t\t}\n\t\t});\n\n\t\treturn components;\n\t}\n\n\tisEntityInSystem(entity: BaseEntity<C>) {\n\t\treturn this.entities.has(entity.eid);\n\t}\n\tprotected matchesQuery(entity: BaseEntity<C>, query: EntityWorkerSystemQuery<C>): boolean {\n\t\tif(entity.components.entity.dead) {\n\t\t\treturn false;\n\t\t}\n\t\tif(!this.matchesComponents(entity, query)) {\n\t\t\treturn false;\n\t\t}\n\t\tif(query.filter && !query.filter(entity)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\tprivate matchesComponents(entity: BaseEntity<C>, query: EntityWorkerSystemQuery<C>): boolean {\n\t\tif(query.required.find(component => !entity.components[component])) {\n\t\t\treturn false;\n\t\t}\n\t\tif(query.not?.find(component => !!entity.components[component])) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\tprivate getQueryDelta(queryName: string): MembershipDelta<C> {\n\t\tlet delta = this.queryDeltas[queryName];\n\t\tif(!delta) {\n\t\t\tdelta = this.queryDeltas[queryName] = { added: new Set(), removed: new Set() };\n\t\t}\n\n\t\treturn delta;\n\t}\n\t// A pending removal this same frame is cancelled, so the net effect is a re-send rather than remove+add churn.\n\tprivate markAdded(delta: MembershipDelta<C>, entity: BaseEntity<C>) {\n\t\tdelta.removed.delete(entity.eid);\n\t\tdelta.added.add(entity);\n\t}\n\tprivate markRemoved(delta: MembershipDelta<C>, entity: BaseEntity<C>) {\n\t\tif(delta.added.delete(entity)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdelta.removed.add(entity.eid);\n\t}\n\tprotected updateEntityList(queryName: string, list: Map<number, BaseEntity<C>>, entity: BaseEntity<C>, shouldInclude: boolean) {\n\t\tconst delta = this.getQueryDelta(queryName);\n\t\tif(shouldInclude) {\n\t\t\tlist.set(entity.eid, entity);\n\t\t\tthis.markAdded(delta, entity);\n\t\t} else if(list.delete(entity.eid)) {\n\t\t\tthis.markRemoved(delta, entity);\n\t\t}\n\t}\n\n\t// WorkerSystem has no main query: its empty `required` would otherwise match every entity.\n\tprotected get tracksMainQuery(): boolean {\n\t\treturn true;\n\t}\n\n\tcheckAddEntity(entity: BaseEntity<C>): boolean {\n\t\tconst shouldAddToMain = this.tracksMainQuery && this.matchesQuery(entity, this.options);\n\t\tthis.updateEntityList(MAIN_QUERY_NAME, this.entities, entity, shouldAddToMain);\n\n\t\tObject.entries(this.options.queries ?? {}).forEach(([queryName, query]) => {\n\t\t\tconst queryList = this.queryEntities[queryName] ?? (this.queryEntities[queryName] = new Map());\n\t\t\tthis.updateEntityList(queryName, queryList, entity, this.matchesQuery(entity, query));\n\t\t});\n\n\t\treturn shouldAddToMain;\n\t}\n\taddEntities(batch: EntityBatch<C>): void {\n\t\t// A subclass with its own membership rule gets it applied per entity, exactly as entity-added would.\n\t\tif(this.checkAddEntity !== EntityWorkerSystem.prototype.checkAddEntity || this.matchesQuery !== EntityWorkerSystem.prototype.matchesQuery) {\n\t\t\tbatch.entities.forEach(entity => this.checkAddEntity(entity));\n\t\t\treturn;\n\t\t}\n\n\t\tif(this.tracksMainQuery) {\n\t\t\tthis.addBatchToQuery(MAIN_QUERY_NAME, this.entities, this.options, batch);\n\t\t}\n\t\tObject.entries(this.options.queries ?? {}).forEach(([queryName, query]) => {\n\t\t\tconst queryList = this.queryEntities[queryName] ?? (this.queryEntities[queryName] = new Map());\n\t\t\tthis.addBatchToQuery(queryName, queryList, query, batch);\n\t\t});\n\t}\n\tprivate addBatchToQuery(queryName: string, list: Map<number, BaseEntity<C>>, query: EntityWorkerSystemQuery<C>, batch: EntityBatch<C>) {\n\t\tconst delta = this.getQueryDelta(queryName);\n\t\tforEachInMatchingGroups(batch, entity => this.matchesComponents(entity, query), entity => {\n\t\t\tif(entity.components.entity.dead || (query.filter && !query.filter(entity))) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlist.set(entity.eid, entity);\n\t\t\tthis.markAdded(delta, entity);\n\t\t});\n\t}\n\n\tremoveEntity(entity: BaseEntity<C>) {\n\t\tthis.updateEntityList(MAIN_QUERY_NAME, this.entities, entity, false);\n\t\tObject.entries(this.queryEntities).forEach(([queryName, list]) => {\n\t\t\tthis.updateEntityList(queryName, list, entity, false);\n\t\t});\n\t}\n\n\t// Re-evaluates every entity's membership against the current queries. Needed when a `filter` closes over mutable\n\t// state (e.g. a scope keyed on which group is active) and that state changes with no entity event to react to\n\trecheckMembership() {\n\t\tthis.world.entities.forEach(entity => {\n\t\t\tthis.checkAddEntity(entity);\n\t\t});\n\t}\n\n\tshouldRun(): boolean {\n\t\treturn this.workPass !== undefined || this.entities.size > 0;\n\t}\n\n\tdestroy() {\n\t\tsuper.destroy();\n\t\tthis.pendingEffects?.discard();\n\n\t\tif('terminate' in this.worker) {\n\t\t\tthis.worker.terminate();\n\t\t}\n\t}\n}\n\ninterface Resolvable {\n\tpromise: Promise<void>\n\tresolve: (value: void | PromiseLike<void>) => void\n}\n\nexport type EntityUpdateComponents<C extends ComponentMap = ComponentMap> = { [K in keyof C]?: ComponentTypedArray };\nexport type EntityQueryComponents<C extends ComponentMap = ComponentMap> = { [key: string]: Array<{ entityId: number, components: EntityUpdateComponents<C> }> };\ntype EntityUpdateFunctionImpl<C extends ComponentMap, T extends EntityUpdateComponents<C>, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld> = (\n\tworld: W,\n\tentityId: number,\n\tcomponents: T,\n\tqueries: EntityQueryComponents<C>,\n\tcallbacks: EntityWorkerSystemCallbacks<C>,\n) => void;\nexport type EntityUpdateFunction<\n\tC extends ComponentMap,\n\tT extends EntityUpdateComponents<C>,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> = EntityUpdateFunctionImpl<C, T, W> & {\n\tqueryChanged?: EntityQueryChangedFunction<C, W>\n\tpreRun?: EntityUpdatePreRunFunction<C, T, W>\n\tpreBatch?: EntityUpdatePreRunFunction<C, T, W>\n\tentityRemoved?: EntityRemovedFunction<C, W>\n\tinit?: EntityUpdateInitFunction<W, D, C, T>\n};\n// Runs after the load's membership is applied, so `entities`/`queries` already hold every loaded entity.\nexport type EntityUpdateInitFunction<\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n\tC extends ComponentMap = ComponentMap,\n\tT extends EntityUpdateComponents<C> = EntityUpdateComponents<C>,\n> = (\n\tworld: EntityWorkerSystemInitWorld,\n\tdata: D | undefined,\n\tentities: Array<UpdateEntityConfigObject<T>>,\n\tqueries: EntityQueryComponents<C>,\n) => Partial<W> | void;\nexport type EntityUpdatePreRunFunction<C extends ComponentMap, T extends EntityUpdateComponents<C>, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld> = (\n\tworld: W,\n\tentities: Array<UpdateEntityConfigObject<T>>,\n\tqueries: EntityQueryComponents<C>,\n\tcallbacks: EntityWorkerSystemCallbacks<C>,\n) => void;\n// Called once per sub-query whose membership changed this run, before preRun. `added` can repeat an entity already\n// in the query (its component bundle was refreshed), so treat it as an upsert.\nexport type EntityQueryChangedFunction<C extends ComponentMap = ComponentMap, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld> = (\n\tworld: W,\n\tqueryName: string,\n\tdelta: QueryDelta<EntityUpdateComponents<C>>,\n\tcallbacks: EntityWorkerSystemCallbacks<C>,\n) => void;\nexport type EntityRemovedFunction<C extends ComponentMap = ComponentMap, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld> = (\n\tworld: W,\n\tentityId: number,\n\tcallbacks: EntityWorkerSystemCallbacks<C>,\n) => void;\nexport type UpdateEntityConfig<T extends EntityUpdateComponents = EntityUpdateComponents> = number | UpdateEntityConfigObject<T>;\nexport type UpdateEntityConfigObject<T extends EntityUpdateComponents> = {\n\tentityId: number\n\tcomponents: T\n};\n\nexport interface QueryDelta<T extends EntityUpdateComponents = EntityUpdateComponents> {\n\tadded: Array<UpdateEntityConfigObject<T>>\n\tremoved: Array<number>\n}\n// Sets so queuing can check for an already-queued or opposite change without scanning a growing array.\ninterface MembershipDelta<C extends ComponentMap> {\n\tadded: Set<BaseEntity<C>>\n\tremoved: Set<number>\n}\n\n// Low-level off-thread allocation primitives, injected onto the worker `world` each run. `allocateEid` mints a\n// heap-unique id; `allocateComponentBlock` pushes a block into a component's shared pool and returns its index.\n// These are the foundation a future worker-side createEntity builds on (allocate + write blocks, then report the\n// eid/indexes back for the main thread to adopt).\nexport interface WorkerAllocator {\n\tallocateEid(): number\n\tallocateComponentBlock(name: string, values: Array<number>): number\n}\n\n// No callbacks or elapsedTime: init only seeds worker-local state, outside any run.\nexport type EntityWorkerSystemInitWorld = Pick<EntityWorkerSystemWorld, 'gameTime' | 'getString' | 'heap'>;\n\nexport interface EntityWorkerSystemWorld {\n\tgameTime: number\n\telapsedTime: number\n\tgetString(pointer: number): string\n\t// The reconstructed heap (real worker) or the shared main-thread heap (fallback), injected each run so an\n\t// update function can rebuild heap-backed structures (a SharedMap/SharedList) from a pointer in a component\n\t// block. Undefined only before the first run.\n\theap?: MemoryHeap\n\tallocate?: WorkerAllocator\n\t// Injected each run on a system registered with createsEntities: builds a WorkerCreatedEntity descriptor from a\n\t// factory config (merges the type's template, allocates + writes each component's block). Drives createEntityWorker.\n\tbuildEntityDescriptor?(config: WorkerCreateEntityConfig): WorkerCreatedEntity\n\t// Injected for systems with addsComponents. Allocates/writes a block off-thread; the main thread attaches it\n\t// after run completion so no running update observes a changing component set.\n\tbuildComponentDescriptor?(name: string, config: Record<string, unknown>): WorkerCreatedComponent\n}\n// What a game passes to createEntityWorker: a factory-style config - the entity `type` plus any overrides layered\n// over that type's factory template. The worker merges template + overrides, then allocates + writes each triggered\n// component's block off-thread via the component's toBlock(config). The \"entity\" component is built on the main\n// thread when the descriptor is adopted, since interning the type is main-thread-only.\nexport type WorkerCreateEntityConfig = { type: string, class?: never } & { [key: string]: unknown };\n// The result reported back on run-complete: the minted id plus, per game component, the pool index the worker\n// allocated. world.adoptEntity turns this into a real BaseEntity.\nexport interface WorkerCreatedEntity {\n\teid: number\n\ttype: string\n\tclass?: string\n\tisStatic?: boolean\n\tcomponents: { [name: string]: number }\n}\n\nexport interface WorkerCreatedComponent {\n\tname: string\n\tindex: number\n}\n\nexport type WorkerComponentChange =\n\t| { type: 'add', entityId: number, component: WorkerCreatedComponent }\n\t| { type: 'remove', entityId: number, componentName: string };\n\nexport interface EntityWorkerSystemCallbacks<C extends ComponentMap = ComponentMap> {\n\tentityComponentChanged<K extends keyof C, P extends keyof C[K]>(entityId: number, componentName: K, prop: P, value: C[K][P]): void\n\t// Args are structured-cloned, so plain values only.\n\temitEntityEvent(entityId: number, event: string, ...args: Array<unknown>): void\n\t// Emitted **on the system** with all its ids in one array. The allocation-free path for something that\n\t// happens to most entities every run; carries no args (values are already in shared memory).\n\temitSystemEvent(event: string, entityId: number): void\n\tentityDied(entityId: number): void\n\tcreateEntity(entity: WorkerCreatedEntity): void\n\taddComponent(entityId: number, component: WorkerCreatedComponent): void\n\tremoveComponent<K extends keyof C>(entityId: number, componentName: K): void\n}\n\nexport interface EntityWorkerSystemQuery<C extends ComponentMap = ComponentMap> {\n\trequired: Array<keyof C>\n\toptional?: Array<keyof C>\n\tnot?: Array<keyof C>\n\tfilter?: (entity: BaseEntity<C>) => boolean\n}\n\nexport interface EntityWorkerSystemConfig<\n\tC extends ComponentMap,\n\tT extends EntityUpdateComponents<C>,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> extends SystemConfig<C>, EntityWorkerSystemQuery<C> {\n\t// Each batch publishes independently; preRun and the logical delta/clock belong to the whole pass.\n\tworkBatchSize?: number\n\tupdateFunction: EntityUpdateFunction<C, T, W, D>\n\tgetWorker: () => Worker\n\tforceMainThread?: boolean\n\tgetInitData?: () => D\n\t// Opt in to worker-side entity creation (createEntityWorker). When set, factory templates and serializable class\n\t// allowlists are shipped to this system's worker; the worker entry must also pass the component registry to\n\t// createEntitySystemWorker so it has each component's toBlock(). Only systems that create entities need either.\n\t// A component list declares publication access for ConflictScheduler; true stays exclusive there.\n\tcreatesEntities?: boolean | ReadonlyArray<keyof C>\n\t// Opt in to worker-side component allocation through addComponentWorker. The worker entry must also pass the\n\t// component registry to createEntitySystemWorker so the worker has each component's toBlock().\n\taddsComponents?: boolean\n\n\tqueries?: { [key: string]: EntityWorkerSystemQuery<C> }\n}\n\nexport type { BaseComponent };\n\ntype WorkerRunCompletion = Extract<EntitySystemWorkerMessage, { type: 'run-complete' }>;\n","import { EventEmitter } from 'eventemitter3';\nimport type BaseWorld from './world';\nimport type { BaseComponent, ComponentDefinitionMap, ComponentMap, RegisteredComponentRegistry } from './component-definition';\nimport type { EntityComponent } from './entity-component';\n\nexport default class BaseEntity<C extends ComponentMap = ComponentMap, Cfg = any> extends EventEmitter {\n\treadonly eid: number;\n\tconfig?: Cfg;\n\n\tworld: BaseWorld<ComponentDefinitionMap, C, Cfg>;\n\tprivate componentMemoryDeletionScheduled = false;\n\tprivate allowedComponents?: ReadonlySet<string>;\n\t// entity is always present; game components are partial.\n\tcomponents: Partial<C> & { entity: EntityComponent } = {} as Partial<C> & { entity: EntityComponent };\n\n\t// `adoptEid`: build an empty shell around a pre-minted id (an entity a worker created off-thread), skipping the\n\t// automatic entity-component load - the caller (world.adoptEntity) loads the entity component and attaches the\n\t// worker-allocated blocks itself.\n\tconstructor(\n\t\tworld: BaseWorld<ComponentDefinitionMap, C, Cfg>,\n\t\tconfig?: Cfg,\n\t\tadoptEid?: number,\n\t\tallowedComponents?: ReadonlySet<string>,\n\t) {\n\t\tsuper();\n\n\t\tthis.world = world;\n\t\tthis.eid = adoptEid ?? world.allocateEid();\n\t\tthis.allowedComponents = allowedComponents ?? world.factory.getAllowedComponentsForConfig(config);\n\t\tif(adoptEid !== undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.loadComponent('entity', config ?? {}, false);\n\t\tif(config) {\n\t\t\tthis.load(config);\n\t\t}\n\t}\n\tget id(): number {\n\t\treturn this.eid;\n\t}\n\tget dead(): boolean {\n\t\treturn this.components.entity.dead;\n\t}\n\tget type(): string {\n\t\treturn this.components.entity.type;\n\t}\n\n\tloadComponent<K extends keyof C>(name: K, config: any, emitAdded = true): C[K] {\n\t\tthis.assertComponentAllowed(name);\n\t\tconst definition = (this.world.registry as RegisteredComponentRegistry<C>)[name];\n\t\tconst memoryComponent = definition.memoryComponent;\n\t\tconst index = memoryComponent.create(definition.toBlock(config, this));\n\t\tconst component = definition.attach(this, memoryComponent, index, config);\n\t\t// A Component subclass already holds its block; only fetch one for a plain-object accessor that didn't.\n\t\t(component as BaseComponent).block ??= memoryComponent.getBlock(index);\n\t\t(this.components as Partial<C>)[name] = component;\n\t\tif(emitAdded) {\n\t\t\tthis.emit('component-added', name, component);\n\t\t}\n\n\t\treturn component;\n\t}\n\t// Builds an accessor over an existing block (allocated + written by a worker) instead of creating a new one - the\n\t// adopt half of loadComponent, without the create.\n\tattachComponent<K extends keyof C>(name: K, index: number, emitAdded = false): C[K] {\n\t\tthis.assertComponentAllowed(name);\n\t\tconst definition = (this.world.registry as RegisteredComponentRegistry<C>)[name];\n\t\tconst component = definition.attach(this, definition.memoryComponent, index);\n\t\t(component as BaseComponent).block ??= definition.memoryComponent.getBlock(index);\n\t\t(this.components as Partial<C>)[name] = component;\n\t\tif(emitAdded) {\n\t\t\tthis.emit('component-added', name, component);\n\t\t}\n\t\treturn component;\n\t}\n\tremoveComponent<K extends keyof C>(name: K) {\n\t\tif(this.componentMemoryDeletionScheduled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst component = (this.components as Partial<C>)[name];\n\t\tif(component) {\n\t\t\tconst definition = (this.world.registry as RegisteredComponentRegistry<C>)[name];\n\t\t\tthis.world.deferComponentMemoryFree(definition.memoryComponent, component.index, definition.free ? () => definition.free!(component) : undefined);\n\t\t\tdelete this.components[name];\n\t\t\tthis.emit('component-removed', name);\n\t\t}\n\t}\n\tsetComponent<K extends keyof C, P extends keyof C[K]>(componentName: K, prop: P, value: C[K][P]) {\n\t\tthis.assertComponentPropertyMutable(componentName, prop);\n\t\tconst component = this.components[componentName];\n\t\tif(!component) {\n\t\t\treturn;\n\t\t}\n\n\t\t(component as unknown as Record<P, C[K][P]>)[prop] = value;\n\t\tthis.emit('component-property-updated', componentName, prop, value);\n\t}\n\t/**\n\t * NOTE: Does not emit component-property-updated!\n\t */\n\tsetComponentBulk<K extends keyof C>(componentName: K, values: Partial<C[K]>) {\n\t\tfor(const prop of Object.keys(values)) {\n\t\t\tthis.assertComponentPropertyMutable(componentName, prop);\n\t\t}\n\t\tconst component = this.components[componentName];\n\t\tif(!component) {\n\t\t\treturn;\n\t\t}\n\n\t\tObject.assign(component, values);\n\t}\n\tdeleteComponent<K extends keyof C>(componentName: K, prop: keyof C[K]) {\n\t\tthis.assertComponentPropertyMutable(componentName, prop);\n\t\tconst component = this.components[componentName];\n\t\tif(!component) {\n\t\t\treturn;\n\t\t}\n\n\t\tdelete (component as Partial<C[K]>)[prop];\n\t\tthis.emit('component-property-deleted', componentName, prop);\n\t}\n\n\tdeleteAllComponentMemory() {\n\t\tif(this.componentMemoryDeletionScheduled) {\n\t\t\treturn;\n\t\t}\n\t\tthis.componentMemoryDeletionScheduled = true;\n\n\t\tconst registry = this.world.registry as RegisteredComponentRegistry<C>;\n\t\tconst components = this.components as Partial<C>;\n\t\tfor(let name of Object.keys(components) as Array<keyof C>) {\n\t\t\tconst definition = registry[name];\n\t\t\tconst component = components[name];\n\t\t\tif(component) {\n\t\t\t\tthis.world.deferComponentMemoryFree(definition.memoryComponent, component.index, definition.free ? () => definition.free!(component) : undefined);\n\t\t\t}\n\t\t}\n\t}\n\n\tload(config: Cfg) {\n\t\tconst props = config as Record<string, unknown>;\n\t\tconst registry = this.world.registry as RegisteredComponentRegistry<C>;\n\t\tfor(let name of Object.keys(registry) as Array<keyof C>) {\n\t\t\tif(name === 'entity') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(!this.isComponentAllowed(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst definition = registry[name];\n\t\t\tif(definition.loadInFinishLoading) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(definition.loadProperties.some(prop => prop in props)) {\n\t\t\t\tthis.loadComponent(name, config, false);\n\t\t\t}\n\t\t}\n\n\t\tthis.config = config;\n\t}\n\tsave(): Cfg {\n\t\tconst config: { [key: string]: any } = {};\n\n\t\tconst registry = this.world.registry as RegisteredComponentRegistry<C>;\n\t\tconst components = this.components as Partial<C>;\n\t\tfor(let name of Object.keys(components) as Array<keyof C>) {\n\t\t\tconst definition = registry[name];\n\t\t\tconst component = components[name];\n\t\t\tif(definition.save && component) {\n\t\t\t\tObject.assign(config, definition.save(component));\n\t\t\t}\n\t\t}\n\n\t\treturn config as Cfg;\n\t}\n\t// Second pass once every entity in a load batch exists; loads the deferred (loadInFinishLoading)\n\t// components load skipped. Overrides should call super.\n\tfinishLoading() {\n\t\tconst config = this.config;\n\t\tif(!config) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst props = config as Record<string, unknown>;\n\t\tconst registry = this.world.registry as RegisteredComponentRegistry<C>;\n\t\tfor(let name of Object.keys(registry) as Array<keyof C>) {\n\t\t\tif(name === 'entity') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(!this.isComponentAllowed(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst definition = registry[name];\n\t\t\tif(definition.loadInFinishLoading && definition.loadProperties.some(prop => prop in props)) {\n\t\t\t\tthis.loadComponent(name, config, false);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate isComponentAllowed(name: keyof C): boolean {\n\t\treturn name === 'entity' || !this.allowedComponents || this.allowedComponents.has(String(name));\n\t}\n\tsetAllowedComponents(allowedComponents: ReadonlySet<string> | undefined): void {\n\t\tif(this.allowedComponents && this.allowedComponents !== allowedComponents) {\n\t\t\tthrow new Error('Entity component allowlist is immutable');\n\t\t}\n\t\tthis.allowedComponents = allowedComponents;\n\t}\n\tprivate assertComponentAllowed(name: keyof C): void {\n\t\tif(!this.isComponentAllowed(name)) {\n\t\t\tthrow new Error(`Component ${String(name)} is not allowed for entity type ${this.type}`);\n\t\t}\n\t}\n\tprivate assertComponentPropertyMutable(componentName: keyof C, prop: PropertyKey): void {\n\t\tif(componentName === 'entity' && (prop === 'type' || prop === 'class')) {\n\t\t\tthrow new Error(`Entity ${prop} is immutable`);\n\t\t}\n\t}\n}\n","import BaseEntity from './entity';\nimport type BaseWorld from './world';\nimport type { ComponentDefinitionMap, ComponentMap } from './component-definition';\nimport type { EntityClassDefinition, EntityClassRegistry, WorkerEntityClassRegistry } from './entity-class';\n\n// Maps type to a template and optionally maps the template's class to a wrapper + component allowlist.\nexport default class EntityFactory<\n\tC extends ComponentMap = ComponentMap,\n\tCfg = any,\n\tE extends BaseEntity<C, Cfg> = BaseEntity<C, Cfg>,\n> {\n\tworld!: BaseWorld<ComponentDefinitionMap, C, Cfg, E>;\n\tconfigs: { [type: string]: Cfg };\n\tclasses: EntityClassRegistry;\n\tprivate allowedComponents = new Map<string, ReadonlySet<string>>();\n\tprivate forbiddenProperties = new Map<string, ReadonlySet<string>>();\n\n\tconstructor(configs: { [type: string]: Cfg } = {}, classes: EntityClassRegistry = {}) {\n\t\tthis.configs = configs;\n\t\tthis.classes = classes;\n\t\tfor(const name of Object.keys(classes)) {\n\t\t\tthis.allowedComponents.set(name, new Set(classes[name].components));\n\t\t}\n\t}\n\n\tregister(type: string, config: Cfg) {\n\t\tif(this.world) {\n\t\t\tthis.validateTemplate(type, config);\n\t\t}\n\t\tthis.configs[type] = config;\n\t}\n\n\tsetWorld(world: BaseWorld<ComponentDefinitionMap, C, Cfg, E>): void {\n\t\tthis.world = world;\n\t\tthis.forbiddenProperties.clear();\n\t\tfor(const name of Object.keys(this.classes)) {\n\t\t\tconst constructor = this.classes[name].entity;\n\t\t\tif(constructor !== BaseEntity && !(constructor.prototype instanceof BaseEntity)) {\n\t\t\t\tthrow new Error(`Entity class ${name} must extend BaseEntity`);\n\t\t\t}\n\t\t\tfor(const component of this.classes[name].components) {\n\t\t\t\tif(component === 'entity' || !(component in world.registry)) {\n\t\t\t\t\tthrow new Error(`Entity class ${name} contains unknown or reserved component ${component}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor(const type of Object.keys(this.configs)) {\n\t\t\tthis.validateTemplate(type, this.configs[type]);\n\t\t}\n\t}\n\n\tgetConfig(config: Cfg): Cfg {\n\t\tconst input = config as { type?: string, class?: unknown } | undefined;\n\t\tconst type = input?.type;\n\t\tconst base = type ? this.configs[type] : undefined;\n\t\tif(this.hasClasses) {\n\t\t\tif(!type || !base) {\n\t\t\t\tthrow new Error(`Unknown entity type: ${type ?? ''}`);\n\t\t\t}\n\t\t\tif(Object.prototype.hasOwnProperty.call(input, 'class')) {\n\t\t\t\tthrow new Error('Entity class comes from its type template and cannot be supplied by an instance config');\n\t\t\t}\n\t\t}\n\t\tconst merged = base ? { ...base, ...config } : config;\n\t\tif(this.hasClasses && type) {\n\t\t\tthis.validateResolvedConfig(type, merged);\n\t\t}\n\t\treturn merged;\n\t}\n\n\tloadEntity(config: Cfg, created = true): E {\n\t\tconst requestedType = (config as { type?: string }).type;\n\t\tconst merged = this.getConfig(config);\n\t\t// The base getConfig already validated; only an override can have changed the result since.\n\t\tif(this.hasClasses && requestedType && this.getConfig !== EntityFactory.prototype.getConfig) {\n\t\t\tthis.validateResolvedConfig(requestedType, merged);\n\t\t}\n\t\tconst definition = this.getClassDefinition(merged);\n\t\tconst entity = definition\n\t\t\t? this.constructEntity(definition, merged)\n\t\t\t: this.createEntity(merged);\n\t\treturn this.world.addEntity(entity, created);\n\t}\n\n\tcreateAdoptedEntity(type: string, entityClass: string | undefined, eid: number): E {\n\t\tif(!entityClass) {\n\t\t\tif(this.hasClasses) {\n\t\t\t\tthrow new Error(`Entity type ${type} has no class`);\n\t\t\t}\n\t\t\treturn new BaseEntity<C, Cfg>(this.world, undefined, eid) as E;\n\t\t}\n\t\tconst definition = this.classes[entityClass];\n\t\tif(!definition) {\n\t\t\tthrow new Error(`Unknown entity class: ${entityClass}`);\n\t\t}\n\t\tthis.validateTypeClass(type, entityClass);\n\t\tconst entity = Reflect.construct(definition.entity, [this.world, undefined, eid, this.allowedComponents.get(entityClass)]) as E;\n\t\tentity.setAllowedComponents(this.allowedComponents.get(entityClass));\n\t\treturn entity;\n\t}\n\n\tisComponentAllowed(entityClass: string | undefined, component: string): boolean {\n\t\treturn !entityClass || !this.hasClasses || this.allowedComponents.get(entityClass)?.has(component) === true;\n\t}\n\n\tgetWorkerClasses(): WorkerEntityClassRegistry | undefined {\n\t\tif(!this.hasClasses) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst classes: WorkerEntityClassRegistry = {};\n\t\tfor(const name of Object.keys(this.classes)) {\n\t\t\tclasses[name] = { components: [...this.classes[name].components] };\n\t\t}\n\t\treturn classes;\n\t}\n\n\tgetAllowedComponentsForConfig(config: Cfg | undefined): ReadonlySet<string> | undefined {\n\t\treturn config ? this.getAllowedComponents(config) : undefined;\n\t}\n\n\tprotected createEntity(config: Cfg): E {\n\t\treturn new BaseEntity<C, Cfg>(this.world, config) as E;\n\t}\n\n\tprivate get hasClasses(): boolean {\n\t\treturn this.allowedComponents.size > 0;\n\t}\n\tprivate getClassDefinition(config: Cfg): EntityClassDefinition | undefined {\n\t\tconst entityClass = (config as { class?: string }).class;\n\t\treturn entityClass ? this.classes[entityClass] : undefined;\n\t}\n\tprivate getAllowedComponents(config: Cfg): ReadonlySet<string> | undefined {\n\t\tconst entityClass = (config as { class?: string }).class;\n\t\treturn entityClass ? this.allowedComponents.get(entityClass) : undefined;\n\t}\n\tprivate constructEntity(definition: EntityClassDefinition, config: Cfg): E {\n\t\tconst entityClass = (config as { class?: string }).class;\n\t\treturn Reflect.construct(definition.entity, [this.world, config, undefined, this.allowedComponents.get(entityClass ?? '')]) as E;\n\t}\n\tprivate validateTemplate(type: string, config: Cfg): void {\n\t\tif(!this.hasClasses) {\n\t\t\treturn;\n\t\t}\n\t\tconst identity = config as { type?: string, class?: string };\n\t\tif(identity.type !== type) {\n\t\t\tthrow new Error(`Entity template ${type} must declare the same type`);\n\t\t}\n\t\tif(!identity.class || !this.classes[identity.class]) {\n\t\t\tthrow new Error(`Entity template ${type} has unknown class ${identity.class ?? ''}`);\n\t\t}\n\t\tthis.validateComponentTriggers(type, identity.class, config);\n\t}\n\tprivate validateResolvedConfig(type: string, config: Cfg): void {\n\t\tconst identity = config as { type?: string, class?: string };\n\t\tif(identity.type !== type) {\n\t\t\tthrow new Error(`Entity type ${type} is immutable`);\n\t\t}\n\t\tif(!identity.class || !this.classes[identity.class]) {\n\t\t\tthrow new Error(`Entity type ${type} has unknown class ${identity.class ?? ''}`);\n\t\t}\n\t\tthis.validateTypeClass(type, identity.class);\n\t\tthis.validateComponentTriggers(type, identity.class, config);\n\t}\n\tprivate validateTypeClass(type: string, entityClass: string): void {\n\t\tconst template = this.configs[type] as { class?: string } | undefined;\n\t\tif(!template || template.class !== entityClass) {\n\t\t\tthrow new Error(`Entity type ${type} does not belong to class ${entityClass}`);\n\t\t}\n\t}\n\tprivate validateComponentTriggers(type: string, entityClass: string, config: Cfg): void {\n\t\tconst forbidden = this.getForbiddenProperties(entityClass);\n\t\tfor(const prop in config as Record<string, unknown>) {\n\t\t\tif(forbidden.has(prop)) {\n\t\t\t\tthis.throwComponentTriggerError(type, entityClass, config);\n\t\t\t}\n\t\t}\n\t}\n\t// Per class: every property that would load a component outside its allowlist. Loads check each config key\n\t// against this instead of rescanning the registry.\n\tprivate getForbiddenProperties(entityClass: string): ReadonlySet<string> {\n\t\tlet forbidden = this.forbiddenProperties.get(entityClass);\n\t\tif(!forbidden) {\n\t\t\tconst allowed = this.allowedComponents.get(entityClass)!;\n\t\t\tconst allowedProperties = new Set<string>();\n\t\t\tfor(const component of allowed) {\n\t\t\t\tfor(const prop of this.world.registry[component as keyof C].loadProperties) {\n\t\t\t\t\tallowedProperties.add(prop);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst props = new Set<string>();\n\t\t\tfor(const name of Object.keys(this.world.registry)) {\n\t\t\t\tif(name === 'entity' || allowed.has(name)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tfor(const prop of this.world.registry[name as keyof C].loadProperties) {\n\t\t\t\t\tif(!allowedProperties.has(prop)) {\n\t\t\t\t\t\tprops.add(prop);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tforbidden = props;\n\t\t\tthis.forbiddenProperties.set(entityClass, forbidden);\n\t\t}\n\t\treturn forbidden;\n\t}\n\t// The original registry-order scan, kept for the failure path so the error names the same component as before.\n\tprivate throwComponentTriggerError(type: string, entityClass: string, config: Cfg): never {\n\t\tconst allowed = this.allowedComponents.get(entityClass)!;\n\t\tconst allowedProperties = new Set<string>();\n\t\tfor(const component of allowed) {\n\t\t\tfor(const prop of this.world.registry[component as keyof C].loadProperties) {\n\t\t\t\tallowedProperties.add(prop);\n\t\t\t}\n\t\t}\n\t\tconst props = config as Record<string, unknown>;\n\t\tfor(const name of Object.keys(this.world.registry)) {\n\t\t\tif(name === 'entity' || allowed.has(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst definition = this.world.registry[name as keyof C];\n\t\t\tconst forbidden = definition.loadProperties.find(prop => prop in props && !allowedProperties.has(prop));\n\t\t\tif(forbidden) {\n\t\t\t\tthrow new Error(`Entity type ${type} class ${entityClass} cannot load component ${name} from property ${forbidden}`);\n\t\t\t}\n\t\t}\n\t\tthrow new Error(`Entity type ${type} class ${entityClass} loads a component outside its class`);\n\t}\n}\n","// Packs flat entity configs that match a definition into short ASCII strings. Format (all chars JSON-safe ASCII):\n// a string is the definition key followed by one field per property in definition order, each field a value or ABSENT.\n// Trailing absent fields are omitted, so decoding an older string with a newer definition leaves new fields unset.\n// Varint: little-endian base-45 digits; every digit but the last comes from CONTINUATION, the last from TERMINAL.\n// A string value is its length as a varint then its raw characters (0 is null); only it can hold non-alphabet chars.\n// A definition sharing its properties across `types` at key n covers keys n, n + 1, ... in that order.\n\nexport type CompressedPropertyType = 'int' | 'uint' | 'boolean' | 'float32' | 'string';\n\nexport interface CompressedEntityProperty {\n\tname: string\n\ttype: CompressedPropertyType\n\t// int/uint decode as stored * step / 10 ** decimals + offset; e.g. step 32 + offset 16 for tile centres.\n\tstep?: number\n\tdecimals?: number\n\toffset?: number\n}\n\ninterface DefinitionProperties {\n\tproperties: ReadonlyArray<CompressedEntityProperty>\n}\nexport type CompressedEntityDefinition = DefinitionProperties & ({ type: string, types?: never } | { types: ReadonlyArray<string>, type?: never });\n\n// Keyed by the decimal key of a definition's first type; see the format note for shared definitions.\nexport type CompressedEntityDefinitions = Record<string, CompressedEntityDefinition>;\n\nexport interface CompressedEntities<Cfg> {\n\tentityDefinitions: CompressedEntityDefinitions\n\tentities: Array<Cfg | string>\n}\n\ntype CompressibleConfig = object & { type?: string };\ntype DecompressedValue = number | boolean | string | null;\n\nconst COMPRESSION_BASE = 45;\nconst ABSENT = '!';\n// '#'..'O' and 'P'..'}' without the backslash: no char JSON would escape.\nconst TERMINAL = '#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO';\nconst CONTINUATION = 'PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}';\n\n// Char code → digit for TERMINAL, digit + BASE for CONTINUATION, -1 otherwise.\nconst DIGITS = new Int8Array(128).fill(-1);\nfor(let i = 0; i < COMPRESSION_BASE; i++) {\n\tDIGITS[TERMINAL.charCodeAt(i)] = i;\n\tDIGITS[CONTINUATION.charCodeAt(i)] = i + COMPRESSION_BASE;\n}\n\nfunction encodeVarint(value: number): string {\n\tlet encoded = '';\n\twhile(value >= COMPRESSION_BASE) {\n\t\tencoded += CONTINUATION[value % COMPRESSION_BASE];\n\t\tvalue = Math.floor(value / COMPRESSION_BASE);\n\t}\n\treturn encoded + TERMINAL[value];\n}\n\nconst FLOAT_BITS = new Float32Array(1);\nconst UINT_BITS = new Uint32Array(FLOAT_BITS.buffer);\n\n// The field text for a value, or undefined when this property can't represent it exactly.\nfunction encodeField(property: CompressedEntityProperty, value: unknown): string | undefined {\n\tswitch(property.type) {\n\t\tcase 'boolean':\n\t\t\treturn typeof value === 'boolean' ? TERMINAL[Number(value)] : undefined;\n\t\tcase 'string':\n\t\t\tif(value === null) {\n\t\t\t\treturn TERMINAL[0];\n\t\t\t}\n\t\t\treturn typeof value === 'string' && value.length ? encodeVarint(value.length) + value : undefined;\n\t\tcase 'float32':\n\t\t\tif(typeof value !== 'number' || !Number.isFinite(value) || Math.fround(value) !== value) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tFLOAT_BITS[0] = value;\n\t\t\treturn encodeVarint(UINT_BITS[0]);\n\t\tdefault: {\n\t\t\tconst stored = integerValue(property, value);\n\t\t\treturn stored === undefined ? undefined : encodeVarint(stored);\n\t\t}\n\t}\n}\n\nfunction integerValue(property: CompressedEntityProperty, value: unknown): number | undefined {\n\tif(typeof value !== 'number') {\n\t\treturn undefined;\n\t}\n\tconst stored = Math.round((value - (property.offset ?? 0)) * 10 ** (property.decimals ?? 0) / (property.step ?? 1));\n\t// Rejects anything that doesn't decode exactly, including values only near the step through floating point error.\n\tif(!Number.isSafeInteger(stored) || scaled(property, stored) !== value) {\n\t\treturn undefined;\n\t}\n\tif(property.type === 'uint') {\n\t\treturn stored >= 0 ? stored : undefined;\n\t}\n\t// Zigzag so small negatives stay short.\n\tconst zigzag = stored >= 0 ? stored * 2 : -stored * 2 - 1;\n\treturn Number.isSafeInteger(zigzag) ? zigzag : undefined;\n}\n\n// Divides by a power of ten rather than multiplying by a fraction: 1234 / 100 is exactly 12.34, 1234 * 0.01 is not.\nfunction scaled(property: CompressedEntityProperty, stored: number) {\n\treturn stored * (property.step ?? 1) / 10 ** (property.decimals ?? 0) + (property.offset ?? 0);\n}\n\nfunction loadedValue(property: CompressedEntityProperty, stored: number): DecompressedValue {\n\tswitch(property.type) {\n\t\tcase 'boolean':\n\t\t\treturn stored !== 0;\n\t\tcase 'float32':\n\t\t\tUINT_BITS[0] = stored;\n\t\t\treturn FLOAT_BITS[0];\n\t\tcase 'uint':\n\t\t\treturn scaled(property, stored);\n\t\tdefault:\n\t\t\treturn scaled(property, stored % 2 === 0 ? stored / 2 : -(stored + 1) / 2);\n\t}\n}\n\nfunction typesOf(definition: CompressedEntityDefinition): ReadonlyArray<string> {\n\treturn definition.types !== undefined ? definition.types : [definition.type];\n}\n\ninterface DefinitionGroup {\n\tkey: number\n\tdefinition: CompressedEntityDefinition\n\tindices: Map<string, number>\n}\ninterface DefinitionEncoder {\n\tprefix: string\n\tgroup: DefinitionGroup\n}\n\nexport class EntityCompressor {\n\tprivate readonly encoders = new Map<string, DefinitionEncoder>();\n\tprivate readonly used = new Set<DefinitionGroup>();\n\n\tconstructor(definitions: ReadonlyArray<CompressedEntityDefinition>) {\n\t\tlet key = 0;\n\t\tfor(const definition of definitions) {\n\t\t\tconst group: DefinitionGroup = {\n\t\t\t\tkey,\n\t\t\t\tdefinition,\n\t\t\t\tindices: new Map(definition.properties.map((property, index) => [property.name, index])),\n\t\t\t};\n\t\t\tfor(const type of typesOf(definition)) {\n\t\t\t\tif(this.encoders.has(type)) {\n\t\t\t\t\tthrow new Error(`Duplicate compressed entity definition for ${type}`);\n\t\t\t\t}\n\t\t\t\tthis.encoders.set(type, { prefix: encodeVarint(key++), group });\n\t\t\t}\n\t\t}\n\t}\n\n\t// Only the definitions some compressed string needs, so a game can define every type without bloating its saves.\n\tget entityDefinitions(): CompressedEntityDefinitions {\n\t\tconst definitions: CompressedEntityDefinitions = {};\n\t\tfor(const group of this.used) {\n\t\t\tdefinitions[group.key] = group.definition;\n\t\t}\n\t\treturn definitions;\n\t}\n\n\t// Returns the config unchanged when it carries anything its definition can't represent.\n\tcompress<Cfg extends CompressibleConfig>(config: Cfg): Cfg | string {\n\t\tconst encoder = config.type === undefined ? undefined : this.encoders.get(config.type);\n\t\tconst encoded = encoder && this.encode(encoder, config);\n\t\tif(!encoder || encoded === undefined) {\n\t\t\treturn config;\n\t\t}\n\t\tthis.used.add(encoder.group);\n\t\treturn encoded;\n\t}\n\n\tcompressAll<Cfg extends CompressibleConfig>(entities: ReadonlyArray<Cfg>): CompressedEntities<Cfg> {\n\t\tconst compressed = entities.map(config => this.compress(config));\n\t\treturn { entityDefinitions: this.entityDefinitions, entities: compressed };\n\t}\n\n\tprivate encode(encoder: DefinitionEncoder, config: CompressibleConfig): string | undefined {\n\t\tconst fields: Array<string | undefined> = [];\n\t\tfor(const [name, value] of Object.entries(config)) {\n\t\t\tif(name === 'type' || value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst index = encoder.group.indices.get(name);\n\t\t\tif(index === undefined) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst field = encodeField(encoder.group.definition.properties[index], value);\n\t\t\tif(field === undefined) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tfields[index] = field;\n\t\t}\n\n\t\tlet encoded = encoder.prefix;\n\t\tfor(let i = 0; i < fields.length; i++) {\n\t\t\tencoded += fields[i] ?? ABSENT;\n\t\t}\n\t\treturn encoded;\n\t}\n}\n\nexport function compressEntities<Cfg extends CompressibleConfig>(entities: ReadonlyArray<Cfg>, definitions: ReadonlyArray<CompressedEntityDefinition>): CompressedEntities<Cfg> {\n\treturn new EntityCompressor(definitions).compressAll(entities);\n}\n\ninterface ResolvedDefinition {\n\ttype: string\n\tproperties: ReadonlyArray<CompressedEntityProperty>\n}\n// Expanding shared definitions to one entry per key once per save, rather than once per entity.\nconst resolvedDefinitions = new WeakMap<CompressedEntityDefinitions, Map<number, ResolvedDefinition>>();\nfunction resolveDefinitions(definitions: CompressedEntityDefinitions): Map<number, ResolvedDefinition> {\n\tlet resolved = resolvedDefinitions.get(definitions);\n\tif(resolved) {\n\t\treturn resolved;\n\t}\n\tresolved = new Map();\n\tfor(const [key, definition] of Object.entries(definitions)) {\n\t\tconst types = typesOf(definition);\n\t\tfor(let i = 0; i < types.length; i++) {\n\t\t\tif(resolved.has(Number(key) + i)) {\n\t\t\t\tthrow new Error(`Compressed entity definitions overlap at key ${Number(key) + i}`);\n\t\t\t}\n\t\t\tresolved.set(Number(key) + i, { type: types[i], properties: definition.properties });\n\t\t}\n\t}\n\tresolvedDefinitions.set(definitions, resolved);\n\treturn resolved;\n}\n\nexport function decompressEntity(encoded: string, definitions: CompressedEntityDefinitions): Record<string, DecompressedValue | string> {\n\tlet position = 0;\n\tconst readVarint = (): number | undefined => {\n\t\tif(encoded[position] === ABSENT) {\n\t\t\tposition++;\n\t\t\treturn undefined;\n\t\t}\n\t\tlet value = 0;\n\t\tlet multiplier = 1;\n\t\twhile(position < encoded.length) {\n\t\t\tconst code = encoded.charCodeAt(position++);\n\t\t\tconst digit = code < 128 ? DIGITS[code] : -1;\n\t\t\tif(digit < 0) {\n\t\t\t\tthrow new Error(`Invalid compressed entity ${encoded}`);\n\t\t\t}\n\t\t\tif(digit < COMPRESSION_BASE) {\n\t\t\t\treturn value + digit * multiplier;\n\t\t\t}\n\t\t\tvalue += (digit - COMPRESSION_BASE) * multiplier;\n\t\t\tmultiplier *= COMPRESSION_BASE;\n\t\t}\n\t\tthrow new Error(`Truncated compressed entity ${encoded}`);\n\t};\n\n\tconst key = readVarint();\n\tconst definition = key === undefined ? undefined : resolveDefinitions(definitions).get(key);\n\tif(!definition) {\n\t\tthrow new Error(`No compressed entity definition for ${encoded}`);\n\t}\n\tconst config: Record<string, DecompressedValue | string> = { type: definition.type };\n\tfor(let i = 0; position < encoded.length; i++) {\n\t\tconst property = definition.properties[i];\n\t\tif(!property) {\n\t\t\tthrow new Error(`Compressed entity ${encoded} has more values than ${definition.type} defines`);\n\t\t}\n\t\tconst stored = readVarint();\n\t\tif(stored === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tif(property.type !== 'string') {\n\t\t\tconfig[property.name] = loadedValue(property, stored);\n\t\t} else if(stored === 0) {\n\t\t\tconfig[property.name] = null;\n\t\t} else {\n\t\t\tif(position + stored > encoded.length) {\n\t\t\t\tthrow new Error(`Truncated compressed entity ${encoded}`);\n\t\t\t}\n\t\t\tconfig[property.name] = encoded.slice(position, position += stored);\n\t\t}\n\t}\n\treturn config;\n}\n\n// Configs are flat records of the same shape a compressed string expands to, so the caller's Cfg is trusted here.\nexport function decompressEntities<Cfg>(entities: ReadonlyArray<Cfg | string>, definitions: CompressedEntityDefinitions | undefined): Array<Cfg> {\n\treturn entities.map(entity => {\n\t\tif(typeof entity !== 'string') {\n\t\t\treturn entity;\n\t\t}\n\t\tif(!definitions) {\n\t\t\tthrow new Error('Compressed entities need entityDefinitions to load');\n\t\t}\n\t\treturn decompressEntity(entity, definitions) as Cfg;\n\t});\n}\n","import type { ComponentMap } from '../component-definition';\nimport type { Scheduler, SchedulerContext, SchedulerUpdateResult } from './scheduler';\n\nexport default class DefaultScheduler<C extends ComponentMap = ComponentMap> implements Scheduler<C> {\n\tupdate(context: SchedulerContext<C>, elapsedTime: number): SchedulerUpdateResult {\n\t\tlet lastSystemError: Error | null = null;\n\t\tcontext.systems.forEach(system => {\n\t\t\tlet shouldRun = true;\n\t\t\tlet ran = false;\n\t\t\tlet failed = false;\n\t\t\tcontext.emit(`system-${system.name}-started`);\n\t\t\ttry {\n\t\t\t\tshouldRun = system.shouldRun();\n\t\t\t\tif(shouldRun) {\n\t\t\t\t\tran = system.update(elapsedTime);\n\t\t\t\t}\n\t\t\t} catch(e) {\n\t\t\t\tconst error = e as Error;\n\t\t\t\tconsole.error(error.message, error);\n\t\t\t\tfailed = true;\n\t\t\t\tlastSystemError = error;\n\t\t\t\tcontext.emit('system-error', { system: system.name, error, phase: 'run' });\n\t\t\t}\n\t\t\tcontext.emit(`system-${system.name}-finished`, {\n\t\t\t\tran,\n\t\t\t\tshouldRun,\n\t\t\t\tfailed,\n\t\t\t});\n\t\t});\n\n\t\treturn { lastSystemError };\n\t}\n}\n","import { EventEmitter } from 'eventemitter3';\nimport MemoryHeap from '@daneren2005/shared-memory-objects/memory-heap';\nimport type { GrowBufferData } from '@daneren2005/shared-memory-objects/memory-heap';\nimport type AllocatedMemory from '@daneren2005/shared-memory-objects/allocated-memory';\nimport type { SharedAllocatedMemory } from '@daneren2005/shared-memory-objects/allocated-memory';\nimport type { SharedPoolMemory } from '@daneren2005/shared-memory-objects/shared-pool';\nimport { MAX_BYTE_OFFSET_LENGTH } from '@daneren2005/shared-memory-objects/utils/pointer';\nimport MemoryComponent from './memory-component';\nimport ConstantStringCache from './constant-string-cache';\nimport type BaseEntity from './entity';\nimport type System from './systems/system';\nimport type { EntityBatch } from './systems/system';\nimport EntitySystem from './systems/entity-system';\nimport EntityWorkerSystem from './systems/entity-worker-system';\nimport type { WorkerCreatedEntity } from './systems/entity-worker-system';\nimport type {\n\tBaseComponent, ComponentDefinitionMap, ComponentMap, ComponentRegistry, ComponentsOf,\n\tEntityConfigOf, RegisteredComponentDefinition, RegisteredComponentRegistry,\n} from './component-definition';\nimport { entityDefinition, type EntityComponent } from './entity-component';\nimport EntityFactory from './entity-factory';\nimport { decompressEntities, type CompressedEntities } from './entity-compression';\nimport DefaultScheduler from './scheduling/default-scheduler';\nimport type { Scheduler, SchedulerUpdateResult } from './scheduling/scheduler';\n\nconst DEFAULT_HEAP_SIZE = MAX_BYTE_OFFSET_LENGTH;\nconst FREE_BUFFER_STUCK_MS = 10000;\n\ninterface DeferredComponentFree {\n\tmemoryComponent: MemoryComponent\n\tindex: number\n\t// The definition's free hook, deferred to fire alongside the block free rather than the instant the entity dies.\n\tfree?: () => void\n}\n// A batch of component blocks queued to be freed, plus the systems that must each finish a run before it is safe to free them\ninterface QueryKeys {\n\trequired: ReadonlyArray<PropertyKey>\n\toptional?: ReadonlyArray<PropertyKey>\n\tnot?: ReadonlyArray<PropertyKey>\n}\ninterface WorkerQueryKeys extends QueryKeys {\n\tqueries?: { [name: string]: QueryKeys }\n}\n\ninterface ComponentFreeBuffer<C extends ComponentMap> {\n\tfrees: Array<DeferredComponentFree>\n\twaitingSystems: Set<System<C>>\n\twaitElapsed: number\n}\n\nexport interface WorldOptions<\n\tC extends ComponentMap = ComponentMap,\n\tCfg = any,\n\tE extends BaseEntity<C, Cfg> = BaseEntity<C, Cfg>,\n> {\n\theapSize?: number\n\tfactory?: EntityFactory<C, Cfg, E>\n\tscheduler?: Scheduler<C>\n}\n\nexport interface WorldConfig<Cfg = any> {\n\tentities: Array<Cfg>\n\tgameTime?: number\n\tplayerTime?: number\n\ttimeScale?: number\n}\n\n// A save whose entities may be strings packed by compressEntities; load expands them with the bundled definitions.\nexport type CompressedWorldConfig<Cfg = any> = Omit<WorldConfig<Cfg>, 'entities'> & CompressedEntities<Cfg>;\n\n// Shipped to a worker so it can reconstruct handles over this world's shared state (see getSharedComponentMemory).\nexport interface WorldSharedMemory {\n\tcomponents: { [name: string]: SharedPoolMemory }\n\teidCounter: SharedAllocatedMemory\n}\n\nexport default class BaseWorld<\n\tR extends ComponentDefinitionMap = ComponentDefinitionMap,\n\tC extends ComponentMap = ComponentsOf<R>,\n\tCfg = EntityConfigOf<R>,\n\tE extends BaseEntity<C, Cfg> = BaseEntity<C, Cfg>,\n> extends EventEmitter {\n\theap: MemoryHeap;\n\t// Interns entity type names (and any other constant strings) in the heap\n\tconstantStrings: ConstantStringCache;\n\t// Single heap-backed counter every thread bumps atomically, so eids stay unique whether an entity is created on\n\t// the main thread or inside a worker.\n\tprivate eidCounter: AllocatedMemory;\n\tregistry: RegisteredComponentRegistry<C> & { entity: RegisteredComponentDefinition<EntityComponent> };\n\tfactory: EntityFactory<C, Cfg, E>;\n\n\t// Keyed by eid: entities leave from the middle one at a time (every death), so a Map deletes in constant\n\t// time while still iterating in insertion order, preserving load/save order.\n\tentities: Map<number, E> = new Map();\n\tsystems: Array<System<C>> = [];\n\treadonly scheduler: Scheduler<C>;\n\n\tgameTime = 0;\n\t// Keeps advancing while paused and is never scaled by timeScale (unlike gameTime).\n\tplayerTime = 0;\n\ttimeScale = 1;\n\tprivate isPaused = false;\n\tdestroyed = false;\n\t// True while the world has never been loaded into\n\tpristine = true;\n\t// True while load() adds its batch: systems ignore per-entity events and are handed every entity at the end.\n\tisBulkLoading = false;\n\n\t// Two rolling buffers of component blocks awaiting a safe free. New deferrals land in `next`; `active` is the\n\t// one currently waiting for its systems to each finish a run before its blocks can be reused\n\tprivate activeFreeBuffer: ComponentFreeBuffer<C> = { frees: [], waitingSystems: new Set(), waitElapsed: 0 };\n\tprivate nextFreeBuffer: ComponentFreeBuffer<C> = { frees: [], waitingSystems: new Set(), waitElapsed: 0 };\n\tprivate clearing = false;\n\n\t// The entity component is added automatically, so it must not be part of the passed registry.\n\tconstructor(registry: R, options: WorldOptions<C, Cfg, E> = {}) {\n\t\tsuper();\n\n\t\tthis.scheduler = options.scheduler ?? new DefaultScheduler<C>();\n\t\tthis.heap = new MemoryHeap({ bufferSize: options.heapSize ?? DEFAULT_HEAP_SIZE });\n\t\tthis.constantStrings = new ConstantStringCache(this.heap);\n\t\tthis.eidCounter = this.heap.allocUI32(1);\n\t\t// A grown buffer must reach every worker's reconstructed heap so pointers into it still resolve.\n\t\tthis.heap.addOnGrowBufferHandlers((data: GrowBufferData) => this.emit('grow-buffer', data));\n\n\t\tconst inputRegistry = { ...registry, entity: entityDefinition } as ComponentRegistry<C> & { entity: typeof entityDefinition };\n\t\tconst registry_: Record<string, RegisteredComponentDefinition<BaseComponent>> = {};\n\t\tfor(let name of Object.keys(inputRegistry)) {\n\t\t\tconst definition = inputRegistry[name as keyof typeof inputRegistry];\n\t\t\tregistry_[name] = {\n\t\t\t\t...definition,\n\t\t\t\tmemoryComponent: new MemoryComponent(this.heap, definition.type, definition.size),\n\t\t\t};\n\t\t}\n\t\tthis.registry = registry_ as RegisteredComponentRegistry<C> & { entity: RegisteredComponentDefinition<EntityComponent> };\n\n\t\tthis.factory = options.factory ?? new EntityFactory<C, Cfg, E>();\n\t\tthis.factory.setWorld(this);\n\t}\n\n\t// Returns a fresh, unique entity id. Backed by a heap atomic so a worker allocating an entity gets an id that can\n\t// never collide with one the main thread (or another worker) hands out. First id is 1, matching the old counter.\n\tallocateEid(): number {\n\t\treturn Atomics.add(this.eidCounter.data, 0, 1) + 1;\n\t}\n\t// Everything a worker needs to reconstruct handles over this world's shared state: one SharedPoolMemory per\n\t// registered component (so it can allocate/read blocks) plus the eid counter (so it can mint unique ids).\n\tgetSharedComponentMemory(): WorldSharedMemory {\n\t\tconst components: { [name: string]: SharedPoolMemory } = {};\n\t\tfor(let name of Object.keys(this.registry)) {\n\t\t\tcomponents[name] = this.registry[name as keyof typeof this.registry].memoryComponent.getSharedMemory();\n\t\t}\n\t\treturn {\n\t\t\tcomponents,\n\t\t\teidCounter: this.eidCounter.getSharedMemory(),\n\t\t};\n\t}\n\t// A buffer that was grown inside a worker: adopt it into the main heap (if not already present) and fan it out to\n\t// every other worker so their heaps can resolve pointers into it. The heap's BUFFER_COUNT is authoritative, so\n\t// re-adding an already-known position is a harmless overwrite of the same SharedArrayBuffer.\n\taddGrownBuffer(data: GrowBufferData) {\n\t\tif(this.heap.buffers[data.bufferPosition] === undefined) {\n\t\t\tthis.heap.addSharedBuffer(data);\n\t\t}\n\t\tthis.emit('grow-buffer', data);\n\t}\n\n\t// Only an off-thread EntityWorkerSystem that creates entities or adds components allocates in a worker, so only\n\t// then is a pre-fanned-out spare buffer worth keeping. The main-thread fallback allocates on the main thread, where\n\t// growth fans out inline, so it never needs one.\n\tprivate get needsSpareBuffer(): boolean {\n\t\treturn this.systems.some(system => system instanceof EntityWorkerSystem\n\t\t\t&& system.isWorkerThread\n\t\t\t&& (!!system.options.createsEntities || !!system.options.addsComponents));\n\t}\n\n\tasync init() {\n\t\tawait Promise.all(this.systems.map(system => system.init()).filter(promise => promise instanceof Promise));\n\t}\n\tprivate async finishLoadingSystems(): Promise<void> {\n\t\tawait Promise.all(this.systems.map(system => system.finishLoading()).filter(promise => promise instanceof Promise));\n\t}\n\n\taddEntity(entity: E, created = true): E {\n\t\tthis.entities.set(entity.eid, entity);\n\t\tentity.world = this;\n\t\t// Any entity in the world means there is state to tear down on the next load/clear.\n\t\tthis.pristine = false;\n\n\t\tentity.on('component-added', (name: keyof C) => {\n\t\t\tthis.addEntityToEntityWorkerSystem(entity, name);\n\t\t});\n\t\tentity.on('component-removed', (name: keyof C) => {\n\t\t\tthis.removeEntityFromEntityWorkerSystem(entity, name);\n\t\t});\n\n\t\tif(created) {\n\t\t\tentity.finishLoading();\n\t\t\tthis.emit('entity-added', entity);\n\t\t\tentity.on('death', () => {\n\t\t\t\tthis.onEntityDied(entity);\n\t\t\t});\n\t\t}\n\n\t\treturn entity;\n\t}\n\tloadEntity(config: Cfg, created = true): E {\n\t\treturn this.factory.loadEntity(config, created);\n\t}\n\t// Materializes an entity a worker created off-thread (see createEntityWorker): the worker already minted the id and\n\t// allocated + wrote every game-component block, so this only builds the `entity` component on the main thread\n\t// (interning its type) and adopts each worker-allocated block by index, then wires it into the world like any new\n\t// entity. The factory selects the same class wrapper a main-thread load would use.\n\tadoptEntity(descriptor: WorkerCreatedEntity): E {\n\t\tlet entity: E | undefined;\n\t\tconst attached = new Set<string>();\n\t\ttry {\n\t\t\tfor(const name of Object.keys(descriptor.components)) {\n\t\t\t\tif(!(name in this.registry)) {\n\t\t\t\t\tthrow new Error(`Worker-created entity contains unknown component ${name}`);\n\t\t\t\t}\n\t\t\t\tif(!this.factory.isComponentAllowed(descriptor.class, name)) {\n\t\t\t\t\tthrow new Error(`Component ${name} is not allowed for entity class ${descriptor.class ?? ''}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tentity = this.factory.createAdoptedEntity(descriptor.type, descriptor.class, descriptor.eid);\n\t\t\tentity.loadComponent('entity', { type: descriptor.type, class: descriptor.class, isStatic: descriptor.isStatic }, false);\n\t\t\tfor(let name of Object.keys(descriptor.components)) {\n\t\t\t\tentity.attachComponent(name, descriptor.components[name]);\n\t\t\t\tattached.add(name);\n\t\t\t}\n\t\t\treturn this.addEntity(entity, true);\n\t\t} catch(error) {\n\t\t\tentity?.deleteAllComponentMemory();\n\t\t\tfor(const name of Object.keys(descriptor.components)) {\n\t\t\t\tif(!attached.has(name) && name in this.registry) {\n\t\t\t\t\tthis.deferComponentMemoryFree(this.registry[name as keyof C].memoryComponent, descriptor.components[name]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\t// Replaces the world's contents. Entities load with created = false so no finishLoading runs mid-batch;\n\t// finishLoading is called on each once the whole batch exists, so cross-entity dependencies can resolve.\n\tload(config: WorldConfig<Cfg> | CompressedWorldConfig<Cfg>): Promise<void> {\n\t\t// A pristine world (fresh or just cleared) has nothing to tear down, so skip the per-system clear.\n\t\tif(!this.pristine || (this.scheduler.prepareEffects && this.systems.some(system => system.isCurrentlyRunning()))) {\n\t\t\t// Iterate over a copy since removeEntity mutates `this.entities`.\n\t\t\tfor(let entity of Array.from(this.entities.values())) {\n\t\t\t\tthis.removeEntity(entity);\n\t\t\t}\n\t\t\tthis.systems.forEach(system => system.clear());\n\t\t\tthis.scheduler.reset?.(this);\n\t\t\tthis.consolidateFreeBuffersForReload();\n\t\t}\n\n\t\t// Intern a constant string for every type the factory knows, so a worker can resolve any type - even one no\n\t\t// currently-loaded entity uses. Deduped, so the types actually loaded below cost nothing extra.\n\t\tfor(let type of Object.keys(this.factory.configs)) {\n\t\t\tthis.constantStrings.getOrCreate(type);\n\t\t}\n\t\tfor(let entityClass of Object.keys(this.factory.classes)) {\n\t\t\tthis.constantStrings.getOrCreate(entityClass);\n\t\t}\n\n\t\tthis.isBulkLoading = true;\n\t\ttry {\n\t\t\tconst configs = 'entityDefinitions' in config ? decompressEntities(config.entities, config.entityDefinitions) : config.entities;\n\t\t\tconst entities = configs.map(entityConfig => this.loadEntity(entityConfig, false));\n\t\t\tfor(let entity of entities) {\n\t\t\t\tentity.finishLoading();\n\t\t\t\tthis.emit('entity-added', entity);\n\t\t\t\tentity.on('death', () => {\n\t\t\t\t\tthis.onEntityDied(entity);\n\t\t\t\t});\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.isBulkLoading = false;\n\t\t}\n\t\t// Read back from the world rather than the batch, so entities created or removed by listeners mid-load are\n\t\t// reflected. The world was empty beforehand, so no system holds any of these yet.\n\t\tconst batch = batchByComponents(this.entities.values());\n\t\tthis.systems.forEach(system => system.addEntities(batch));\n\n\t\tthis.gameTime = config.gameTime ?? 0;\n\t\tthis.playerTime = config.playerTime ?? 0;\n\t\tthis.timeScale = config.timeScale ?? 1;\n\n\t\t// EntityWorkerSystem re-sends its init data here.\n\t\treturn this.finishLoadingSystems();\n\t}\n\tasync clear(): Promise<void> {\n\t\tif(this.pristine && !this.scheduler.beforeClear) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.clearing = true;\n\t\ttry {\n\t\t\tthis.scheduler.beforeClear?.(this);\n\t\t\t// Await active workers before their component blocks can be reused.\n\t\t\tawait Promise.all(\n\t\t\t\tthis.systems\n\t\t\t\t\t.map(system => system.waitForRunToComplete())\n\t\t\t\t\t.filter(promise => promise instanceof Promise),\n\t\t\t);\n\t\t\tfor(let entity of Array.from(this.entities.values())) {\n\t\t\t\tthis.removeEntity(entity);\n\t\t\t}\n\t\t\tthis.systems.forEach(system => system.clear());\n\t\t\tthis.scheduler.reset?.(this);\n\t\t\tthis.freeAllPendingBuffers();\n\n\t\t\tthis.pristine = true;\n\t\t} finally {\n\t\t\tthis.clearing = false;\n\t\t}\n\t}\n\tremoveEntity(entity: E) {\n\t\t// Match the instance as well as the eid: a stale entity must not remove a newer entity that owns the same key.\n\t\tif(this.entities.get(entity.eid) !== entity) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.entities.delete(entity.eid);\n\t\tthis.emit('entity-removed', entity);\n\t\tentity.deleteAllComponentMemory();\n\t}\n\t// Fires the death hooks then removes the entity\n\tonEntityDied(entity: E) {\n\t\tif(this.entities.get(entity.eid) !== entity) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst registry = this.registry as RegisteredComponentRegistry<C>;\n\t\tconst components = entity.components as Partial<C>;\n\t\tfor(let name of Object.keys(components) as Array<keyof C>) {\n\t\t\tconst definition = registry[name];\n\t\t\tconst component = components[name];\n\t\t\tif(definition?.died && component) {\n\t\t\t\t// A bad hook must not abort the death; mirror the update-loop convention and surface a system-error.\n\t\t\t\ttry {\n\t\t\t\t\tdefinition.died(component, entity, this as unknown as BaseWorld);\n\t\t\t\t} catch(e) {\n\t\t\t\t\tconst error = e as Error;\n\t\t\t\t\tconsole.error(`Error in died hook for component ${String(name)} (entity ${entity.eid}): ${error.message}`, error);\n\t\t\t\t\tthis.emit('system-error', { system: String(name), error, entityId: entity.eid, phase: 'died' });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.emit('entity-died', entity);\n\t\tthis.removeEntity(entity);\n\t}\n\tgetEntityByEid(eid: number): E | undefined {\n\t\treturn this.entities.get(eid);\n\t}\n\n\t// Queues a component block to be freed when all systems done using it, running the definition's free hook (if any)\n\t// at that same deferred point so a system still mid-run can't observe the resource being torn down early.\n\tdeferComponentMemoryFree(memoryComponent: MemoryComponent, index: number, free?: () => void) {\n\t\tthis.nextFreeBuffer.frees.push({ memoryComponent, index, free });\n\t}\n\t// A system finished a run; if the active buffer was waiting on it, drop it and, once nothing is left to wait\n\t// for, free the buffer. One completion is enough: the system is now done touching the block for that run, and\n\t// every later run applies the pending removed-delta before its update loop, so it can never process the freed\n\t// entity again.\n\tnotifySystemRunCompleted(system: System<C>) {\n\t\tif(this.activeFreeBuffer.waitingSystems.delete(system) && this.activeFreeBuffer.waitingSystems.size === 0) {\n\t\t\tthis.processFreeBuffers();\n\t\t}\n\t\tthis.scheduler.runCompleted?.(this, system);\n\t}\n\tprivate processFreeBuffers() {\n\t\t// Loop so a promoted buffer with no systems to wait for is freed the same tick rather than a frame later.\n\t\twhile(this.activeFreeBuffer.waitingSystems.size === 0) {\n\t\t\tif(this.activeFreeBuffer.frees.length > 0) {\n\t\t\t\tthis.performFrees(this.activeFreeBuffer);\n\t\t\t}\n\t\t\tif(this.nextFreeBuffer.frees.length === 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.promoteNextFreeBuffer();\n\t\t}\n\t}\n\tprivate promoteNextFreeBuffer() {\n\t\t// active is now empty (its frees were performed); swap roles and reuse it as the new next buffer.\n\t\tconst emptied = this.activeFreeBuffer;\n\t\tthis.activeFreeBuffer = this.nextFreeBuffer;\n\t\tthis.nextFreeBuffer = emptied;\n\n\t\tconst active = this.activeFreeBuffer;\n\t\tactive.waitElapsed = 0;\n\t\tactive.waitingSystems.clear();\n\t\tfor(let system of this.systems) {\n\t\t\t// Wait on a system if it will run (and so might pick up this block) or is already mid-run over memory we\n\t\t\t// may free. A system that is neither can't touch these blocks, so there's nothing to wait for.\n\t\t\tif(system.shouldRun() || system.isCurrentlyRunning()) {\n\t\t\t\tactive.waitingSystems.add(system);\n\t\t\t}\n\t\t}\n\t}\n\t// On reload every system was just cleared (its completedRuns reset and worker told to drop its lists), so the\n\t// old targets no longer apply. Collapse whatever was pending into `next` with a fresh (empty) active buffer\n\tprivate consolidateFreeBuffersForReload() {\n\t\tif(this.activeFreeBuffer.frees.length > 0) {\n\t\t\tthis.nextFreeBuffer.frees.push(...this.activeFreeBuffer.frees);\n\t\t\tthis.activeFreeBuffer.frees.length = 0;\n\t\t}\n\t\tthis.activeFreeBuffer.waitingSystems.clear();\n\t\tthis.activeFreeBuffer.waitElapsed = 0;\n\t}\n\t// Frees both buffers outright. Only safe once every system's in-flight run has finished (see clear()), since it\n\t// skips the per-system wait the update loop normally enforces.\n\tprivate freeAllPendingBuffers() {\n\t\tthis.performFrees(this.activeFreeBuffer);\n\t\tthis.performFrees(this.nextFreeBuffer);\n\t\tthis.activeFreeBuffer.waitingSystems.clear();\n\t\tthis.activeFreeBuffer.waitElapsed = 0;\n\t\tthis.nextFreeBuffer.waitingSystems.clear();\n\t\tthis.nextFreeBuffer.waitElapsed = 0;\n\t}\n\tprivate performFrees(buffer: ComponentFreeBuffer<C>) {\n\t\tfor(let deferred of buffer.frees) {\n\t\t\tdeferred.free?.();\n\t\t\tdeferred.memoryComponent.delete(deferred.index);\n\t\t}\n\t\tbuffer.frees.length = 0;\n\t}\n\tprivate checkFreeBufferTimeout(elapsedTime: number) {\n\t\tconst active = this.activeFreeBuffer;\n\t\tif(active.waitingSystems.size === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tactive.waitElapsed += elapsedTime;\n\t\tif(active.waitElapsed >= FREE_BUFFER_STUCK_MS) {\n\t\t\tconst stuck = Array.from(active.waitingSystems).map(system => system.name).join(', ');\n\t\t\tconsole.warn(`shared-memory-ecs: deferred component free waited over ${FREE_BUFFER_STUCK_MS}ms on system(s): ${stuck}; freeing anyway`);\n\t\t\tactive.waitingSystems.clear();\n\t\t\tthis.processFreeBuffers();\n\t\t}\n\t}\n\n\taddSystem<T extends System<C>>(system: T): T {\n\t\tthis.systems.push(system);\n\t\tthis.scheduler.systemAdded?.(this, system);\n\t\tthis.emit('system-added', system);\n\t\treturn system;\n\t}\n\taddSystemIfNotExists(system: System<C>) {\n\t\tlet index = this.systems.findIndex(otherSystem => system.name === otherSystem.name);\n\t\tif(index === -1) {\n\t\t\tthis.systems.push(system);\n\t\t\tthis.scheduler.systemAdded?.(this, system);\n\t\t\tthis.emit('system-added', system);\n\t\t}\n\t}\n\tremoveSystem(name: string) {\n\t\tlet index = this.systems.findIndex(system => system.name === name);\n\t\tif(index !== -1) {\n\t\t\tconst [system] = this.systems.splice(index, 1);\n\t\t\tthis.scheduler.systemRemoved?.(this, system);\n\t\t\tthis.emit('system-removed', system);\n\t\t}\n\t}\n\n\tupdate(elapsedTime: number): SchedulerUpdateResult {\n\t\tthis.emit('update-started', elapsedTime);\n\t\tconst result = this.runUpdate(elapsedTime);\n\t\tthis.emit('update-finished', elapsedTime);\n\n\t\treturn result;\n\t}\n\tprivate runUpdate(elapsedTime: number): SchedulerUpdateResult {\n\t\tthis.playerTime += elapsedTime;\n\t\tif(this.paused) {\n\t\t\treturn {};\n\t\t}\n\t\tconst unscaledElapsedTime = elapsedTime;\n\t\telapsedTime = this.timeScale * elapsedTime;\n\n\t\tthis.gameTime += elapsedTime;\n\n\t\t// Promote before running: a run this same update then counts toward the wait, instead of after it.\n\t\tthis.processFreeBuffers();\n\n\t\t// Keep an empty heap buffer fanned out ahead of any worker that allocates off-thread, so its allocations land in\n\t\t// a buffer every thread already holds. Done here (before dispatching runs) so the resulting grow-buffer message\n\t\t// is queued to each worker before its run message - postMessage is FIFO, so the worker has the buffer first.\n\t\tif(this.needsSpareBuffer) {\n\t\t\tthis.heap.ensureSpareBuffer();\n\t\t}\n\n\t\tconst result = this.scheduler.update(this, elapsedTime);\n\n\t\tthis.checkFreeBufferTimeout(unscaledElapsedTime);\n\n\t\treturn result;\n\t}\n\tpause() {\n\t\tthis.paused = true;\n\t}\n\tget paused(): boolean {\n\t\treturn this.isPaused;\n\t}\n\tset paused(paused: boolean) {\n\t\tif(this.isPaused === paused) {\n\t\t\treturn;\n\t\t}\n\t\tthis.isPaused = paused;\n\t\tif(paused) {\n\t\t\tthis.scheduler.pause?.(this);\n\t\t}\n\t}\n\tprepareForSystemDispatch(): boolean {\n\t\tif(!this.dispatchAllowed) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.needsSpareBuffer) {\n\t\t\tthis.heap.ensureSpareBuffer();\n\t\t}\n\t\treturn true;\n\t}\n\tget dispatchAllowed(): boolean {\n\t\treturn !this.clearing && !this.destroyed;\n\t}\n\tresume() {\n\t\tthis.paused = false;\n\t}\n\n\taddEntityToEntityWorkerSystem(entity: BaseEntity<C>, component: keyof C) {\n\t\tif(this.isBulkLoading) {\n\t\t\treturn;\n\t\t}\n\t\tthis.systems.forEach(system => {\n\t\t\tif(system instanceof EntitySystem && system.options.components?.includes(component)) {\n\t\t\t\tsystem.checkAddEntity(entity);\n\t\t\t} else if(system instanceof EntityWorkerSystem) {\n\t\t\t\tif(this.queriesReferenceComponent(system.options, component)) {\n\t\t\t\t\tsystem.checkAddEntity(entity);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tremoveEntityFromEntityWorkerSystem(entity: BaseEntity<C>, component: keyof C) {\n\t\tif(this.isBulkLoading) {\n\t\t\treturn;\n\t\t}\n\t\tthis.systems.forEach(system => {\n\t\t\tif(system instanceof EntitySystem && system.options.components?.includes(component)) {\n\t\t\t\tsystem.removeEntity(entity);\n\t\t\t} else if(system instanceof EntityWorkerSystem) {\n\t\t\t\tif(this.queriesReferenceComponent(system.options, component)) {\n\t\t\t\t\tsystem.checkAddEntity(entity);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t// Takes only query keys: an EntityWorkerSystem<C> parameter would make BaseWorld (and BaseEntity) invariant in C.\n\tprivate queriesReferenceComponent(options: WorkerQueryKeys, component: keyof C): boolean {\n\t\tconst affectsMainQuery = options.required.includes(component)\n\t\t\t|| !!options.not?.includes(component)\n\t\t\t|| !!options.optional?.includes(component);\n\t\tconst affectsSubQuery = Object.values(options.queries ?? {}).some(query => {\n\t\t\treturn query.required.includes(component)\n\t\t\t\t|| !!query.not?.includes(component)\n\t\t\t\t|| !!query.optional?.includes(component);\n\t\t});\n\n\t\treturn affectsMainQuery || affectsSubQuery;\n\t}\n\n\tdestroy() {\n\t\tif(this.destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.systems.forEach(system => {\n\t\t\tsystem.destroy();\n\t\t});\n\t\tthis.scheduler.destroy?.(this);\n\t\tthis.destroyed = true;\n\t}\n}\n\n// Removed components are deleted from the bag, so the key list alone identifies the component set.\nfunction batchByComponents<C extends ComponentMap>(entities: Iterable<BaseEntity<C>>): EntityBatch<C> {\n\tconst batch: EntityBatch<C> = { entities: [], groupIndexes: [], groups: [] };\n\tconst groupIndexByKey = new Map<string, number>();\n\tfor(let entity of entities) {\n\t\tconst key = Object.keys(entity.components).sort().join(',');\n\t\tlet groupIndex = groupIndexByKey.get(key);\n\t\tif(groupIndex === undefined) {\n\t\t\tgroupIndex = batch.groups.push(entity) - 1;\n\t\t\tgroupIndexByKey.set(key, groupIndex);\n\t\t}\n\t\tbatch.entities.push(entity);\n\t\tbatch.groupIndexes.push(groupIndex);\n\t}\n\treturn batch;\n}\n","import type { ComponentMap } from '../component-definition';\nimport type System from '../systems/system';\nimport IterableSystem from '../systems/iterable-system';\nimport type { Scheduler, SchedulerContext, SchedulerEffects, SchedulerUpdateResult } from './scheduler';\n\nexport interface ConflictSchedule<C extends ComponentMap = ComponentMap> {\n\treadonly order: ReadonlyArray<System<C>>\n\treadonly batches: ReadonlyArray<ReadonlyArray<System<C>>>\n}\n\ninterface SystemAccess {\n\treads: Set<PropertyKey>\n\tcreationReads: Set<PropertyKey>\n\tcreationQueries?: ReadonlyArray<ReadonlyArray<PropertyKey>>\n\twrites: Set<PropertyKey>\n\tcreates: Set<PropertyKey>\n\texclusive: boolean\n}\n\ntype RunState = 'pending' | 'running' | 'complete';\n\ninterface ScheduledUpdate<C extends ComponentMap> {\n\tsystem: System<C>\n\taccess: SystemAccess\n\telapsedTime: number\n\tgameTime: number\n\tstate: RunState\n\tdependencies: number\n\tdependents: Array<ScheduledUpdate<C>>\n\tpublicationDependencies: number\n\tpublicationDependents: Array<ScheduledUpdate<C>>\n\teffects?: SchedulerEffects\n}\n\ninterface ComponentFrontier<C extends ComponentMap> {\n\twriter?: ScheduledUpdate<C>\n\tcreator?: ScheduledUpdate<C>\n\treaders: Map<System<C>, ScheduledUpdate<C>>\n}\n\nexport default class ConflictScheduler<C extends ComponentMap = ComponentMap> implements Scheduler<C> {\n\tprivate compiled: ConflictSchedule<C> = Object.freeze({ order: Object.freeze([]), batches: Object.freeze([]) });\n\tprivate registeredSystems: Array<System<C>> = [];\n\tprivate access = new Map<System<C>, SystemAccess>();\n\tprivate nodes = new Set<ScheduledUpdate<C>>();\n\tprivate tails = new Map<System<C>, ScheduledUpdate<C>>();\n\tprivate frontiers = new Map<PropertyKey, ComponentFrontier<C>>();\n\tprivate creators = new Map<SystemAccess, ScheduledUpdate<C>>();\n\tprivate creationReaders = new Map<SystemAccess, ScheduledUpdate<C>>();\n\tprivate exclusiveTail: ScheduledUpdate<C> | undefined;\n\tprivate running = new Map<System<C>, ScheduledUpdate<C>>();\n\tprivate ready: Array<ScheduledUpdate<C>> = [];\n\tprivate readyIndex = 0;\n\tprivate gameTime = 0;\n\tprivate pumping = false;\n\tprivate resumeQueued = false;\n\tprivate continuationTimer: ReturnType<typeof setTimeout> | undefined;\n\tprivate generation = 0;\n\tprivate publications = new Set<ScheduledUpdate<C>>();\n\tprivate publicationReady: Array<ScheduledUpdate<C>> = [];\n\tprivate publishing = false;\n\n\tget schedule(): ConflictSchedule<C> {\n\t\treturn this.compiled;\n\t}\n\n\trebuild(context: SchedulerContext<C>): ConflictSchedule<C> {\n\t\tconst systems = Array.from(new Set(context.systems));\n\t\tconst access = systems.map(system => {\n\t\t\tconst reads = system.readComponents;\n\t\t\tconst queries = system.creationReadQueries;\n\t\t\treturn {\n\t\t\t\treads: new Set(reads),\n\t\t\t\tcreationReads: new Set(queries === undefined ? system.creationReadComponents : system.reads),\n\t\t\t\tcreationQueries: queries?.map(query => Array.from(query)),\n\t\t\t\twrites: new Set(system.writes),\n\t\t\t\tcreates: new Set(system.createdComponents),\n\t\t\t\texclusive: system.requiresExclusiveScheduling || reads === undefined || system.writes === undefined,\n\t\t\t};\n\t\t});\n\t\tthis.access = new Map(systems.map((system, index) => [system, access[index]]));\n\t\tconst batches: Array<Array<System<C>>> = [];\n\t\tconst levels: Array<number> = [];\n\t\tfor(let i = 0; i < systems.length; i++) {\n\t\t\tlet level = 0;\n\t\t\tfor(let j = 0; j < i; j++) {\n\t\t\t\tif(this.conflicts(access[j], access[i])) {\n\t\t\t\t\tlevel = Math.max(level, levels[j] + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlevels.push(level);\n\t\t\t(batches[level] ??= []).push(systems[i]);\n\t\t}\n\t\tthis.registeredSystems = context.systems.slice();\n\t\tthis.compiled = Object.freeze({\n\t\t\torder: Object.freeze(batches.flat()),\n\t\t\tbatches: Object.freeze(batches.map(batch => Object.freeze(batch))),\n\t\t});\n\t\treturn this.compiled;\n\t}\n\n\tsystemAdded(context: SchedulerContext<C>): void {\n\t\tthis.rebuild(context);\n\t}\n\tsystemRemoved(context: SchedulerContext<C>): void {\n\t\tthis.rebuild(context);\n\t}\n\n\tupdate(context: SchedulerContext<C>, elapsedTime: number): SchedulerUpdateResult {\n\t\tif(this.pumping) {\n\t\t\tthrow new Error('ConflictScheduler does not support reentrant updates');\n\t\t}\n\t\tthis.refreshMembership(context);\n\t\tthis.gameTime = context.gameTime ?? this.gameTime + elapsedTime;\n\t\tfor(const system of new Set(context.systems)) {\n\t\t\tthis.enqueue(system, this.access.get(system)!, elapsedTime, this.gameTime);\n\t\t}\n\t\treturn this.pump(context, true);\n\t}\n\n\trunCompleted(context: SchedulerContext<C>, system: System<C>): void {\n\t\tconst node = this.running.get(system);\n\t\tif(!node) {\n\t\t\treturn;\n\t\t}\n\t\tthis.complete(node);\n\t\tif(this.pumping || this.resumeQueued) {\n\t\t\treturn;\n\t\t}\n\t\tthis.resumeQueued = true;\n\t\tconst generation = this.generation;\n\t\t// Let the worker settle its completion promise before dispatching another run on that worker.\n\t\tqueueMicrotask(() => {\n\t\t\tif(generation !== this.generation) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.resumeQueued = false;\n\t\t\tthis.pump(context, false);\n\t\t});\n\t}\n\n\tpause(context: SchedulerContext<C>): void {\n\t\tthis.scheduleContinuation(context);\n\t}\n\n\tprivate scheduleContinuation(context: SchedulerContext<C>): void {\n\t\tif(this.continuationTimer !== undefined || !context.paused || !this.dispatchAllowed(context)\n\t\t\t|| !Array.from(this.running.values()).some(node => this.isSliced(node))) {\n\t\t\treturn;\n\t\t}\n\t\tconst generation = this.generation;\n\t\t// Yield between slices so draining cannot starve worker replies or lifecycle calls.\n\t\tthis.continuationTimer = setTimeout(() => {\n\t\t\tif(generation !== this.generation) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.continuationTimer = undefined;\n\t\t\tif(context.paused) {\n\t\t\t\tthis.pump(context, 'sliced');\n\t\t\t}\n\t\t}, 0);\n\t}\n\n\tprivate isSliced(node: ScheduledUpdate<C>): boolean {\n\t\treturn node.system instanceof IterableSystem && node.system.remainingInstancesToRun.length > 0;\n\t}\n\n\treset(): void {\n\t\tif(this.continuationTimer !== undefined) {\n\t\t\tclearTimeout(this.continuationTimer);\n\t\t\tthis.continuationTimer = undefined;\n\t\t}\n\t\tconst effects = Array.from(this.publications, node => node.effects!);\n\t\tthis.publications.clear();\n\t\tthis.publicationReady = [];\n\t\tthis.nodes.clear();\n\t\tthis.tails.clear();\n\t\tthis.frontiers.clear();\n\t\tthis.creators.clear();\n\t\tthis.creationReaders.clear();\n\t\tthis.exclusiveTail = undefined;\n\t\tthis.running.clear();\n\t\tthis.ready = [];\n\t\tthis.readyIndex = 0;\n\t\tthis.gameTime = 0;\n\t\tthis.resumeQueued = false;\n\t\tthis.generation++;\n\t\teffects.forEach(effect => effect.discard());\n\t}\n\n\tbeforeClear(): void {\n\t\tthis.reset();\n\t}\n\n\tprepareEffects(context: SchedulerContext<C>, system: System<C>): (effects: SchedulerEffects) => void {\n\t\tconst node = this.running.get(system);\n\t\tconst generation = this.generation;\n\t\treturn effects => {\n\t\t\tif(!node || generation !== this.generation || !this.nodes.has(node)) {\n\t\t\t\teffects.discard();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnode.effects = effects;\n\t\t\tthis.publications.add(node);\n\t\t\tif(node.publicationDependencies === 0) {\n\t\t\t\tthis.publicationReady.push(node);\n\t\t\t}\n\t\t\tthis.publish();\n\t\t};\n\t}\n\n\tprivate publish(): void {\n\t\tif(this.publishing) {\n\t\t\treturn;\n\t\t}\n\t\tthis.publishing = true;\n\t\tconst generation = this.generation;\n\t\ttry {\n\t\t\twhile(this.publicationReady.length && generation === this.generation) {\n\t\t\t\tconst node = this.publicationReady.pop()!;\n\t\t\t\tthis.publications.delete(node);\n\t\t\t\tconst effects = node.effects!;\n\t\t\t\tnode.effects = undefined;\n\t\t\t\teffects.apply();\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.publishing = false;\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.reset();\n\t}\n\n\tprivate refreshMembership(context: SchedulerContext<C>): void {\n\t\tif(context.systems.length !== this.registeredSystems.length\n\t\t\t|| context.systems.some((system, i) => system !== this.registeredSystems[i])) {\n\t\t\tthis.rebuild(context);\n\t\t}\n\t}\n\n\tprivate pump(context: SchedulerContext<C>, continueRuns: boolean | 'sliced'): SchedulerUpdateResult {\n\t\tthis.pumping = true;\n\t\tlet lastSystemError: Error | null = null;\n\t\tconst generation = this.generation;\n\t\ttry {\n\t\t\tif(continueRuns) {\n\t\t\t\tfor(const node of Array.from(this.running.values())) {\n\t\t\t\t\tif(!node.system.isCurrentlyRunning() || (continueRuns === 'sliced' && !this.isSliced(node))) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif(!this.prepare(context)) {\n\t\t\t\t\t\treturn { lastSystemError };\n\t\t\t\t\t}\n\t\t\t\t\tconst result = this.dispatch(context, node, true);\n\t\t\t\t\tlastSystemError = result?.lastSystemError ?? lastSystemError;\n\t\t\t\t\tif(!result || generation !== this.generation) {\n\t\t\t\t\t\treturn { lastSystemError };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile(this.readyIndex < this.ready.length && generation === this.generation) {\n\t\t\t\tif(!this.prepare(context)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst node = this.ready[this.readyIndex++];\n\t\t\t\tconst result = this.dispatch(context, node, false);\n\t\t\t\tlastSystemError = result?.lastSystemError ?? lastSystemError;\n\t\t\t\tif(!result) {\n\t\t\t\t\tif(this.nodes.has(node) && node.state === 'pending') {\n\t\t\t\t\t\tthis.ready.push(node);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.ready = this.ready.slice(this.readyIndex);\n\t\t\tthis.readyIndex = 0;\n\t\t\tthis.pumping = false;\n\t\t\tthis.scheduleContinuation(context);\n\t\t}\n\t\treturn { lastSystemError };\n\t}\n\n\tprivate enqueue(system: System<C>, access: SystemAccess, elapsedTime: number, gameTime: number): void {\n\t\tconst node: ScheduledUpdate<C> = {\n\t\t\tsystem, access, elapsedTime, gameTime, state: 'pending', dependencies: 0, dependents: [],\n\t\t\tpublicationDependencies: 0, publicationDependents: [],\n\t\t};\n\t\tconst dependencies = new Set<ScheduledUpdate<C>>();\n\t\tconst publicationDependencies = new Set<ScheduledUpdate<C>>();\n\t\tconst dependOn = (previous: ScheduledUpdate<C> | undefined) => {\n\t\t\tif(previous && previous.state !== 'complete') {\n\t\t\t\tdependencies.add(previous);\n\t\t\t}\n\t\t};\n\t\tdependOn(this.tails.get(system));\n\t\tdependOn(this.exclusiveTail);\n\t\tif(access.exclusive) {\n\t\t\tthis.tails.forEach(dependOn);\n\t\t\tthis.exclusiveTail = node;\n\t\t} else {\n\t\t\tconst publishAfter = (previous: ScheduledUpdate<C> | undefined) => {\n\t\t\t\tif(previous && previous.state !== 'complete') {\n\t\t\t\t\tpublicationDependencies.add(previous);\n\t\t\t\t}\n\t\t\t};\n\t\t\tfor(const component of access.creates) {\n\t\t\t\tconst frontier = this.frontier(component);\n\t\t\t\tpublishAfter(frontier.writer);\n\t\t\t\tpublishAfter(frontier.creator);\n\t\t\t}\n\t\t\tif(access.creates.size) {\n\t\t\t\tfor(const reader of this.creationReaders.values()) {\n\t\t\t\t\tif(this.observesCreation(access, reader.access)) {\n\t\t\t\t\t\tpublishAfter(reader);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor(const component of access.reads) {\n\t\t\t\tif(!access.writes.has(component)) {\n\t\t\t\t\tconst frontier = this.frontier(component);\n\t\t\t\t\tdependOn(frontier.writer);\n\t\t\t\t\tfrontier.readers.set(system, node);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor(const creator of this.creators.values()) {\n\t\t\t\tif(this.observesCreation(creator.access, access)) {\n\t\t\t\t\tdependOn(creator);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(access.creationReads.size || access.creationQueries?.length) {\n\t\t\t\tthis.creationReaders.set(access, node);\n\t\t\t}\n\t\t\tfor(const component of access.writes) {\n\t\t\t\tconst frontier = this.frontier(component);\n\t\t\t\tdependOn(frontier.writer);\n\t\t\t\tdependOn(frontier.creator);\n\t\t\t\tfrontier.readers.forEach(dependOn);\n\t\t\t\tfrontier.readers.clear();\n\t\t\t\tfrontier.writer = node;\n\t\t\t}\n\t\t\tfor(const component of access.creates) {\n\t\t\t\tthis.frontier(component).creator = node;\n\t\t\t}\n\t\t\tif(access.creates.size) {\n\t\t\t\t// Keep distinct creation bounds so an unrelated later creator cannot hide a matching one.\n\t\t\t\tthis.creators.set(access, node);\n\t\t\t}\n\t\t}\n\t\tfor(const dependency of dependencies) {\n\t\t\tdependency.dependents.push(node);\n\t\t}\n\t\tnode.dependencies = dependencies.size;\n\t\tfor(const dependency of publicationDependencies) {\n\t\t\tdependency.publicationDependents.push(node);\n\t\t}\n\t\tnode.publicationDependencies = publicationDependencies.size;\n\t\tthis.nodes.add(node);\n\t\tthis.tails.set(system, node);\n\t\tif(!node.dependencies) {\n\t\t\tthis.ready.push(node);\n\t\t}\n\t}\n\n\tprivate frontier(component: PropertyKey): ComponentFrontier<C> {\n\t\tlet frontier = this.frontiers.get(component);\n\t\tif(!frontier) {\n\t\t\tfrontier = { readers: new Map() };\n\t\t\tthis.frontiers.set(component, frontier);\n\t\t}\n\t\treturn frontier;\n\t}\n\n\tprivate complete(node: ScheduledUpdate<C>): void {\n\t\tif(node.state === 'complete') {\n\t\t\treturn;\n\t\t}\n\t\tnode.state = 'complete';\n\t\tthis.nodes.delete(node);\n\t\tthis.running.delete(node.system);\n\t\tif(this.tails.get(node.system) === node) {\n\t\t\tthis.tails.delete(node.system);\n\t\t}\n\t\tif(this.exclusiveTail === node) {\n\t\t\tthis.exclusiveTail = undefined;\n\t\t}\n\t\tif(this.creators.get(node.access) === node) {\n\t\t\tthis.creators.delete(node.access);\n\t\t}\n\t\tif(this.creationReaders.get(node.access) === node) {\n\t\t\tthis.creationReaders.delete(node.access);\n\t\t}\n\t\tfor(const component of new Set([...node.access.reads, ...node.access.writes, ...node.access.creates])) {\n\t\t\tconst frontier = this.frontiers.get(component);\n\t\t\tif(frontier?.writer === node) {\n\t\t\t\tfrontier.writer = undefined;\n\t\t\t}\n\t\t\tif(frontier?.creator === node) {\n\t\t\t\tfrontier.creator = undefined;\n\t\t\t}\n\t\t\tif(frontier?.readers.get(node.system) === node) {\n\t\t\t\tfrontier.readers.delete(node.system);\n\t\t\t}\n\t\t\tif(frontier && !frontier.writer && !frontier.creator && !frontier.readers.size) {\n\t\t\t\tthis.frontiers.delete(component);\n\t\t\t}\n\t\t}\n\t\tfor(const dependent of node.dependents) {\n\t\t\tif(--dependent.dependencies === 0) {\n\t\t\t\tthis.ready.push(dependent);\n\t\t\t}\n\t\t}\n\t\tnode.dependents.length = 0;\n\t\tfor(const dependent of node.publicationDependents) {\n\t\t\tdependent.publicationDependencies--;\n\t\t\tif(dependent.publicationDependencies === 0 && dependent.effects) {\n\t\t\t\tthis.publicationReady.push(dependent);\n\t\t\t}\n\t\t}\n\t\tnode.publicationDependents.length = 0;\n\t\tthis.publish();\n\t}\n\n\tprivate dispatch(context: SchedulerContext<C>, node: ScheduledUpdate<C>, continuation: boolean): SchedulerUpdateResult | undefined {\n\t\tconst system = node.system;\n\t\tif(!continuation && !context.systems.includes(system)) {\n\t\t\tthis.complete(node);\n\t\t\treturn {};\n\t\t}\n\t\tconst generation = this.generation;\n\t\tlet shouldRun = true;\n\t\tlet ran = false;\n\t\tlet failed = false;\n\t\tlet lastSystemError: Error | null = null;\n\t\tcontext.emit(`system-${system.name}-started`);\n\t\tif(!this.nodes.has(node) || !this.dispatchAllowed(context)) {\n\t\t\treturn undefined;\n\t\t}\n\t\ttry {\n\t\t\tconst dispatched = system.withGameTime(node.gameTime, () => {\n\t\t\t\tshouldRun = continuation || system.shouldRun();\n\t\t\t\tif(!this.nodes.has(node) || !this.dispatchAllowed(context)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif(shouldRun) {\n\t\t\t\t\tnode.state = 'running';\n\t\t\t\t\tthis.running.set(system, node);\n\t\t\t\t\tran = system.update(continuation ? 0 : node.elapsedTime);\n\t\t\t\t\tif(generation === this.generation && !system.isCurrentlyRunning()) {\n\t\t\t\t\t\tthis.complete(node);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.complete(node);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\t\tif(!dispatched) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t} catch(e) {\n\t\t\tconst error = e as Error;\n\t\t\tconsole.error(error.message, error);\n\t\t\tfailed = true;\n\t\t\tlastSystemError = error;\n\t\t\tif(generation === this.generation) {\n\t\t\t\tif(system.isCurrentlyRunning()) {\n\t\t\t\t\tnode.state = 'running';\n\t\t\t\t\tthis.running.set(system, node);\n\t\t\t\t} else {\n\t\t\t\t\tthis.complete(node);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.emit('system-error', { system: system.name, error, phase: 'run' });\n\t\t}\n\t\tcontext.emit(`system-${system.name}-finished`, { ran, shouldRun, failed });\n\t\treturn { lastSystemError };\n\t}\n\n\tprivate prepare(context: SchedulerContext<C>): boolean {\n\t\treturn this.dispatchAllowed(context) && context.prepareForSystemDispatch?.() !== false;\n\t}\n\n\tprivate dispatchAllowed(context: SchedulerContext<C>): boolean {\n\t\treturn context.dispatchAllowed !== false;\n\t}\n\tprivate observesCreation(creator: SystemAccess, reader: SystemAccess): boolean {\n\t\tfor(const component of reader.creationReads) {\n\t\t\tif(creator.creates.has(component)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn reader.creationQueries?.some(query => query.every(component => creator.creates.has(component))) ?? false;\n\t}\n\n\tprivate conflicts(a: SystemAccess, b: SystemAccess): boolean {\n\t\tif(a.exclusive || b.exclusive) {\n\t\t\treturn true;\n\t\t}\n\t\tfor(const component of a.writes) {\n\t\t\tif(b.reads.has(component) || b.writes.has(component)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tfor(const component of b.writes) {\n\t\t\tif(a.reads.has(component)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tfor(const component of a.creates) {\n\t\t\tif(b.writes.has(component)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn a.creates.size > 0 && this.observesCreation(a, b);\n\t}\n}\n","import type { ComponentDefinitionMap, EntityConfigOf } from './component-definition';\n\nexport type EntityClassConstructor = abstract new (...args: never[]) => { readonly eid: number };\n\nexport interface EntityClassDefinition {\n\tentity: EntityClassConstructor\n\tcomponents: ReadonlyArray<string>\n}\n\nexport type EntityClassRegistry = Record<string, EntityClassDefinition>;\n\ndeclare const ENTITY_CLASSES_TYPE: unique symbol;\n\nexport type DefinedEntityClasses<\n\tR extends ComponentDefinitionMap,\n\tClasses extends EntityClassRegistry,\n> = Classes & { readonly [ENTITY_CLASSES_TYPE]: R };\n\nexport type EntityInstancesOf<Classes extends EntityClassRegistry> = InstanceType<Classes[keyof Classes & string]['entity']>;\n\ntype RegistryOf<Classes extends EntityClassRegistry> = Classes extends DefinedEntityClasses<infer R, EntityClassRegistry> ? R : never;\ntype ComponentKeysOf<Definition> = Definition extends { components: ReadonlyArray<infer K> } ? K : never;\n\nexport type EntityClassTemplateConfig<\n\tClasses extends EntityClassRegistry,\n\tClassName extends keyof Classes & string,\n\tR extends ComponentDefinitionMap = RegistryOf<Classes>,\n> = EntityConfigOf<Pick<R, Extract<ComponentKeysOf<Classes[ClassName]>, keyof R>>> & {\n\ttype: string\n\tclass: ClassName\n};\n\nexport type EntityTemplateConfigOf<Classes extends EntityClassRegistry> = {\n\t[ClassName in keyof Classes & string]: EntityClassTemplateConfig<Classes, ClassName>\n}[keyof Classes & string];\n\nexport type EntityInstanceConfigOf<Classes extends EntityClassRegistry> = EntityTemplateConfigOf<Classes> extends infer Config\n\t? Config extends object ? Omit<Config, 'class'> & { class?: never } : never\n\t: never;\n\ntype EntityClassInput<R extends ComponentDefinitionMap> = Record<string, {\n\tentity: EntityClassConstructor\n\tcomponents: ReadonlyArray<keyof R & string>\n}>;\n\ntype ExactEntityConfig<Classes extends EntityClassRegistry, ClassName extends keyof Classes & string, Type, Config> = Config\n\t& EntityClassTemplateConfig<Classes, ClassName>\n\t& { type: Type }\n\t& Record<Exclude<keyof Config, keyof EntityClassTemplateConfig<Classes, ClassName>>, never>;\n\ntype CheckedEntityConfig<Classes extends EntityClassRegistry, Type, Config> =\n\tConfig extends { class: infer ClassName }\n\t\t? ClassName extends keyof Classes & string\n\t\t\t? ExactEntityConfig<Classes, ClassName, Type, Config>\n\t\t\t: never\n\t\t: never;\n\ntype CheckedEntityConfigs<Classes extends EntityClassRegistry, Configs> = {\n\t[K in keyof Configs]: CheckedEntityConfig<Classes, K, Configs[K]>\n};\n\nexport function defineEntityClasses<\n\tR extends ComponentDefinitionMap,\n\tconst Classes extends EntityClassInput<R>,\n>(_registry: R, classes: Classes): DefinedEntityClasses<R, Classes> {\n\treturn classes as DefinedEntityClasses<R, Classes>;\n}\n\nexport function defineEntityConfigs<\n\tClasses extends EntityClassRegistry,\n\tconst Configs extends Record<string, { type: string, class: keyof Classes & string }>,\n>(_classes: Classes, configs: Configs & CheckedEntityConfigs<Classes, Configs>): Configs {\n\treturn configs;\n}\n\nexport interface WorkerEntityClassDefinition {\n\tcomponents: Array<string>\n}\n\nexport type WorkerEntityClassRegistry = Record<string, WorkerEntityClassDefinition>;\n","import type BaseEntity from '../entity';\n\n// Flags the entity dead in shared memory and emits `death`; BaseWorld listens for it to remove the entity.\nexport default function killEntity(entity: BaseEntity): void {\n\tentity.components.entity.dead = true;\n\tentity.emit('death');\n}\n","import { EventEmitter } from 'eventemitter3';\nimport type BaseWorld from './world';\nimport type { ComponentDefinitionMap, ComponentMap } from './component-definition';\nimport type System from './systems/system';\nimport type { EntityWorkBatch } from './systems/workers/entity-system-worker-message';\n\nexport const DEFAULT_TICKS_BETWEEN_UPDATES = 1_000;\n\nexport interface TimingStats {\n\tavg: number\n\tmin: number\n\tmax: number\n\tsamples: number\n}\n\nexport interface SystemTimingStats {\n\tname: string\n\trun: TimingStats\n\tevents: TimingStats\n}\n\nexport interface PerformanceStats {\n\tupdate: TimingStats\n\tsystems: Array<SystemTimingStats>\n\tevents: TimingStats\n}\n\nexport interface PerformanceTimingOptions {\n\tticksBetweenUpdates?: number\n\tautoUpdate?: boolean\n}\n\ninterface SystemTiming {\n\trun: Array<number>\n\tevents: Array<number>\n\tpendingRun: number\n\tpendingEvents: number\n\t// -1 when no run is being dispatched.\n\teventStart: number\n\tonRunFinished: (runTime: number, batch?: Pick<EntityWorkBatch, 'first' | 'last'>) => void\n\tonEventsFinished: (runTime: number, batch?: Pick<EntityWorkBatch, 'first' | 'last'>) => void\n}\n\nconst EMPTY_TIMING: TimingStats = { avg: 0, min: 0, max: 0, samples: 0 };\n\n// An empty window reads as zeroes (not an infinite min) so a snapshot is always safe to render.\nfunction summarize(samples: Array<number>): TimingStats {\n\tif(!samples.length) {\n\t\treturn { ...EMPTY_TIMING };\n\t}\n\n\tlet total = 0;\n\tlet min = Infinity;\n\tlet max = 0;\n\tfor(let sample of samples) {\n\t\ttotal += sample;\n\t\tif(sample < min) {\n\t\t\tmin = sample;\n\t\t}\n\t\tif(sample > max) {\n\t\t\tmax = sample;\n\t\t}\n\t}\n\n\treturn {\n\t\tavg: total / samples.length,\n\t\tmin,\n\t\tmax,\n\t\tsamples: samples.length,\n\t};\n}\n\n// Watches a world and reports what it costs to run, driven off events the world emits. Emits `stats-updated`\n// every `ticksBetweenUpdates`; paused frames are skipped.\nexport default class PerformanceTiming<C extends ComponentMap = ComponentMap> extends EventEmitter {\n\tworld: BaseWorld<ComponentDefinitionMap, C>;\n\tticksBetweenUpdates: number;\n\tstats: PerformanceStats = {\n\t\tupdate: { ...EMPTY_TIMING },\n\t\tsystems: [],\n\t\tevents: { ...EMPTY_TIMING },\n\t};\n\n\tprivate readonly autoUpdate: boolean;\n\tprivate ticks = 0;\n\tprivate updateStart = 0;\n\tprivate updateTimes: Array<number> = [];\n\tprivate systemTimings = new Map<string, SystemTiming>();\n\tprivate destroyed = false;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: PerformanceTimingOptions = {}) {\n\t\tsuper();\n\n\t\tthis.world = world;\n\t\tthis.autoUpdate = options.autoUpdate ?? true;\n\t\tthis.ticksBetweenUpdates = options.ticksBetweenUpdates ?? DEFAULT_TICKS_BETWEEN_UPDATES;\n\n\t\tworld.on('update-started', this.onUpdateStarted);\n\t\tworld.on('update-finished', this.onUpdateFinished);\n\t\tworld.on('system-added', this.onSystemAdded);\n\t\tworld.on('system-removed', this.onSystemRemoved);\n\t\tworld.systems.forEach(system => this.trackSystem(system));\n\t}\n\n\tgetSystemStats(name: string): SystemTimingStats | undefined {\n\t\treturn this.stats.systems.find(system => system.name === name);\n\t}\n\n\treset() {\n\t\tthis.ticks = 0;\n\t\tthis.updateTimes = [];\n\t\tthis.systemTimings.forEach(timing => {\n\t\t\ttiming.run = [];\n\t\t\ttiming.events = [];\n\t\t\ttiming.eventStart = -1;\n\t\t\ttiming.pendingRun = 0;\n\t\t\ttiming.pendingEvents = 0;\n\t\t});\n\t\tthis.stats = {\n\t\t\tupdate: { ...EMPTY_TIMING },\n\t\t\tsystems: [],\n\t\t\tevents: { ...EMPTY_TIMING },\n\t\t};\n\t}\n\n\tdestroy() {\n\t\tif(this.destroyed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.destroyed = true;\n\n\t\tthis.world.off('update-started', this.onUpdateStarted);\n\t\tthis.world.off('update-finished', this.onUpdateFinished);\n\t\tthis.world.off('system-added', this.onSystemAdded);\n\t\tthis.world.off('system-removed', this.onSystemRemoved);\n\t\tArray.from(this.systemTimings.keys()).forEach(name => this.untrackSystem(name));\n\t\tthis.removeAllListeners();\n\t}\n\n\tprivate onUpdateStarted = () => {\n\t\tthis.updateStart = performance.now();\n\t};\n\n\tprivate onUpdateFinished = (elapsedTime: number) => {\n\t\tif(this.world.paused) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateTimes.push(performance.now() - this.updateStart);\n\n\t\tthis.ticks += elapsedTime;\n\t\tif(this.autoUpdate && this.ticks >= this.ticksBetweenUpdates) {\n\t\t\tthis.flush();\n\t\t}\n\t};\n\n\tprivate onSystemAdded = (system: System<C>) => {\n\t\tthis.trackSystem(system);\n\t};\n\n\tprivate onSystemRemoved = (system: System<C>) => {\n\t\tthis.untrackSystem(system.name);\n\t};\n\n\t// The gap between `-worker-finished` (before events dispatch) and `-worker-events-finished` (after) is what\n\t// that run cost this thread. Both fire for the main-thread fallback too.\n\tprivate trackSystem(system: System<C>) {\n\t\tif(this.systemTimings.has(system.name)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst timing: SystemTiming = {\n\t\t\trun: [],\n\t\t\tevents: [],\n\t\t\teventStart: -1,\n\t\t\tpendingRun: 0,\n\t\t\tpendingEvents: 0,\n\t\t\tonRunFinished: (runTime, batch) => {\n\t\t\t\tif(!batch || batch.first) {\n\t\t\t\t\ttiming.pendingRun = 0;\n\t\t\t\t\ttiming.pendingEvents = 0;\n\t\t\t\t}\n\t\t\t\ttiming.pendingRun += runTime;\n\t\t\t\tif(!batch || batch.last) {\n\t\t\t\t\ttiming.run.push(timing.pendingRun);\n\t\t\t\t\ttiming.pendingRun = 0;\n\t\t\t\t}\n\t\t\t\ttiming.eventStart = performance.now();\n\t\t\t},\n\t\t\tonEventsFinished: (_runTime, batch) => {\n\t\t\t\tif(timing.eventStart < 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttiming.pendingEvents += performance.now() - timing.eventStart;\n\t\t\t\tif(!batch || batch.last) {\n\t\t\t\t\ttiming.events.push(timing.pendingEvents);\n\t\t\t\t\ttiming.pendingEvents = 0;\n\t\t\t\t}\n\t\t\t\ttiming.eventStart = -1;\n\t\t\t},\n\t\t};\n\n\t\tthis.world.on(`system-${system.name}-worker-finished`, timing.onRunFinished);\n\t\tthis.world.on(`system-${system.name}-worker-events-finished`, timing.onEventsFinished);\n\t\tthis.systemTimings.set(system.name, timing);\n\t}\n\n\tprivate untrackSystem(name: string) {\n\t\tconst timing = this.systemTimings.get(name);\n\t\tif(!timing) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.world.off(`system-${name}-worker-finished`, timing.onRunFinished);\n\t\tthis.world.off(`system-${name}-worker-events-finished`, timing.onEventsFinished);\n\t\tthis.systemTimings.delete(name);\n\t}\n\n\tflush(): PerformanceStats {\n\t\tif(this.destroyed) {\n\t\t\treturn this.stats;\n\t\t}\n\n\t\tconst systems = this.world.systems.map(system => {\n\t\t\tconst timing = this.systemTimings.get(system.name);\n\t\t\treturn {\n\t\t\t\tname: system.name,\n\t\t\t\trun: summarize(timing?.run ?? []),\n\t\t\t\tevents: summarize(timing?.events ?? []),\n\t\t\t};\n\t\t});\n\n\t\tconst events: TimingStats = { ...EMPTY_TIMING };\n\t\tsystems.forEach(system => {\n\t\t\tevents.avg += system.events.avg;\n\t\t\tevents.min += system.events.min;\n\t\t\tevents.max += system.events.max;\n\t\t\tevents.samples += system.events.samples;\n\t\t});\n\n\t\tthis.stats = {\n\t\t\tupdate: summarize(this.updateTimes),\n\t\t\tsystems,\n\t\t\tevents,\n\t\t};\n\n\t\tthis.ticks = 0;\n\t\tthis.updateTimes = [];\n\t\tthis.systemTimings.forEach(timing => {\n\t\t\ttiming.run = [];\n\t\t\ttiming.events = [];\n\t\t});\n\n\t\tthis.emit('stats-updated', this.stats);\n\t\treturn this.stats;\n\t}\n}\n","import type BaseWorld from '../world';\nimport type { ComponentDefinitionMap, ComponentMap } from '../component-definition';\nimport type { SystemConfig } from './system';\nimport EntityWorkerSystem, {\n\ttype EntityWorkerSystemQuery, type EntityWorkerSystemWorld, type EntityUpdateComponents,\n} from './entity-worker-system';\nimport { toEntityUpdateFunction, type WorkerSystemInitFunction, type WorkerSystemRunFunction } from './workers/create-system-worker';\n\n// An EntityWorkerSystem that runs its update function once per tick instead of once per entity. It accepts the same\n// named `queries` (so it can count/scan other entities), runs on its own worker, can create entities off-thread, and\n// receives fresh per-run data via addDataToWorld — all reusing the EntityWorkerSystem machinery. It has no main query:\n// all work happens in the single run function over the named sub-queries.\nexport default class WorkerSystem<\n\tC extends ComponentMap,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> extends EntityWorkerSystem<C, EntityUpdateComponents<C>, W, D> {\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: WorkerSystemConfig<C, W, D>) {\n\t\tsuper(world, {\n\t\t\t...options,\n\t\t\t// No main query: the run function works entirely over the named sub-queries.\n\t\t\trequired: [],\n\t\t\tupdateFunction: toEntityUpdateFunction(options.updateFunction),\n\t\t});\n\t}\n\n\t// Sub-query membership is maintained as usual so the run function still sees it.\n\tprotected get tracksMainQuery(): boolean {\n\t\treturn false;\n\t}\n\n\t// Runs every interval regardless of membership, since its work is the single run function over sub-queries.\n\tshouldRun(): boolean {\n\t\treturn true;\n\t}\n}\n\nexport interface WorkerSystemConfig<\n\tC extends ComponentMap,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> extends SystemConfig<C> {\n\tupdateFunction: WorkerSystemRunFunction<C, W, D>\n\tgetWorker: () => Worker\n\tforceMainThread?: boolean\n\tgetInitData?: () => D\n\tcreatesEntities?: boolean | ReadonlyArray<keyof C>\n\tqueries?: { [key: string]: EntityWorkerSystemQuery<C> }\n}\n\nexport type { WorkerSystemInitFunction, WorkerSystemRunFunction };\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../node_modules/eventemitter3/index.js","../node_modules/eventemitter3/index.mjs","../src/systems/system.ts","../src/systems/iterable-system.ts","../src/systems/entity-system.ts","../src/systems/workers/web-worker.ts","../src/systems/workers/entity-system-web-worker.ts","../src/systems/entity-worker-system.ts","../src/entity.ts","../src/entity-factory.ts","../src/entity-compression.ts","../src/scheduling/default-scheduler.ts","../src/world.ts","../src/scheduling/conflict-scheduler.ts","../src/entity-class.ts","../src/actions/kill-entity.ts","../src/performance-timing.ts","../src/systems/worker-system.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","import EventEmitter from './index.js'\n\nexport { EventEmitter }\nexport default EventEmitter\n","import { EventEmitter } from 'eventemitter3';\nimport type BaseWorld from '../world';\nimport type BaseEntity from '../entity';\nimport type { ComponentDefinitionMap, ComponentMap } from '../component-definition';\n\n// Base system: runs on an optional fixed timestep (deltaBetweenRuns), driven by BaseWorld#update.\nexport default abstract class System<C extends ComponentMap = ComponentMap> extends EventEmitter {\n\tworld: BaseWorld<ComponentDefinitionMap, C>;\n\tname: string;\n\tcurrentDelta: number = 0;\n\tdeltaBetweenRuns: number;\n\tfirstRun: boolean;\n\treadonly reads?: ReadonlyArray<PropertyKey>;\n\treadonly writes?: ReadonlyArray<PropertyKey>;\n\tprivate readonly exclusive: boolean;\n\tprivate scheduledGameTime: number | undefined;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: SystemConfig<C> = { name: 'System' }) {\n\t\tsuper();\n\n\t\tthis.name = options.name;\n\t\tthis.world = world;\n\t\tthis.reads = options.reads;\n\t\tthis.writes = options.writes;\n\t\tthis.exclusive = options.exclusive ?? false;\n\n\t\tthis.deltaBetweenRuns = options.deltaBetweenRuns ?? 0;\n\t\tthis.firstRun = options.firstRun !== undefined ? options.firstRun : false;\n\t}\n\n\tinit(): void | Promise<void> {}\n\n\tclear() {\n\t\tthis.currentDelta = 0;\n\t}\n\t// Called once the world's entities all exist: the point a system hands its startup data off (see EntityWorkerSystem).\n\tfinishLoading(): void | Promise<void> {}\n\t// world.load() joins its whole batch here instead of one entity-added at a time.\n\taddEntities(batch: EntityBatch<C>): void {}\n\n\tget gameTime(): number {\n\t\treturn this.scheduledGameTime ?? this.world.gameTime;\n\t}\n\twithGameTime<T>(gameTime: number, update: () => T): T {\n\t\tconst previous = this.scheduledGameTime;\n\t\tthis.scheduledGameTime = gameTime;\n\t\ttry {\n\t\t\treturn update();\n\t\t} finally {\n\t\t\tthis.scheduledGameTime = previous;\n\t\t}\n\t}\n\tupdate(elapsedTime: number): boolean {\n\t\tthis.currentDelta += elapsedTime;\n\n\t\tif(this.currentDelta >= this.deltaBetweenRuns || this.firstRun) {\n\t\t\tlet leftOverDelta = 0;\n\t\t\tif(this.deltaBetweenRuns > 0) {\n\t\t\t\t// Carry the remainder so a run that overshoots its timestep doesn't drift the next one later.\n\t\t\t\tleftOverDelta = this.currentDelta % this.deltaBetweenRuns;\n\t\t\t}\n\n\t\t\tthis.run(this.currentDelta - leftOverDelta);\n\t\t\tthis.currentDelta = leftOverDelta;\n\t\t\tthis.firstRun = false;\n\t\t\tthis.onRunFinished();\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\tabstract run(elapsedTime: number): void;\n\n\t// Logs and surfaces an error thrown by user code (an update body, preRun, etc.) on the main thread: a\n\t// `system-error` event carrying the system name, so a run keeps going past one failure instead of aborting.\n\tprotected onError(error: Error, context: { entityId?: number, phase?: SystemErrorPhase } = {}) {\n\t\tconst where = context.entityId !== undefined ? ` (entity ${context.entityId})` : '';\n\t\tconsole.error(`Error in system ${this.name}${where}: ${error.message}`, error);\n\t\tconst payload: SystemError = { system: this.name, error, entityId: context.entityId, phase: context.phase };\n\t\tthis.world.emit('system-error', payload);\n\t}\n\n\t// Marks one run as fully applied. Synchronous systems finish inside update(); subclasses whose work is\n\t// deferred (spread across frames, or off-thread) override this and call it at their real completion point.\n\tprotected onRunFinished() {\n\t\tthis.world.notifySystemRunCompleted(this);\n\t}\n\t// True while a run is still in progress between update() calls (a worker round-trip, or an iteration spread\n\t// across frames). Used by the world to keep waiting on a system that is mid-run over memory it may free.\n\tisCurrentlyRunning(): boolean {\n\t\treturn false;\n\t}\n\t// Resolves once any in-flight run has finished, so the world's clear() knows nothing is still reading memory\n\twaitForRunToComplete(): void | Promise<void> {}\n\n\tshouldRun(): boolean {\n\t\treturn true;\n\t}\n\tget readComponents(): ReadonlyArray<PropertyKey> | undefined {\n\t\treturn this.reads;\n\t}\n\tget requiresExclusiveScheduling(): boolean {\n\t\treturn this.exclusive;\n\t}\n\tget createdComponents(): ReadonlyArray<PropertyKey> {\n\t\treturn [];\n\t}\n\tget creationReadComponents(): ReadonlyArray<PropertyKey> | undefined {\n\t\treturn this.readComponents;\n\t}\n\tget creationReadQueries(): ReadonlyArray<ReadonlyArray<PropertyKey>> | undefined {\n\t\treturn undefined;\n\t}\n\n\tdestroy() {\n\t\tthis.removeAllListeners();\n\t}\n}\n\n// A load batch in load order. Entities with identical component keys share a group, so a query's component test is\n// answered once per group rather than once per entity.\nexport interface EntityBatch<C extends ComponentMap = ComponentMap> {\n\tentities: Array<BaseEntity<C>>\n\t// Per entity, its index into `groups`.\n\tgroupIndexes: Array<number>\n\t// One representative entity per distinct component-key set.\n\tgroups: Array<BaseEntity<C>>\n}\n\n// Visits, in load order, each entity whose group passes `matchesGroup`.\nexport function forEachInMatchingGroups<C extends ComponentMap>(batch: EntityBatch<C>, matchesGroup: (representative: BaseEntity<C>) => boolean, callback: (entity: BaseEntity<C>) => void) {\n\tconst matches = batch.groups.map(matchesGroup);\n\tfor(let i = 0; i < batch.entities.length; i++) {\n\t\tif(matches[batch.groupIndexes[i]]) {\n\t\t\tcallback(batch.entities[i]);\n\t\t}\n\t}\n}\n\nexport interface SystemConfig<C extends ComponentMap = ComponentMap> {\n\tname: string\n\tdeltaBetweenRuns?: number\n\tfirstRun?: boolean\n\treads?: ReadonlyArray<keyof C>\n\twrites?: ReadonlyArray<keyof C>\n\texclusive?: boolean\n}\n\n// Which part of a run threw, for the `system-error` event.\nexport type SystemErrorPhase = 'queryChanged' | 'preRun' | 'preBatch' | 'update' | 'entityRemoved' | 'run' | 'died';\nexport interface SystemError {\n\tsystem: string\n\terror: Error\n\tentityId?: number\n\tphase?: SystemErrorPhase\n}\n","import type BaseWorld from '../world';\nimport type { ComponentDefinitionMap, ComponentMap } from '../component-definition';\nimport System, { type SystemConfig } from './system';\n\nexport default abstract class IterableSystem<C extends ComponentMap, T> extends System<C> {\n\tremainingInstancesToRun: Array<T> = [];\n\tremainingInstancesStartTime: number | null = null;\n\titerationsPerCheck: number;\n\tmaxMsPerFrame: number;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: IterableSystemConfig<C>) {\n\t\tsuper(world, options);\n\n\t\tthis.iterationsPerCheck = options.iterationsPerCheck ?? 1;\n\t\tthis.maxMsPerFrame = options.maxMsPerFrame ?? 10;\n\t}\n\n\tclear() {\n\t\tsuper.clear();\n\n\t\tthis.remainingInstancesToRun = [];\n\t\tthis.remainingInstancesStartTime = null;\n\t}\n\n\tupdate(elapsedTime: number): boolean {\n\t\tif(this.remainingInstancesToRun.length) {\n\t\t\tthis.runIterables(this.remainingInstancesToRun, this.remainingInstancesStartTime ?? 0);\n\t\t\tthis.currentDelta += elapsedTime;\n\t\t\tif(!this.remainingInstancesToRun.length) {\n\t\t\t\tthis.onRunFinished();\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn super.update(elapsedTime);\n\t\t}\n\t}\n\trun(elapsedTime: number): void {\n\t\tlet iterables = this.getIterables();\n\t\tthis.runIterables(iterables, elapsedTime);\n\t}\n\t// A run that overflowed onto a later frame isn't finished yet; only count it once the queue drains (handled\n\t// by update() when it empties remainingInstancesToRun).\n\tprotected onRunFinished() {\n\t\tif(this.remainingInstancesToRun.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tsuper.onRunFinished();\n\t}\n\tisCurrentlyRunning(): boolean {\n\t\treturn this.remainingInstancesToRun.length > 0;\n\t}\n\n\trunIterables(iterables: Array<T>, elapsedTime: number) {\n\t\tlet started = performance.now();\n\t\ttry {\n\t\t\tthis.beforeRunIterables();\n\t\t} catch(e) {\n\t\t\t// preRun failed: skip the iteration this frame rather than run over half-prepared state.\n\t\t\tthis.onError(e as Error, { phase: 'preRun' });\n\t\t\tthis.remainingInstancesToRun = [];\n\t\t\tthis.remainingInstancesStartTime = null;\n\t\t\treturn;\n\t\t}\n\t\tfor(let i = 0; i < iterables.length; i++) {\n\t\t\ttry {\n\t\t\t\tthis.updateIterable(iterables[i], elapsedTime);\n\t\t\t} catch(e) {\n\t\t\t\t// One iterable failing must not stop the rest of the run.\n\t\t\t\tthis.onError(e as Error, { phase: 'update', entityId: this.getIterableEntityId(iterables[i]) });\n\t\t\t}\n\n\t\t\tif(i % this.iterationsPerCheck === 0) {\n\t\t\t\tlet now = performance.now();\n\t\t\t\tif(now - started >= this.maxMsPerFrame) {\n\t\t\t\t\tthis.remainingInstancesToRun = iterables.slice(i + 1);\n\t\t\t\t\tthis.remainingInstancesStartTime = elapsedTime;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.remainingInstancesToRun = [];\n\t\tthis.remainingInstancesStartTime = null;\n\t}\n\tbeforeRunIterables() {}\n\t// Best-effort eid for a failed iterable, so `system-error` can name it. Subclasses whose T carries an eid override.\n\tprotected getIterableEntityId(_iterable: T): number | undefined {\n\t\treturn undefined;\n\t}\n\n\tabstract getIterables(): Array<T>;\n\tabstract updateIterable(iterable: T, elapsedTime: number): void;\n}\n\nexport interface IterableSystemConfig<C extends ComponentMap = ComponentMap> extends SystemConfig<C> {\n\titerationsPerCheck?: number\n\tmaxMsPerFrame?: number\n}\n","import type BaseWorld from '../world';\nimport type BaseEntity from '../entity';\nimport type { ComponentDefinitionMap, ComponentMap } from '../component-definition';\nimport IterableSystem, { type IterableSystemConfig } from './iterable-system';\nimport { forEachInMatchingGroups, type EntityBatch } from './system';\n\n// Iterates the entities owning a given set of components on the main thread; membership tracks world events.\nexport default abstract class EntitySystem<C extends ComponentMap, T extends BaseEntity<C> = BaseEntity<C>> extends IterableSystem<C, T> {\n\tentities: Map<number, T> = new Map();\n\toptions: EntitySystemConfig<C>;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: EntitySystemConfig<C> = { name: 'EntitySystem' }) {\n\t\tif(!options.iterationsPerCheck) {\n\t\t\toptions.iterationsPerCheck = 10;\n\t\t}\n\t\tif(!options.maxMsPerFrame) {\n\t\t\toptions.maxMsPerFrame = 4;\n\t\t}\n\n\t\tsuper(world, options);\n\t\tthis.options = options;\n\n\t\tworld.on('entity-added', (entity: BaseEntity<C>) => {\n\t\t\tif(!world.isBulkLoading) {\n\t\t\t\tthis.onEntityAdded(entity);\n\t\t\t}\n\t\t});\n\t\tworld.on('entity-removed', (entity: BaseEntity<C>) => {\n\t\t\tthis.removeEntity(entity);\n\t\t});\n\n\t\tworld.entities.forEach(entity => {\n\t\t\tthis.checkAddEntity(entity);\n\t\t});\n\t}\n\n\tgetIterables(): Array<T> {\n\t\tconst iterables: Array<T> = [];\n\t\tthis.entities.forEach(entity => {\n\t\t\tif(!entity.components.entity.dead) {\n\t\t\t\titerables.push(entity);\n\t\t\t}\n\t\t});\n\n\t\treturn iterables;\n\t}\n\tupdateIterable(entity: T, elapsedTime: number): void {\n\t\t// A multi-frame snapshot can outlive query membership. Revalidate the exact instance before touching it.\n\t\tif(entity.components.entity.dead || this.entities.get(entity.eid) !== entity) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateEntity(entity, elapsedTime);\n\t}\n\tfilterEntity(entity: BaseEntity<C>): boolean {\n\t\treturn !entity.components.entity.isStatic;\n\t}\n\tprotected getIterableEntityId(entity: T): number {\n\t\treturn entity.eid;\n\t}\n\tisEntityInSystem(entity: BaseEntity<C>) {\n\t\treturn this.entities.has(entity.eid);\n\t}\n\tabstract updateEntity(entity: T, elapsedTime: number): void;\n\n\tprivate onEntityAdded(entity: BaseEntity<C>) {\n\t\tif(this.checkAddEntity(entity) && this.options.updateEntityOnAdd) {\n\t\t\tthis.updateEntity(entity as T, 0);\n\t\t}\n\t}\n\taddEntities(batch: EntityBatch<C>): void {\n\t\t// A subclass with its own membership rule gets it applied per entity, exactly as entity-added would.\n\t\tif(this.checkAddEntity !== EntitySystem.prototype.checkAddEntity) {\n\t\t\tbatch.entities.forEach(entity => this.onEntityAdded(entity));\n\t\t\treturn;\n\t\t}\n\n\t\tforEachInMatchingGroups(batch, entity => this.hasComponents(entity), entity => {\n\t\t\tif(this.filterEntity(entity)) {\n\t\t\t\tthis.entities.set(entity.eid, entity as T);\n\t\t\t\tif(this.options.updateEntityOnAdd) {\n\t\t\t\t\tthis.updateEntity(entity as T, 0);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tprivate hasComponents(entity: BaseEntity<C>): boolean {\n\t\treturn !this.options.components || this.options.components.every(component => !!entity.components[component]);\n\t}\n\n\tcheckAddEntity(entity: BaseEntity<C>): boolean {\n\t\tif(!this.hasComponents(entity)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.filterEntity(entity)) {\n\t\t\tthis.entities.set(entity.eid, entity as T);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\tremoveEntity(entity: BaseEntity<C>) {\n\t\tthis.entities.delete(entity.eid);\n\t}\n\n\tshouldRun(): boolean {\n\t\t// A continuation must drain even if every live member left since the previous frame.\n\t\treturn this.isCurrentlyRunning() || this.entities.size > 0;\n\t}\n\tget creationReadComponents(): ReadonlyArray<PropertyKey> | undefined {\n\t\tif(!this.options.components) {\n\t\t\treturn this.reads ? ['entity', ...this.reads] : undefined;\n\t\t}\n\t\tconst required = this.options.components.filter(component => component !== 'entity');\n\t\treturn [...this.reads ?? [], ...required.length ? required : ['entity']];\n\t}\n\tget creationReadQueries(): ReadonlyArray<ReadonlyArray<PropertyKey>> | undefined {\n\t\tif(this.checkAddEntity !== EntitySystem.prototype.checkAddEntity) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [this.options.components ?? []];\n\t}\n\tget readComponents(): ReadonlyArray<PropertyKey> | undefined {\n\t\tconst components = this.options.components ?? this.reads;\n\t\treturn components ? ['entity', ...components, ...this.reads ?? []] : undefined;\n\t}\n}\n\nexport interface EntitySystemConfig<C extends ComponentMap> extends IterableSystemConfig<C> {\n\tcomponents?: Array<keyof C>\n\tupdateEntityOnAdd?: boolean\n}\n","// Minimal Worker-like base for the main-thread fallback. Loose params: this mirrors the DOM Worker boundary.\nexport default abstract class WebWorker {\n\tabstract postMessage(message: any): void | Promise<void>;\n\tonmessage(message: any, transferrables: Array<any> = []): void {\n\n\t}\n}\n","import WebWorker from './web-worker';\nimport QueryMembership from './query-membership';\nimport EntityWorkBatchState from './entity-work-batch';\nimport type EntitySystemWorkerMessage from './entity-system-worker-message';\nimport type { EntityEvent, SystemEvents, WorkerRunError } from './entity-system-worker-message';\nimport type BaseWorld from '../../world';\nimport type { ComponentDefinitionMap, ComponentMap, RegisteredComponentRegistry } from '../../component-definition';\nimport type {\n\tEntityWorkerSystemCallbacks, EntityWorkerSystemWorld, EntityQueryComponents, EntityUpdateComponents,\n\tEntityUpdateFunction, QueryDelta, WorkerAllocator, WorkerComponentChange, WorkerCreatedEntity,\n} from '../entity-worker-system';\nimport { buildWorkerComponent, buildWorkerEntity, type WorkerCreateRegistry } from '../../actions/build-worker-entity';\n\n// Main-thread fallback that runs the update function synchronously, mirroring the real worker's behavior.\nexport default class EntitySystemWebWorker<C extends ComponentMap, T extends EntityUpdateComponents<C>, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld, D = unknown> extends WebWorker {\n\tprivate updateFunction: EntityUpdateFunction<C, T, W, D>;\n\tprivate entities = new QueryMembership<T>();\n\tprivate workState = new EntityWorkBatchState<T, W>();\n\tprivate queryEntities: { [key: string]: QueryMembership<T> } = {};\n\t// Mirrors createEntitySystemWorker: updateFunction.init's result, merged onto `world` each run.\n\tprivate worldExtension: Partial<W> | undefined;\n\t// Running on the main thread, this shares the world (its string cache, registry pools, eid counter) directly.\n\tprivate world: BaseWorld<ComponentDefinitionMap, C>;\n\tprivate allocator: WorkerAllocator;\n\tprivate createsEntities: boolean;\n\tprivate addsComponents: boolean;\n\n\tconstructor(\n\t\tupdateFunction: EntityUpdateFunction<C, T, W, D>,\n\t\tworld: BaseWorld<ComponentDefinitionMap, C>,\n\t\tcreatesEntities = false,\n\t\taddsComponents = false,\n\t) {\n\t\tsuper();\n\t\tthis.updateFunction = updateFunction;\n\t\tthis.world = world;\n\t\tthis.createsEntities = createsEntities;\n\t\tthis.addsComponents = addsComponents;\n\t\tconst registry = world.registry as RegisteredComponentRegistry<C>;\n\t\tthis.allocator = {\n\t\t\tallocateEid: () => world.allocateEid(),\n\t\t\tallocateComponentBlock: (name, values) => registry[name as keyof C].memoryComponent.create(values),\n\t\t};\n\t}\n\n\tprivate getString = (pointer: number): string => this.world.constantStrings.getString(pointer) ?? '';\n\n\tpostMessage(message: EntitySystemWorkerMessage<W, D>): void {\n\t\tif(message.type === 'init') {\n\t\t\tthis.onMessageTyped({\n\t\t\t\ttype: 'init-complete',\n\t\t\t});\n\t\t} else if(message.type === 'load') {\n\t\t\tthis.entities.apply(message.entities as QueryDelta<T>);\n\t\t\tconst queries = this.applyQueryDeltas(message.queries);\n\t\t\tconst world = { gameTime: message.gameTime, getString: this.getString, heap: this.world.heap };\n\t\t\tthis.worldExtension = this.updateFunction.init?.(world, message.data, this.entities.entries, queries) ?? undefined;\n\t\t\tthis.onMessageTyped({\n\t\t\t\ttype: 'loaded',\n\t\t\t});\n\t\t} else if(message.type === 'reset') {\n\t\t\tthis.workState.clear();\n\t\t\t// Drop the persistent lists so a reused world starts empty; worldExtension is refreshed by the next load.\n\t\t\tthis.entities.clear();\n\t\t\tthis.queryEntities = {};\n\t\t} else if(message.type === 'run') {\n\t\t\tmessage.world = this.workState.getWorld(message.world, message.workBatch);\n\t\t\tif(this.worldExtension) {\n\t\t\t\tObject.assign(message.world, this.worldExtension);\n\t\t\t}\n\t\t\tmessage.world.getString = this.getString;\n\t\t\tmessage.world.heap = this.world.heap;\n\t\t\tmessage.world.allocate = this.allocator;\n\t\t\tif(this.createsEntities) {\n\t\t\t\tconst registry: WorkerCreateRegistry = this.world.registry;\n\t\t\t\tmessage.world.buildEntityDescriptor = config => buildWorkerEntity(\n\t\t\t\t\tconfig,\n\t\t\t\t\tthis.world.factory.configs,\n\t\t\t\t\tregistry,\n\t\t\t\t\tthis.allocator,\n\t\t\t\t\tthis.world.factory.getWorkerClasses(),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif(this.addsComponents) {\n\t\t\t\tconst registry: WorkerCreateRegistry = this.world.registry;\n\t\t\t\tmessage.world.buildComponentDescriptor = (name, config) => buildWorkerComponent(name, config, registry, this.allocator);\n\t\t\t}\n\t\t\t// Timed like the real worker so a forceMainThread system reports a real run cost, not zero.\n\t\t\tconst start = performance.now();\n\t\t\tlet entityEvents: Array<EntityEvent> = [];\n\t\t\tlet systemEvents: SystemEvents = {};\n\t\t\tlet createdEntities: Array<WorkerCreatedEntity> = [];\n\t\t\tlet componentChanges: Array<WorkerComponentChange> = [];\n\t\t\tlet errors: Array<WorkerRunError> = [];\n\n\t\t\tthis.entities.apply(message.entities as QueryDelta<T>);\n\t\t\tconst runEntities = this.workState.getEntities(this.entities.entries, message.entities as QueryDelta<T>, message.workBatch);\n\t\t\tconst queries = this.applyQueryDeltas(message.queries);\n\n\t\t\tlet callbacks: EntityWorkerSystemCallbacks<C> = {\n\t\t\t\tentityComponentChanged<K extends keyof C, P extends keyof C[K]>(entityId: number, componentName: K, prop: P, value: C[K][P]) {\n\t\t\t\t\tentityEvents.push({\n\t\t\t\t\t\tentityId,\n\t\t\t\t\t\tevent: 'component-property-updated',\n\t\t\t\t\t\targs: [componentName, prop, value],\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\temitEntityEvent(entityId: number, event: string, ...args: Array<unknown>) {\n\t\t\t\t\tentityEvents.push({\n\t\t\t\t\t\tentityId,\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\targs,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\temitSystemEvent(event: string, entityId: number) {\n\t\t\t\t\t(systemEvents[event] ?? (systemEvents[event] = [])).push(entityId);\n\t\t\t\t},\n\t\t\t\tentityDied(entityId: number) {\n\t\t\t\t\tentityEvents.push({\n\t\t\t\t\t\tentityId,\n\t\t\t\t\t\tevent: 'death',\n\t\t\t\t\t\targs: [],\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tcreateEntity(entity: WorkerCreatedEntity) {\n\t\t\t\t\tcreatedEntities.push(entity);\n\t\t\t\t},\n\t\t\t\taddComponent(entityId, component) {\n\t\t\t\t\tcomponentChanges.push({ type: 'add', entityId, component });\n\t\t\t\t},\n\t\t\t\tremoveComponent(entityId, componentName) {\n\t\t\t\t\tcomponentChanges.push({ type: 'remove', entityId, componentName: String(componentName) });\n\t\t\t\t},\n\t\t\t};\n\t\t\tif(this.updateFunction.queryChanged) {\n\t\t\t\tfor(const [queryName, delta] of Object.entries(message.queries)) {\n\t\t\t\t\tif(!delta.added.length && !delta.removed.length) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.updateFunction.queryChanged(message.world, queryName, delta, callbacks);\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\terrors.push({ error: e as Error, phase: 'queryChanged' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet preRunFailed = false;\n\t\t\tif(this.updateFunction.preRun && (!message.workBatch || message.workBatch.first)) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.updateFunction.preRun(message.world, this.entities.entries, queries, callbacks);\n\t\t\t\t} catch(e) {\n\t\t\t\t\tpreRunFailed = true;\n\t\t\t\t\terrors.push({ error: e as Error, phase: 'preRun' });\n\t\t\t\t}\n\t\t\t}\n\t\t\t// preRun sets up the run's state; if it threw, skip the entity loop rather than run over half-prepared data.\n\t\t\tif(!preRunFailed && this.updateFunction.preBatch) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.updateFunction.preBatch(message.world, runEntities, queries, callbacks);\n\t\t\t\t} catch(e) {\n\t\t\t\t\tpreRunFailed = true;\n\t\t\t\t\terrors.push({ error: e as Error, phase: 'preBatch' });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!preRunFailed) {\n\t\t\t\trunEntities.forEach(entity => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.updateFunction(message.world, entity.entityId, entity.components, queries, callbacks);\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t// One entity failing must not stop the rest of the run.\n\t\t\t\t\t\terrors.push({ error: e as Error, phase: 'update', entityId: entity.entityId });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif(this.updateFunction.entityRemoved) {\n\t\t\t\tfor(let entityId of message.entities.removed) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.updateFunction.entityRemoved(message.world, entityId, callbacks);\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\terrors.push({ error: e as Error, phase: 'entityRemoved', entityId });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst runTime = performance.now() - start;\n\t\t\tthis.workState.finish(message.workBatch, preRunFailed);\n\n\t\t\tthis.onMessageTyped({\n\t\t\t\ttype: 'run-complete',\n\t\t\t\tgeneration: message.generation,\n\t\t\t\trunTime,\n\t\t\t\tevents: entityEvents,\n\t\t\t\tsystemEvents,\n\t\t\t\tcreated: createdEntities,\n\t\t\t\tcomponentChanges,\n\t\t\t\terrors,\n\t\t\t\tworkFailed: preRunFailed,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate applyQueryDeltas(deltas: { [key: string]: QueryDelta }): EntityQueryComponents<C> {\n\t\tconst queries: EntityQueryComponents<C> = {};\n\t\tfor(const [queryKey, delta] of Object.entries(deltas)) {\n\t\t\tconst membership = this.queryEntities[queryKey] ??= new QueryMembership<T>();\n\t\t\tmembership.apply(delta as QueryDelta<T>);\n\t\t\tqueries[queryKey] = membership.entries;\n\t\t}\n\t\treturn queries;\n\t}\n\n\tonMessageTyped(message: EntitySystemWorkerMessage<W, D>) {\n\t\tthis.onmessage({\n\t\t\tdata: message,\n\t\t});\n\t}\n}\n","import type MemoryHeap from '@daneren2005/shared-memory-objects/memory-heap';\nimport type { GrowBufferData } from '@daneren2005/shared-memory-objects/memory-heap';\nimport type BaseWorld from '../world';\nimport type BaseEntity from '../entity';\nimport type { BaseComponent, ComponentDefinitionMap, ComponentMap } from '../component-definition';\nimport type { ComponentTypedArray } from '../memory-component';\nimport System, { forEachInMatchingGroups, type EntityBatch, type SystemConfig } from './system';\nimport type EntitySystemWorkerMessage from './workers/entity-system-worker-message';\nimport type { EntityWorkBatch } from './workers/entity-system-worker-message';\nimport EntitySystemWebWorker from './workers/entity-system-web-worker';\nimport type { SchedulerEffects } from '../scheduling/scheduler';\n\nconst MAIN_QUERY_NAME = '___main';\n\n// Runs an update function over the raw shared-memory blocks of its matched entities. Uses getWorker() when\n// Web Workers + SharedArrayBuffer exist, else falls back to EntitySystemWebWorker on the main thread. No game\n// concepts; games inject per-run data via addDataToWorld.\nexport default abstract class EntityWorkerSystem<\n\tC extends ComponentMap,\n\tT extends EntityUpdateComponents<C>,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> extends System<C> {\n\tentities: Map<number, BaseEntity<C>> = new Map();\n\toptions: EntityWorkerSystemConfig<C, T, W, D>;\n\n\tworker: Worker | EntitySystemWebWorker<C, T, W, D>;\n\tisWorkerThread: boolean;\n\n\tprivate initialized = false;\n\tprivate initPromise: PromiseWithResolvers<void> | null = null;\n\tprivate initError: Error | null = null;\n\tprivate loadingPromise: Resolvable | null = null;\n\tprivate runCompletePromise: Resolvable | null = null;\n\tprivate isRunning = false;\n\tprivate workPass: { entities: Array<BaseEntity<C>>, cursor: number, elapsedTime: number, gameTime: number } | undefined;\n\tprivate timingBatch: Pick<EntityWorkBatch, 'first' | 'last'> | undefined;\n\tprivate pendingEffects: SchedulerEffects | undefined;\n\tprivate completeEffects: ((effects: SchedulerEffects) => void) | undefined;\n\t// Bumped by clear(); checked on each event to make certain we are dealing with the correct world\n\tprivate generation = 0;\n\tprotected queryEntities: { [key: string]: Map<number, BaseEntity<C>> } = {};\n\t// Membership changes since the last run(), flushed each run as a delta so a steady-state run sends empty\n\t// arrays rather than re-transmitting every eid. The worker applies these to its own list (see applyQueryDelta).\n\tprivate queryDeltas: { [key: string]: MembershipDelta<C> } = {};\n\n\taddDataToWorld?(world: W): void;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: EntityWorkerSystemConfig<C, T, W, D>) {\n\t\tsuper(world, options);\n\t\tif(options.workBatchSize !== undefined && (!Number.isSafeInteger(options.workBatchSize) || options.workBatchSize <= 0)) {\n\t\t\tthrow new Error('workBatchSize must be a positive safe integer');\n\t\t}\n\t\tthis.options = options;\n\t\tObject.keys(this.options.queries ?? {}).forEach(queryName => {\n\t\t\tthis.queryEntities[queryName] = new Map();\n\t\t});\n\n\t\tworld.on('entity-added', (entity: BaseEntity<C>) => {\n\t\t\tif(!world.isBulkLoading) {\n\t\t\t\tthis.checkAddEntity(entity);\n\t\t\t}\n\t\t});\n\t\tworld.on('entity-removed', (entity: BaseEntity<C>) => {\n\t\t\tthis.removeEntity(entity);\n\t\t});\n\n\t\tworld.entities.forEach(entity => {\n\t\t\tthis.checkAddEntity(entity);\n\t\t});\n\n\t\tif(!options.forceMainThread && typeof globalThis.Worker !== 'undefined' && typeof globalThis.SharedArrayBuffer !== 'undefined') {\n\t\t\tthis.worker = options.getWorker();\n\t\t\tthis.isWorkerThread = true;\n\t\t\t// Forward heap growth so the worker's reconstructed heap can resolve pointers into new buffers.\n\t\t\tworld.on('grow-buffer', (buffer: GrowBufferData) => {\n\t\t\t\tthis.worker.postMessage({ type: 'grow-buffer', buffer });\n\t\t\t});\n\t\t} else {\n\t\t\tthis.worker = new EntitySystemWebWorker(options.updateFunction, world, !!options.createsEntities, !!options.addsComponents);\n\t\t\tthis.isWorkerThread = false;\n\t\t}\n\n\t\tthis.initWorker();\n\t}\n\n\tprivate initWorker() {\n\t\tconst onWorkerError = (error: Error) => {\n\t\t\tconsole.error(error, error.cause);\n\t\t\tif(!this.initialized) {\n\t\t\t\tthis.initError = error;\n\t\t\t\tthis.initPromise?.reject(error);\n\t\t\t}\n\t\t};\n\t\tif(!(this.worker instanceof EntitySystemWebWorker)) {\n\t\t\tconst onErrorEvent = (event: ErrorEvent | MessageEvent) => {\n\t\t\t\tonWorkerError(new Error(`Worker ${this.name} failed to load`, { cause: event }));\n\t\t\t};\n\t\t\tthis.worker.onerror = onErrorEvent;\n\t\t\tthis.worker.onmessageerror = onErrorEvent;\n\t\t}\n\n\t\tthis.worker.onmessage = (e: MessageEvent) => {\n\t\t\tlet message = e.data as EntitySystemWorkerMessage;\n\t\t\tif(message.type === 'unhandled-rejection') {\n\t\t\t\tonWorkerError(new Error(`Worker ${this.name} had an unhandled promise rejection`, { cause: message.error }));\n\t\t\t} else if(message.type === 'init-complete') {\n\t\t\t\tthis.initialized = true;\n\t\t\t\tif(this.initPromise) {\n\t\t\t\t\tthis.initPromise.resolve();\n\t\t\t\t\tthis.initPromise = null;\n\t\t\t\t}\n\t\t\t} else if(message.type === 'loaded') {\n\t\t\t\tif(this.loadingPromise) {\n\t\t\t\t\tthis.loadingPromise.resolve();\n\t\t\t\t\tthis.loadingPromise = null;\n\t\t\t\t}\n\t\t\t} else if(message.type === 'grow-buffer-from-worker') {\n\t\t\t\t// A buffer this worker grew while allocating: adopt into the main heap and fan out to sibling workers.\n\t\t\t\tthis.world.addGrownBuffer(message.buffer);\n\t\t\t} else if(message.type === 'run-complete') {\n\t\t\t\t// A reply from a run that started before a clear(): the world it ran over is gone, so drop it whole.\n\t\t\t\tif(message.generation !== this.generation) {\n\t\t\t\t\tif(this.world.scheduler.prepareEffects) {\n\t\t\t\t\t\tthis.discardWorkerAllocations(message);\n\t\t\t\t\t}\n\t\t\t\t\tthis.world.notifyAbandonedRunFinished(this);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst timingBatch = this.timingBatch && { ...this.timingBatch, last: this.timingBatch.last || !!message.workFailed };\n\t\t\t\tif(message.workFailed) {\n\t\t\t\t\tthis.workPass = undefined;\n\t\t\t\t}\n\n\t\t\t\tif(!this.completeEffects) {\n\t\t\t\t\tthis.applyWorkerEffects(message, true, timingBatch);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.world.emit(`system-${this.name}-worker-finished`, message.runTime, timingBatch);\n\t\t\t\tconst generation = this.generation;\n\t\t\t\tlet settled = false;\n\t\t\t\tconst finish = () => {\n\t\t\t\t\tthis.pendingEffects = undefined;\n\t\t\t\t\tthis.isRunning = false;\n\t\t\t\t\tthis.runCompletePromise?.resolve();\n\t\t\t\t\tthis.runCompletePromise = null;\n\t\t\t\t};\n\t\t\t\tconst effects: SchedulerEffects = {\n\t\t\t\t\tapply: () => {\n\t\t\t\t\t\tif(settled) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(generation !== this.generation) {\n\t\t\t\t\t\t\teffects.discard();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tthis.pendingEffects = undefined;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tthis.applyWorkerEffects(message, false, timingBatch);\n\t\t\t\t\t\t} catch(error) {\n\t\t\t\t\t\t\tthis.onError(error as Error, { phase: 'run' });\n\t\t\t\t\t\t\tthis.world.notifySystemRunCompleted(this);\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tfinish();\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tdiscard: () => {\n\t\t\t\t\t\tif(settled) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tthis.discardWorkerAllocations(message);\n\t\t\t\t\t\tfinish();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tthis.pendingEffects = effects;\n\t\t\t\tthis.completeEffects(effects);\n\t\t\t}\n\t\t};\n\n\t\tconst message: EntitySystemWorkerMessage<W, D> = {\n\t\t\ttype: 'init',\n\t\t};\n\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tprivate applyWorkerEffects(message: WorkerRunCompletion, emitWorkerFinished: boolean, timingBatch: Pick<EntityWorkBatch, 'first' | 'last'> | undefined): void {\n\t\tthis.isRunning = false;\n\t\tif(emitWorkerFinished) {\n\t\t\tthis.world.emit(`system-${this.name}-worker-finished`, message.runTime, timingBatch);\n\t\t}\n\n\t\t// User-code errors caught inside the run: log + emit on the main thread, one per failure.\n\t\tmessage.errors.forEach(({ error, entityId, phase }) => {\n\t\t\tthis.onError(error, { entityId, phase });\n\t\t});\n\n\t\t// Structural changes are applied only after the worker has finished iterating its snapshot. Attaching emits\n\t\t// the same entity events as a main-thread mutation, which rechecks every affected system/query and queues\n\t\t// refreshed component bundles for their next run.\n\t\t(message.componentChanges ?? []).forEach(change => {\n\t\t\tconst entity = this.world.getEntityByEid(change.entityId);\n\t\t\tif(change.type === 'add') {\n\t\t\t\tconst definition = this.world.registry[change.component.name as keyof C];\n\t\t\t\tif(!entity || !definition || change.component.name === 'entity') {\n\t\t\t\t\tdefinition?.memoryComponent.delete(change.component.index);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst componentName = change.component.name as keyof C;\n\t\t\t\tentity.removeComponent(componentName);\n\t\t\t\tentity.attachComponent(componentName, change.component.index, true);\n\t\t\t} else if(entity && change.componentName !== 'entity') {\n\t\t\t\tentity.removeComponent(change.componentName);\n\t\t\t}\n\t\t});\n\n\t\t// Before the per-entity events: an entity killed this run is still in the world here, since `death`\n\t\t// is dispatched below and removes it.\n\t\tfor(const event of Object.keys(message.systemEvents)) {\n\t\t\tthis.emit(event, message.systemEvents[event]);\n\t\t}\n\n\t\tmessage.events.forEach(event => {\n\t\t\t// Look up on the world, not the query cache, so events for sub-query-only entities still route.\n\t\t\tconst entity = this.world.getEntityByEid(event.entityId);\n\t\t\tif(!entity) {\n\t\t\t\tconsole.warn(`${this.name}-event ${event.event}: Could not find entity with id ${event.entityId}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tentity.emit(event.event, ...event.args);\n\t\t});\n\n\t\t// After deaths, so an entity created this run isn't immediately removed. Adopts the blocks the worker\n\t\t// already allocated + wrote, rather than re-creating them.\n\t\tmessage.created.forEach(descriptor => {\n\t\t\tthis.world.adoptEntity(descriptor);\n\t\t});\n\n\t\tthis.world.emit(`system-${this.name}-worker-events-finished`, message.runTime, timingBatch);\n\t\tthis.world.notifySystemRunCompleted(this);\n\n\t\tif(this.runCompletePromise) {\n\t\t\tthis.runCompletePromise.resolve();\n\t\t\tthis.runCompletePromise = null;\n\t\t}\n\t}\n\n\tprivate discardWorkerAllocations(message: WorkerRunCompletion): void {\n\t\tfor(const entity of message.created) {\n\t\t\tfor(const [name, index] of Object.entries(entity.components)) {\n\t\t\t\tthis.world.registry[name as keyof C]?.memoryComponent.delete(index);\n\t\t\t}\n\t\t}\n\t\tfor(const change of message.componentChanges ?? []) {\n\t\t\tif(change.type === 'add') {\n\t\t\t\tthis.world.registry[change.component.name as keyof C]?.memoryComponent.delete(change.component.index);\n\t\t\t}\n\t\t}\n\t}\n\n\tinit(): Promise<void> | void {\n\t\tif(this.initError) {\n\t\t\treturn Promise.reject(this.initError);\n\t\t}\n\t\tif(this.initialized) {\n\t\t\treturn;\n\t\t} else if(this.initPromise) {\n\t\t\treturn this.initPromise.promise;\n\t\t}\n\n\t\tthis.initPromise = Promise.withResolvers<void>();\n\t\treturn this.initPromise.promise;\n\t}\n\n\t// Sends the init data plus pending membership over, so the worker caches every loaded entity before reporting loaded\n\tfinishLoading(): Promise<void> {\n\t\tlet { promise, resolve } = Promise.withResolvers<void>();\n\t\t// Assigned before posting: the main-thread fallback replies synchronously from inside postMessage.\n\t\tthis.loadingPromise = {\n\t\t\tpromise,\n\t\t\tresolve,\n\t\t};\n\n\t\tconst queries: { [key: string]: QueryDelta<T> } = {};\n\t\tObject.entries(this.options.queries ?? {}).forEach(([queryKey, query]) => {\n\t\t\tqueries[queryKey] = this.buildQueryDelta(queryKey, query);\n\t\t});\n\t\tconst message: EntitySystemWorkerMessage<W, D> = {\n\t\t\ttype: 'load',\n\t\t\tdata: this.options.getInitData?.(),\n\t\t\tgameTime: this.gameTime,\n\t\t\tentities: this.buildQueryDelta(MAIN_QUERY_NAME, this.options),\n\t\t\tqueries,\n\t\t\t// Only a real worker needs the buffers to rebuild a heap, plus the pools + eid counter to allocate off-thread.\n\t\t\theap: this.isWorkerThread ? this.world.heap.getSharedMemory() : undefined,\n\t\t\tsharedMemory: this.isWorkerThread ? this.world.getSharedComponentMemory() : undefined,\n\t\t\t// Factory templates only go to workers that create entities.\n\t\t\tfactoryConfigs: this.isWorkerThread && this.options.createsEntities ? this.world.factory.configs : undefined,\n\t\t\tfactoryClasses: this.isWorkerThread && this.options.createsEntities ? this.world.factory.getWorkerClasses() : undefined,\n\t\t\taddsComponents: !!this.options.addsComponents,\n\t\t};\n\t\tthis.worker.postMessage(message);\n\n\t\treturn promise;\n\t}\n\n\t// Un-initializes the system so its world can be reused\n\tclear() {\n\t\tsuper.clear();\n\t\tthis.pendingEffects?.discard();\n\n\t\tif(this.isRunning) {\n\t\t\tif(!this.runCompletePromise) {\n\t\t\t\tconst { promise, resolve } = Promise.withResolvers<void>();\n\t\t\t\tthis.runCompletePromise = { promise, resolve };\n\t\t\t}\n\t\t}\n\t\tthis.isRunning = false;\n\t\tthis.generation++;\n\n\t\tthis.entities.clear();\n\t\tObject.values(this.queryEntities).forEach(list => list.clear());\n\t\tthis.queryDeltas = {};\n\t\tthis.workPass = undefined;\n\t\tthis.timingBatch = undefined;\n\n\t\tconst message: EntitySystemWorkerMessage = { type: 'reset' };\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tupdate(elapsedTime: number): boolean {\n\t\tif(this.isRunning) {\n\t\t\tthis.currentDelta += elapsedTime;\n\n\t\t\treturn false;\n\t\t} else if(this.workPass) {\n\t\t\tthis.currentDelta += elapsedTime;\n\t\t\tthis.run(this.workPass.elapsedTime);\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn super.update(elapsedTime);\n\t\t}\n\t}\n\t// A run finishes off-thread, not when update() returns; completedRuns is bumped on the worker's run-complete.\n\tprotected onRunFinished() {}\n\tisCurrentlyRunning(): boolean {\n\t\treturn this.isRunning;\n\t}\n\tget readComponents(): ReadonlyArray<PropertyKey> {\n\t\tconst queries = [this.options, ...Object.values(this.options.queries ?? {})];\n\t\treturn ['entity', ...this.reads ?? [], ...queries.flatMap(query => [...query.required, ...query.optional ?? []])];\n\t}\n\tget requiresExclusiveScheduling(): boolean {\n\t\treturn super.requiresExclusiveScheduling || this.options.createsEntities === true || !!this.options.addsComponents;\n\t}\n\tget createdComponents(): ReadonlyArray<PropertyKey> {\n\t\tconst components = this.options.createsEntities;\n\t\treturn components && typeof components !== 'boolean' ? ['entity', ...components] : [];\n\t}\n\tget creationReadComponents(): ReadonlyArray<PropertyKey> {\n\t\tconst queries = Object.values(this.options.queries ?? {});\n\t\tif(this.tracksMainQuery) {\n\t\t\tqueries.push(this.options);\n\t\t}\n\t\treturn [...this.reads ?? [], ...queries.flatMap(query => {\n\t\t\tconst required = query.required.filter(component => component !== 'entity');\n\t\t\tconst optional = query.optional?.filter(component => component !== 'entity') ?? [];\n\t\t\t// With another required component, reading dead flags does not make this an all-entity query.\n\t\t\treturn [...required.length ? required : ['entity'], ...optional, ...query.not ?? []];\n\t\t})];\n\t}\n\tget creationReadQueries(): ReadonlyArray<ReadonlyArray<PropertyKey>> | undefined {\n\t\tif(this.checkAddEntity !== EntityWorkerSystem.prototype.checkAddEntity || this.matchesQuery !== EntityWorkerSystem.prototype.matchesQuery) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst queries = Object.values(this.options.queries ?? {});\n\t\tif(this.tracksMainQuery) {\n\t\t\tqueries.push(this.options);\n\t\t}\n\t\treturn queries.map(query => query.required);\n\t}\n\twaitForRunToComplete(): void | Promise<void> {\n\t\tif(!this.isRunning) {\n\t\t\treturn;\n\t\t}\n\t\tif(!this.runCompletePromise) {\n\t\t\tconst { promise, resolve } = Promise.withResolvers<void>();\n\t\t\tthis.runCompletePromise = { promise, resolve };\n\t\t}\n\t\treturn this.runCompletePromise.promise;\n\t}\n\trun(elapsedTime: number): void {\n\t\tlet workBatch: Extract<EntitySystemWorkerMessage, { type: 'run' }>['workBatch'];\n\t\tlet gameTime = this.gameTime;\n\t\tif(this.options.workBatchSize !== undefined && this.tracksMainQuery) {\n\t\t\tconst first = !this.workPass;\n\t\t\tconst pass = this.workPass ??= { entities: Array.from(this.entities.values()), cursor: 0, elapsedTime, gameTime };\n\t\t\tgameTime = pass.gameTime;\n\t\t\telapsedTime = pass.elapsedTime;\n\t\t\tconst end = Math.min(pass.cursor + this.options.workBatchSize, pass.entities.length);\n\t\t\tconst entityIds: Array<number> = [];\n\t\t\tfor(; pass.cursor < end; pass.cursor++) {\n\t\t\t\tconst entity = pass.entities[pass.cursor];\n\t\t\t\tif(this.entities.get(entity.eid) === entity) {\n\t\t\t\t\tentityIds.push(entity.eid);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst last = pass.cursor === pass.entities.length;\n\t\t\tworkBatch = { entityIds, first, last };\n\t\t\tif(last) {\n\t\t\t\tthis.workPass = undefined;\n\t\t\t}\n\t\t}\n\t\tconst world = {\n\t\t\tgameTime,\n\t\t\telapsedTime,\n\t\t} as W;\n\t\tif(!workBatch || workBatch.first) {\n\t\t\tthis.addDataToWorld?.(world);\n\t\t}\n\n\t\tthis.timingBatch = workBatch && { first: workBatch.first, last: workBatch.last };\n\t\tthis.isRunning = true;\n\t\tthis.completeEffects = this.world.scheduler.prepareEffects?.(this.world, this);\n\t\tlet entities = this.buildQueryDelta(MAIN_QUERY_NAME, this.options);\n\t\tlet queries: { [key: string]: QueryDelta<T> } = {};\n\t\tObject.entries(this.options.queries ?? {}).forEach(([queryKey, query]) => {\n\t\t\tqueries[queryKey] = this.buildQueryDelta(queryKey, query);\n\t\t});\n\t\tlet message: EntitySystemWorkerMessage<W> = {\n\t\t\ttype: 'run',\n\t\t\tgeneration: this.generation,\n\t\t\tworld,\n\t\t\tentities,\n\t\t\tqueries,\n\t\t\tworkBatch,\n\t\t};\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tprivate buildQueryDelta(queryName: string, query: EntityWorkerSystemQuery<C>): QueryDelta<T> {\n\t\tconst delta = this.getQueryDelta(queryName);\n\t\tconst added: Array<UpdateEntityConfigObject<T>> = [];\n\t\tdelta.added.forEach(entity => {\n\t\t\tadded.push({\n\t\t\t\tentityId: entity.eid,\n\t\t\t\tcomponents: this.buildComponents(entity, query),\n\t\t\t});\n\t\t});\n\t\tconst removed = Array.from(delta.removed);\n\t\tthis.queryDeltas[queryName] = { added: new Set(), removed: new Set() };\n\n\t\treturn { added, removed };\n\t}\n\tprivate buildComponents(entity: BaseEntity<C>, query: EntityWorkerSystemQuery<C>): T {\n\t\tconst components = {} as T;\n\t\t[\n\t\t\t...query.required,\n\t\t\t...query.optional ?? [],\n\t\t].forEach(componentName => {\n\t\t\t// Reuse the view cached on the accessor at attach: getBlock allocates a fresh subarray every call and an\n\t\t\t// entity joins many systems, so re-looking it up here per system was a measurable spawn-time cost.\n\t\t\tconst block = entity.components[componentName]?.block;\n\t\t\tif(block) {\n\t\t\t\tcomponents[componentName] = block as T[typeof componentName];\n\t\t\t}\n\t\t});\n\n\t\treturn components;\n\t}\n\n\tisEntityInSystem(entity: BaseEntity<C>) {\n\t\treturn this.entities.has(entity.eid);\n\t}\n\tprotected matchesQuery(entity: BaseEntity<C>, query: EntityWorkerSystemQuery<C>): boolean {\n\t\tif(entity.components.entity.dead) {\n\t\t\treturn false;\n\t\t}\n\t\tif(!this.matchesComponents(entity, query)) {\n\t\t\treturn false;\n\t\t}\n\t\tif(query.filter && !query.filter(entity)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\tprivate matchesComponents(entity: BaseEntity<C>, query: EntityWorkerSystemQuery<C>): boolean {\n\t\tif(query.required.find(component => !entity.components[component])) {\n\t\t\treturn false;\n\t\t}\n\t\tif(query.not?.find(component => !!entity.components[component])) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\tprivate getQueryDelta(queryName: string): MembershipDelta<C> {\n\t\tlet delta = this.queryDeltas[queryName];\n\t\tif(!delta) {\n\t\t\tdelta = this.queryDeltas[queryName] = { added: new Set(), removed: new Set() };\n\t\t}\n\n\t\treturn delta;\n\t}\n\t// A pending removal this same frame is cancelled, so the net effect is a re-send rather than remove+add churn.\n\tprivate markAdded(delta: MembershipDelta<C>, entity: BaseEntity<C>) {\n\t\tdelta.removed.delete(entity.eid);\n\t\tdelta.added.add(entity);\n\t}\n\tprivate markRemoved(delta: MembershipDelta<C>, entity: BaseEntity<C>) {\n\t\tif(delta.added.delete(entity)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdelta.removed.add(entity.eid);\n\t}\n\tprotected updateEntityList(queryName: string, list: Map<number, BaseEntity<C>>, entity: BaseEntity<C>, shouldInclude: boolean) {\n\t\tconst delta = this.getQueryDelta(queryName);\n\t\tif(shouldInclude) {\n\t\t\tlist.set(entity.eid, entity);\n\t\t\tthis.markAdded(delta, entity);\n\t\t} else if(list.delete(entity.eid)) {\n\t\t\tthis.markRemoved(delta, entity);\n\t\t}\n\t}\n\n\t// WorkerSystem has no main query: its empty `required` would otherwise match every entity.\n\tprotected get tracksMainQuery(): boolean {\n\t\treturn true;\n\t}\n\n\tcheckAddEntity(entity: BaseEntity<C>): boolean {\n\t\tconst shouldAddToMain = this.tracksMainQuery && this.matchesQuery(entity, this.options);\n\t\tthis.updateEntityList(MAIN_QUERY_NAME, this.entities, entity, shouldAddToMain);\n\n\t\tObject.entries(this.options.queries ?? {}).forEach(([queryName, query]) => {\n\t\t\tconst queryList = this.queryEntities[queryName] ?? (this.queryEntities[queryName] = new Map());\n\t\t\tthis.updateEntityList(queryName, queryList, entity, this.matchesQuery(entity, query));\n\t\t});\n\n\t\treturn shouldAddToMain;\n\t}\n\taddEntities(batch: EntityBatch<C>): void {\n\t\t// A subclass with its own membership rule gets it applied per entity, exactly as entity-added would.\n\t\tif(this.checkAddEntity !== EntityWorkerSystem.prototype.checkAddEntity || this.matchesQuery !== EntityWorkerSystem.prototype.matchesQuery) {\n\t\t\tbatch.entities.forEach(entity => this.checkAddEntity(entity));\n\t\t\treturn;\n\t\t}\n\n\t\tif(this.tracksMainQuery) {\n\t\t\tthis.addBatchToQuery(MAIN_QUERY_NAME, this.entities, this.options, batch);\n\t\t}\n\t\tObject.entries(this.options.queries ?? {}).forEach(([queryName, query]) => {\n\t\t\tconst queryList = this.queryEntities[queryName] ?? (this.queryEntities[queryName] = new Map());\n\t\t\tthis.addBatchToQuery(queryName, queryList, query, batch);\n\t\t});\n\t}\n\tprivate addBatchToQuery(queryName: string, list: Map<number, BaseEntity<C>>, query: EntityWorkerSystemQuery<C>, batch: EntityBatch<C>) {\n\t\tconst delta = this.getQueryDelta(queryName);\n\t\tforEachInMatchingGroups(batch, entity => this.matchesComponents(entity, query), entity => {\n\t\t\tif(entity.components.entity.dead || (query.filter && !query.filter(entity))) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlist.set(entity.eid, entity);\n\t\t\tthis.markAdded(delta, entity);\n\t\t});\n\t}\n\n\tremoveEntity(entity: BaseEntity<C>) {\n\t\tthis.updateEntityList(MAIN_QUERY_NAME, this.entities, entity, false);\n\t\tObject.entries(this.queryEntities).forEach(([queryName, list]) => {\n\t\t\tthis.updateEntityList(queryName, list, entity, false);\n\t\t});\n\t}\n\n\t// Re-evaluates every entity's membership against the current queries. Needed when a `filter` closes over mutable\n\t// state (e.g. a scope keyed on which group is active) and that state changes with no entity event to react to\n\trecheckMembership() {\n\t\tthis.world.entities.forEach(entity => {\n\t\t\tthis.checkAddEntity(entity);\n\t\t});\n\t}\n\n\tshouldRun(): boolean {\n\t\treturn this.workPass !== undefined || this.entities.size > 0;\n\t}\n\n\tdestroy() {\n\t\tsuper.destroy();\n\t\tthis.pendingEffects?.discard();\n\n\t\tif('terminate' in this.worker) {\n\t\t\tthis.worker.terminate();\n\t\t}\n\t}\n}\n\ninterface Resolvable {\n\tpromise: Promise<void>\n\tresolve: (value: void | PromiseLike<void>) => void\n}\n\nexport type EntityUpdateComponents<C extends ComponentMap = ComponentMap> = { [K in keyof C]?: ComponentTypedArray };\nexport type EntityQueryComponents<C extends ComponentMap = ComponentMap> = { [key: string]: Array<{ entityId: number, components: EntityUpdateComponents<C> }> };\ntype EntityUpdateFunctionImpl<C extends ComponentMap, T extends EntityUpdateComponents<C>, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld> = (\n\tworld: W,\n\tentityId: number,\n\tcomponents: T,\n\tqueries: EntityQueryComponents<C>,\n\tcallbacks: EntityWorkerSystemCallbacks<C>,\n) => void;\nexport type EntityUpdateFunction<\n\tC extends ComponentMap,\n\tT extends EntityUpdateComponents<C>,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> = EntityUpdateFunctionImpl<C, T, W> & {\n\tqueryChanged?: EntityQueryChangedFunction<C, W>\n\tpreRun?: EntityUpdatePreRunFunction<C, T, W>\n\tpreBatch?: EntityUpdatePreRunFunction<C, T, W>\n\tentityRemoved?: EntityRemovedFunction<C, W>\n\tinit?: EntityUpdateInitFunction<W, D, C, T>\n};\n// Runs after the load's membership is applied, so `entities`/`queries` already hold every loaded entity.\nexport type EntityUpdateInitFunction<\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n\tC extends ComponentMap = ComponentMap,\n\tT extends EntityUpdateComponents<C> = EntityUpdateComponents<C>,\n> = (\n\tworld: EntityWorkerSystemInitWorld,\n\tdata: D | undefined,\n\tentities: Array<UpdateEntityConfigObject<T>>,\n\tqueries: EntityQueryComponents<C>,\n) => Partial<W> | void;\nexport type EntityUpdatePreRunFunction<C extends ComponentMap, T extends EntityUpdateComponents<C>, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld> = (\n\tworld: W,\n\tentities: Array<UpdateEntityConfigObject<T>>,\n\tqueries: EntityQueryComponents<C>,\n\tcallbacks: EntityWorkerSystemCallbacks<C>,\n) => void;\n// Called once per sub-query whose membership changed this run, before preRun. `added` can repeat an entity already\n// in the query (its component bundle was refreshed), so treat it as an upsert.\nexport type EntityQueryChangedFunction<C extends ComponentMap = ComponentMap, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld> = (\n\tworld: W,\n\tqueryName: string,\n\tdelta: QueryDelta<EntityUpdateComponents<C>>,\n\tcallbacks: EntityWorkerSystemCallbacks<C>,\n) => void;\nexport type EntityRemovedFunction<C extends ComponentMap = ComponentMap, W extends EntityWorkerSystemWorld = EntityWorkerSystemWorld> = (\n\tworld: W,\n\tentityId: number,\n\tcallbacks: EntityWorkerSystemCallbacks<C>,\n) => void;\nexport type UpdateEntityConfig<T extends EntityUpdateComponents = EntityUpdateComponents> = number | UpdateEntityConfigObject<T>;\nexport type UpdateEntityConfigObject<T extends EntityUpdateComponents> = {\n\tentityId: number\n\tcomponents: T\n};\n\nexport interface QueryDelta<T extends EntityUpdateComponents = EntityUpdateComponents> {\n\tadded: Array<UpdateEntityConfigObject<T>>\n\tremoved: Array<number>\n}\n// Sets so queuing can check for an already-queued or opposite change without scanning a growing array.\ninterface MembershipDelta<C extends ComponentMap> {\n\tadded: Set<BaseEntity<C>>\n\tremoved: Set<number>\n}\n\n// Low-level off-thread allocation primitives, injected onto the worker `world` each run. `allocateEid` mints a\n// heap-unique id; `allocateComponentBlock` pushes a block into a component's shared pool and returns its index.\n// These are the foundation a future worker-side createEntity builds on (allocate + write blocks, then report the\n// eid/indexes back for the main thread to adopt).\nexport interface WorkerAllocator {\n\tallocateEid(): number\n\tallocateComponentBlock(name: string, values: Array<number>): number\n}\n\n// No callbacks or elapsedTime: init only seeds worker-local state, outside any run.\nexport type EntityWorkerSystemInitWorld = Pick<EntityWorkerSystemWorld, 'gameTime' | 'getString' | 'heap'>;\n\nexport interface EntityWorkerSystemWorld {\n\tgameTime: number\n\telapsedTime: number\n\tgetString(pointer: number): string\n\t// The reconstructed heap (real worker) or the shared main-thread heap (fallback), injected each run so an\n\t// update function can rebuild heap-backed structures (a SharedMap/SharedList) from a pointer in a component\n\t// block. Undefined only before the first run.\n\theap?: MemoryHeap\n\tallocate?: WorkerAllocator\n\t// Injected each run on a system registered with createsEntities: builds a WorkerCreatedEntity descriptor from a\n\t// factory config (merges the type's template, allocates + writes each component's block). Drives createEntityWorker.\n\tbuildEntityDescriptor?(config: WorkerCreateEntityConfig): WorkerCreatedEntity\n\t// Injected for systems with addsComponents. Allocates/writes a block off-thread; the main thread attaches it\n\t// after run completion so no running update observes a changing component set.\n\tbuildComponentDescriptor?(name: string, config: Record<string, unknown>): WorkerCreatedComponent\n}\n// What a game passes to createEntityWorker: a factory-style config - the entity `type` plus any overrides layered\n// over that type's factory template. The worker merges template + overrides, then allocates + writes each triggered\n// component's block off-thread via the component's toBlock(config). The \"entity\" component is built on the main\n// thread when the descriptor is adopted, since interning the type is main-thread-only.\nexport type WorkerCreateEntityConfig = { type: string, class?: never } & { [key: string]: unknown };\n// The result reported back on run-complete: the minted id plus, per game component, the pool index the worker\n// allocated. world.adoptEntity turns this into a real BaseEntity.\nexport interface WorkerCreatedEntity {\n\teid: number\n\ttype: string\n\tclass?: string\n\tisStatic?: boolean\n\tcomponents: { [name: string]: number }\n}\n\nexport interface WorkerCreatedComponent {\n\tname: string\n\tindex: number\n}\n\nexport type WorkerComponentChange =\n\t| { type: 'add', entityId: number, component: WorkerCreatedComponent }\n\t| { type: 'remove', entityId: number, componentName: string };\n\nexport interface EntityWorkerSystemCallbacks<C extends ComponentMap = ComponentMap> {\n\tentityComponentChanged<K extends keyof C, P extends keyof C[K]>(entityId: number, componentName: K, prop: P, value: C[K][P]): void\n\t// Args are structured-cloned, so plain values only.\n\temitEntityEvent(entityId: number, event: string, ...args: Array<unknown>): void\n\t// Emitted **on the system** with all its ids in one array. The allocation-free path for something that\n\t// happens to most entities every run; carries no args (values are already in shared memory).\n\temitSystemEvent(event: string, entityId: number): void\n\tentityDied(entityId: number): void\n\tcreateEntity(entity: WorkerCreatedEntity): void\n\taddComponent(entityId: number, component: WorkerCreatedComponent): void\n\tremoveComponent<K extends keyof C>(entityId: number, componentName: K): void\n}\n\nexport interface EntityWorkerSystemQuery<C extends ComponentMap = ComponentMap> {\n\trequired: Array<keyof C>\n\toptional?: Array<keyof C>\n\tnot?: Array<keyof C>\n\tfilter?: (entity: BaseEntity<C>) => boolean\n}\n\nexport interface EntityWorkerSystemConfig<\n\tC extends ComponentMap,\n\tT extends EntityUpdateComponents<C>,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> extends SystemConfig<C>, EntityWorkerSystemQuery<C> {\n\t// Each batch publishes independently; preRun and the logical delta/clock belong to the whole pass.\n\tworkBatchSize?: number\n\tupdateFunction: EntityUpdateFunction<C, T, W, D>\n\tgetWorker: () => Worker\n\tforceMainThread?: boolean\n\tgetInitData?: () => D\n\t// Opt in to worker-side entity creation (createEntityWorker). When set, factory templates and serializable class\n\t// allowlists are shipped to this system's worker; the worker entry must also pass the component registry to\n\t// createEntitySystemWorker so it has each component's toBlock(). Only systems that create entities need either.\n\t// A component list declares publication access for ConflictScheduler; true stays exclusive there.\n\tcreatesEntities?: boolean | ReadonlyArray<keyof C>\n\t// Opt in to worker-side component allocation through addComponentWorker. The worker entry must also pass the\n\t// component registry to createEntitySystemWorker so the worker has each component's toBlock().\n\taddsComponents?: boolean\n\n\tqueries?: { [key: string]: EntityWorkerSystemQuery<C> }\n}\n\nexport type { BaseComponent };\n\ntype WorkerRunCompletion = Extract<EntitySystemWorkerMessage, { type: 'run-complete' }>;\n","import { EventEmitter } from 'eventemitter3';\nimport type BaseWorld from './world';\nimport type { BaseComponent, ComponentDefinitionMap, ComponentMap, RegisteredComponentRegistry } from './component-definition';\nimport type { EntityComponent } from './entity-component';\n\nexport default class BaseEntity<C extends ComponentMap = ComponentMap, Cfg = any> extends EventEmitter {\n\treadonly eid: number;\n\tconfig?: Cfg;\n\n\tworld: BaseWorld<ComponentDefinitionMap, C, Cfg>;\n\tprivate componentMemoryDeletionScheduled = false;\n\tprivate allowedComponents?: ReadonlySet<string>;\n\t// entity is always present; game components are partial.\n\tcomponents: Partial<C> & { entity: EntityComponent } = {} as Partial<C> & { entity: EntityComponent };\n\n\t// `adoptEid`: build an empty shell around a pre-minted id (an entity a worker created off-thread), skipping the\n\t// automatic entity-component load - the caller (world.adoptEntity) loads the entity component and attaches the\n\t// worker-allocated blocks itself.\n\tconstructor(\n\t\tworld: BaseWorld<ComponentDefinitionMap, C, Cfg>,\n\t\tconfig?: Cfg,\n\t\tadoptEid?: number,\n\t\tallowedComponents?: ReadonlySet<string>,\n\t) {\n\t\tsuper();\n\n\t\tthis.world = world;\n\t\tthis.eid = adoptEid ?? world.allocateEid();\n\t\tthis.allowedComponents = allowedComponents ?? world.factory.getAllowedComponentsForConfig(config);\n\t\tif(adoptEid !== undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.loadComponent('entity', config ?? {}, false);\n\t\tif(config) {\n\t\t\tthis.load(config);\n\t\t}\n\t}\n\tget id(): number {\n\t\treturn this.eid;\n\t}\n\tget dead(): boolean {\n\t\treturn this.components.entity.dead;\n\t}\n\tget type(): string {\n\t\treturn this.components.entity.type;\n\t}\n\n\tloadComponent<K extends keyof C>(name: K, config: any, emitAdded = true): C[K] {\n\t\tthis.assertComponentAllowed(name);\n\t\tconst definition = (this.world.registry as RegisteredComponentRegistry<C>)[name];\n\t\tconst memoryComponent = definition.memoryComponent;\n\t\tconst index = memoryComponent.create(definition.toBlock(config, this));\n\t\tconst component = definition.attach(this, memoryComponent, index, config);\n\t\t// A Component subclass already holds its block; only fetch one for a plain-object accessor that didn't.\n\t\t(component as BaseComponent).block ??= memoryComponent.getBlock(index);\n\t\t(this.components as Partial<C>)[name] = component;\n\t\tif(emitAdded) {\n\t\t\tthis.emit('component-added', name, component);\n\t\t}\n\n\t\treturn component;\n\t}\n\t// Builds an accessor over an existing block (allocated + written by a worker) instead of creating a new one - the\n\t// adopt half of loadComponent, without the create.\n\tattachComponent<K extends keyof C>(name: K, index: number, emitAdded = false): C[K] {\n\t\tthis.assertComponentAllowed(name);\n\t\tconst definition = (this.world.registry as RegisteredComponentRegistry<C>)[name];\n\t\tconst component = definition.attach(this, definition.memoryComponent, index);\n\t\t(component as BaseComponent).block ??= definition.memoryComponent.getBlock(index);\n\t\t(this.components as Partial<C>)[name] = component;\n\t\tif(emitAdded) {\n\t\t\tthis.emit('component-added', name, component);\n\t\t}\n\t\treturn component;\n\t}\n\tremoveComponent<K extends keyof C>(name: K) {\n\t\tif(this.componentMemoryDeletionScheduled) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst component = (this.components as Partial<C>)[name];\n\t\tif(component) {\n\t\t\tconst definition = (this.world.registry as RegisteredComponentRegistry<C>)[name];\n\t\t\tthis.world.deferComponentMemoryFree(definition.memoryComponent, component.index, definition.free ? () => definition.free!(component) : undefined);\n\t\t\tdelete this.components[name];\n\t\t\tthis.emit('component-removed', name);\n\t\t}\n\t}\n\tsetComponent<K extends keyof C, P extends keyof C[K]>(componentName: K, prop: P, value: C[K][P]) {\n\t\tthis.assertComponentPropertyMutable(componentName, prop);\n\t\tconst component = this.components[componentName];\n\t\tif(!component) {\n\t\t\treturn;\n\t\t}\n\n\t\t(component as unknown as Record<P, C[K][P]>)[prop] = value;\n\t\tthis.emit('component-property-updated', componentName, prop, value);\n\t}\n\t/**\n\t * NOTE: Does not emit component-property-updated!\n\t */\n\tsetComponentBulk<K extends keyof C>(componentName: K, values: Partial<C[K]>) {\n\t\tfor(const prop of Object.keys(values)) {\n\t\t\tthis.assertComponentPropertyMutable(componentName, prop);\n\t\t}\n\t\tconst component = this.components[componentName];\n\t\tif(!component) {\n\t\t\treturn;\n\t\t}\n\n\t\tObject.assign(component, values);\n\t}\n\tdeleteComponent<K extends keyof C>(componentName: K, prop: keyof C[K]) {\n\t\tthis.assertComponentPropertyMutable(componentName, prop);\n\t\tconst component = this.components[componentName];\n\t\tif(!component) {\n\t\t\treturn;\n\t\t}\n\n\t\tdelete (component as Partial<C[K]>)[prop];\n\t\tthis.emit('component-property-deleted', componentName, prop);\n\t}\n\n\tdeleteAllComponentMemory() {\n\t\tif(this.componentMemoryDeletionScheduled) {\n\t\t\treturn;\n\t\t}\n\t\tthis.componentMemoryDeletionScheduled = true;\n\n\t\tconst registry = this.world.registry as RegisteredComponentRegistry<C>;\n\t\tconst components = this.components as Partial<C>;\n\t\tfor(let name of Object.keys(components) as Array<keyof C>) {\n\t\t\tconst definition = registry[name];\n\t\t\tconst component = components[name];\n\t\t\tif(component) {\n\t\t\t\tthis.world.deferComponentMemoryFree(definition.memoryComponent, component.index, definition.free ? () => definition.free!(component) : undefined);\n\t\t\t}\n\t\t}\n\t}\n\n\tload(config: Cfg) {\n\t\tconst props = config as Record<string, unknown>;\n\t\tconst registry = this.world.registry as RegisteredComponentRegistry<C>;\n\t\tfor(let name of Object.keys(registry) as Array<keyof C>) {\n\t\t\tif(name === 'entity') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(!this.isComponentAllowed(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst definition = registry[name];\n\t\t\tif(definition.loadInFinishLoading) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(definition.loadProperties.some(prop => prop in props)) {\n\t\t\t\tthis.loadComponent(name, config, false);\n\t\t\t}\n\t\t}\n\n\t\tthis.config = config;\n\t}\n\tsave(): Cfg {\n\t\tconst config: { [key: string]: any } = {};\n\n\t\tconst registry = this.world.registry as RegisteredComponentRegistry<C>;\n\t\tconst components = this.components as Partial<C>;\n\t\tfor(let name of Object.keys(components) as Array<keyof C>) {\n\t\t\tconst definition = registry[name];\n\t\t\tconst component = components[name];\n\t\t\tif(definition.save && component) {\n\t\t\t\tObject.assign(config, definition.save(component));\n\t\t\t}\n\t\t}\n\n\t\treturn config as Cfg;\n\t}\n\t// Second pass once every entity in a load batch exists; loads the deferred (loadInFinishLoading)\n\t// components load skipped. Overrides should call super.\n\tfinishLoading() {\n\t\tconst config = this.config;\n\t\tif(!config) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst props = config as Record<string, unknown>;\n\t\tconst registry = this.world.registry as RegisteredComponentRegistry<C>;\n\t\tfor(let name of Object.keys(registry) as Array<keyof C>) {\n\t\t\tif(name === 'entity') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif(!this.isComponentAllowed(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst definition = registry[name];\n\t\t\tif(definition.loadInFinishLoading && definition.loadProperties.some(prop => prop in props)) {\n\t\t\t\tthis.loadComponent(name, config, false);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate isComponentAllowed(name: keyof C): boolean {\n\t\treturn name === 'entity' || !this.allowedComponents || this.allowedComponents.has(String(name));\n\t}\n\tsetAllowedComponents(allowedComponents: ReadonlySet<string> | undefined): void {\n\t\tif(this.allowedComponents && this.allowedComponents !== allowedComponents) {\n\t\t\tthrow new Error('Entity component allowlist is immutable');\n\t\t}\n\t\tthis.allowedComponents = allowedComponents;\n\t}\n\tprivate assertComponentAllowed(name: keyof C): void {\n\t\tif(!this.isComponentAllowed(name)) {\n\t\t\tthrow new Error(`Component ${String(name)} is not allowed for entity type ${this.type}`);\n\t\t}\n\t}\n\tprivate assertComponentPropertyMutable(componentName: keyof C, prop: PropertyKey): void {\n\t\tif(componentName === 'entity' && (prop === 'type' || prop === 'class')) {\n\t\t\tthrow new Error(`Entity ${prop} is immutable`);\n\t\t}\n\t}\n}\n","import BaseEntity from './entity';\nimport type BaseWorld from './world';\nimport type { ComponentDefinitionMap, ComponentMap } from './component-definition';\nimport type { EntityClassDefinition, EntityClassRegistry, WorkerEntityClassRegistry } from './entity-class';\n\n// Maps type to a template and optionally maps the template's class to a wrapper + component allowlist.\nexport default class EntityFactory<\n\tC extends ComponentMap = ComponentMap,\n\tCfg = any,\n\tE extends BaseEntity<C, Cfg> = BaseEntity<C, Cfg>,\n> {\n\tworld!: BaseWorld<ComponentDefinitionMap, C, Cfg, E>;\n\tconfigs: { [type: string]: Cfg };\n\tclasses: EntityClassRegistry;\n\tprivate allowedComponents = new Map<string, ReadonlySet<string>>();\n\tprivate forbiddenProperties = new Map<string, ReadonlySet<string>>();\n\n\tconstructor(configs: { [type: string]: Cfg } = {}, classes: EntityClassRegistry = {}) {\n\t\tthis.configs = configs;\n\t\tthis.classes = classes;\n\t\tfor(const name of Object.keys(classes)) {\n\t\t\tthis.allowedComponents.set(name, new Set(classes[name].components));\n\t\t}\n\t}\n\n\tregister(type: string, config: Cfg) {\n\t\tif(this.world) {\n\t\t\tthis.validateTemplate(type, config);\n\t\t}\n\t\tthis.configs[type] = config;\n\t}\n\n\tsetWorld(world: BaseWorld<ComponentDefinitionMap, C, Cfg, E>): void {\n\t\tthis.world = world;\n\t\tthis.forbiddenProperties.clear();\n\t\tfor(const name of Object.keys(this.classes)) {\n\t\t\tconst constructor = this.classes[name].entity;\n\t\t\tif(constructor !== BaseEntity && !(constructor.prototype instanceof BaseEntity)) {\n\t\t\t\tthrow new Error(`Entity class ${name} must extend BaseEntity`);\n\t\t\t}\n\t\t\tfor(const component of this.classes[name].components) {\n\t\t\t\tif(component === 'entity' || !(component in world.registry)) {\n\t\t\t\t\tthrow new Error(`Entity class ${name} contains unknown or reserved component ${component}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor(const type of Object.keys(this.configs)) {\n\t\t\tthis.validateTemplate(type, this.configs[type]);\n\t\t}\n\t}\n\n\tgetConfig(config: Cfg): Cfg {\n\t\tconst input = config as { type?: string, class?: unknown } | undefined;\n\t\tconst type = input?.type;\n\t\tconst base = type ? this.configs[type] : undefined;\n\t\tif(this.hasClasses) {\n\t\t\tif(!type || !base) {\n\t\t\t\tthrow new Error(`Unknown entity type: ${type ?? ''}`);\n\t\t\t}\n\t\t\tif(Object.prototype.hasOwnProperty.call(input, 'class')) {\n\t\t\t\tthrow new Error('Entity class comes from its type template and cannot be supplied by an instance config');\n\t\t\t}\n\t\t}\n\t\tconst merged = base ? { ...base, ...config } : config;\n\t\tif(this.hasClasses && type) {\n\t\t\tthis.validateResolvedConfig(type, merged);\n\t\t}\n\t\treturn merged;\n\t}\n\n\tloadEntity(config: Cfg, created = true): E {\n\t\tconst requestedType = (config as { type?: string }).type;\n\t\tconst merged = this.getConfig(config);\n\t\t// The base getConfig already validated; only an override can have changed the result since.\n\t\tif(this.hasClasses && requestedType && this.getConfig !== EntityFactory.prototype.getConfig) {\n\t\t\tthis.validateResolvedConfig(requestedType, merged);\n\t\t}\n\t\tconst definition = this.getClassDefinition(merged);\n\t\tconst entity = definition\n\t\t\t? this.constructEntity(definition, merged)\n\t\t\t: this.createEntity(merged);\n\t\treturn this.world.addEntity(entity, created);\n\t}\n\n\tcreateAdoptedEntity(type: string, entityClass: string | undefined, eid: number): E {\n\t\tif(!entityClass) {\n\t\t\tif(this.hasClasses) {\n\t\t\t\tthrow new Error(`Entity type ${type} has no class`);\n\t\t\t}\n\t\t\treturn new BaseEntity<C, Cfg>(this.world, undefined, eid) as E;\n\t\t}\n\t\tconst definition = this.classes[entityClass];\n\t\tif(!definition) {\n\t\t\tthrow new Error(`Unknown entity class: ${entityClass}`);\n\t\t}\n\t\tthis.validateTypeClass(type, entityClass);\n\t\tconst entity = Reflect.construct(definition.entity, [this.world, undefined, eid, this.allowedComponents.get(entityClass)]) as E;\n\t\tentity.setAllowedComponents(this.allowedComponents.get(entityClass));\n\t\treturn entity;\n\t}\n\n\tisComponentAllowed(entityClass: string | undefined, component: string): boolean {\n\t\treturn !entityClass || !this.hasClasses || this.allowedComponents.get(entityClass)?.has(component) === true;\n\t}\n\n\tgetWorkerClasses(): WorkerEntityClassRegistry | undefined {\n\t\tif(!this.hasClasses) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst classes: WorkerEntityClassRegistry = {};\n\t\tfor(const name of Object.keys(this.classes)) {\n\t\t\tclasses[name] = { components: [...this.classes[name].components] };\n\t\t}\n\t\treturn classes;\n\t}\n\n\tgetAllowedComponentsForConfig(config: Cfg | undefined): ReadonlySet<string> | undefined {\n\t\treturn config ? this.getAllowedComponents(config) : undefined;\n\t}\n\n\tprotected createEntity(config: Cfg): E {\n\t\treturn new BaseEntity<C, Cfg>(this.world, config) as E;\n\t}\n\n\tprivate get hasClasses(): boolean {\n\t\treturn this.allowedComponents.size > 0;\n\t}\n\tprivate getClassDefinition(config: Cfg): EntityClassDefinition | undefined {\n\t\tconst entityClass = (config as { class?: string }).class;\n\t\treturn entityClass ? this.classes[entityClass] : undefined;\n\t}\n\tprivate getAllowedComponents(config: Cfg): ReadonlySet<string> | undefined {\n\t\tconst entityClass = (config as { class?: string }).class;\n\t\treturn entityClass ? this.allowedComponents.get(entityClass) : undefined;\n\t}\n\tprivate constructEntity(definition: EntityClassDefinition, config: Cfg): E {\n\t\tconst entityClass = (config as { class?: string }).class;\n\t\treturn Reflect.construct(definition.entity, [this.world, config, undefined, this.allowedComponents.get(entityClass ?? '')]) as E;\n\t}\n\tprivate validateTemplate(type: string, config: Cfg): void {\n\t\tif(!this.hasClasses) {\n\t\t\treturn;\n\t\t}\n\t\tconst identity = config as { type?: string, class?: string };\n\t\tif(identity.type !== type) {\n\t\t\tthrow new Error(`Entity template ${type} must declare the same type`);\n\t\t}\n\t\tif(!identity.class || !this.classes[identity.class]) {\n\t\t\tthrow new Error(`Entity template ${type} has unknown class ${identity.class ?? ''}`);\n\t\t}\n\t\tthis.validateComponentTriggers(type, identity.class, config);\n\t}\n\tprivate validateResolvedConfig(type: string, config: Cfg): void {\n\t\tconst identity = config as { type?: string, class?: string };\n\t\tif(identity.type !== type) {\n\t\t\tthrow new Error(`Entity type ${type} is immutable`);\n\t\t}\n\t\tif(!identity.class || !this.classes[identity.class]) {\n\t\t\tthrow new Error(`Entity type ${type} has unknown class ${identity.class ?? ''}`);\n\t\t}\n\t\tthis.validateTypeClass(type, identity.class);\n\t\tthis.validateComponentTriggers(type, identity.class, config);\n\t}\n\tprivate validateTypeClass(type: string, entityClass: string): void {\n\t\tconst template = this.configs[type] as { class?: string } | undefined;\n\t\tif(!template || template.class !== entityClass) {\n\t\t\tthrow new Error(`Entity type ${type} does not belong to class ${entityClass}`);\n\t\t}\n\t}\n\tprivate validateComponentTriggers(type: string, entityClass: string, config: Cfg): void {\n\t\tconst forbidden = this.getForbiddenProperties(entityClass);\n\t\tfor(const prop in config as Record<string, unknown>) {\n\t\t\tif(forbidden.has(prop)) {\n\t\t\t\tthis.throwComponentTriggerError(type, entityClass, config);\n\t\t\t}\n\t\t}\n\t}\n\t// Per class: every property that would load a component outside its allowlist. Loads check each config key\n\t// against this instead of rescanning the registry.\n\tprivate getForbiddenProperties(entityClass: string): ReadonlySet<string> {\n\t\tlet forbidden = this.forbiddenProperties.get(entityClass);\n\t\tif(!forbidden) {\n\t\t\tconst allowed = this.allowedComponents.get(entityClass)!;\n\t\t\tconst allowedProperties = new Set<string>();\n\t\t\tfor(const component of allowed) {\n\t\t\t\tfor(const prop of this.world.registry[component as keyof C].loadProperties) {\n\t\t\t\t\tallowedProperties.add(prop);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst props = new Set<string>();\n\t\t\tfor(const name of Object.keys(this.world.registry)) {\n\t\t\t\tif(name === 'entity' || allowed.has(name)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tfor(const prop of this.world.registry[name as keyof C].loadProperties) {\n\t\t\t\t\tif(!allowedProperties.has(prop)) {\n\t\t\t\t\t\tprops.add(prop);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tforbidden = props;\n\t\t\tthis.forbiddenProperties.set(entityClass, forbidden);\n\t\t}\n\t\treturn forbidden;\n\t}\n\t// The original registry-order scan, kept for the failure path so the error names the same component as before.\n\tprivate throwComponentTriggerError(type: string, entityClass: string, config: Cfg): never {\n\t\tconst allowed = this.allowedComponents.get(entityClass)!;\n\t\tconst allowedProperties = new Set<string>();\n\t\tfor(const component of allowed) {\n\t\t\tfor(const prop of this.world.registry[component as keyof C].loadProperties) {\n\t\t\t\tallowedProperties.add(prop);\n\t\t\t}\n\t\t}\n\t\tconst props = config as Record<string, unknown>;\n\t\tfor(const name of Object.keys(this.world.registry)) {\n\t\t\tif(name === 'entity' || allowed.has(name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst definition = this.world.registry[name as keyof C];\n\t\t\tconst forbidden = definition.loadProperties.find(prop => prop in props && !allowedProperties.has(prop));\n\t\t\tif(forbidden) {\n\t\t\t\tthrow new Error(`Entity type ${type} class ${entityClass} cannot load component ${name} from property ${forbidden}`);\n\t\t\t}\n\t\t}\n\t\tthrow new Error(`Entity type ${type} class ${entityClass} loads a component outside its class`);\n\t}\n}\n","// Packs flat entity configs that match a definition into short ASCII strings. Format (all chars JSON-safe ASCII):\n// a string is the definition key followed by one field per property in definition order, each field a value or ABSENT.\n// Trailing absent fields are omitted, so decoding an older string with a newer definition leaves new fields unset.\n// Varint: little-endian base-45 digits; every digit but the last comes from CONTINUATION, the last from TERMINAL.\n// A string value is its length as a varint then its raw characters (0 is null); only it can hold non-alphabet chars.\n// A definition sharing its properties across `types` at key n covers keys n, n + 1, ... in that order.\n\nexport type CompressedPropertyType = 'int' | 'uint' | 'boolean' | 'float32' | 'string';\n\nexport interface CompressedEntityProperty {\n\tname: string\n\ttype: CompressedPropertyType\n\t// int/uint decode as stored * step / 10 ** decimals + offset; e.g. step 32 + offset 16 for tile centres.\n\tstep?: number\n\tdecimals?: number\n\toffset?: number\n}\n\ninterface DefinitionProperties {\n\tproperties: ReadonlyArray<CompressedEntityProperty>\n}\nexport type CompressedEntityDefinition = DefinitionProperties & ({ type: string, types?: never } | { types: ReadonlyArray<string>, type?: never });\n\n// Keyed by the decimal key of a definition's first type; see the format note for shared definitions.\nexport type CompressedEntityDefinitions = Record<string, CompressedEntityDefinition>;\n\nexport interface CompressedEntities<Cfg> {\n\tentityDefinitions: CompressedEntityDefinitions\n\tentities: Array<Cfg | string>\n}\n\ntype CompressibleConfig = object & { type?: string };\ntype DecompressedValue = number | boolean | string | null;\n\nconst COMPRESSION_BASE = 45;\nconst ABSENT = '!';\n// '#'..'O' and 'P'..'}' without the backslash: no char JSON would escape.\nconst TERMINAL = '#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO';\nconst CONTINUATION = 'PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}';\n\n// Char code → digit for TERMINAL, digit + BASE for CONTINUATION, -1 otherwise.\nconst DIGITS = new Int8Array(128).fill(-1);\nfor(let i = 0; i < COMPRESSION_BASE; i++) {\n\tDIGITS[TERMINAL.charCodeAt(i)] = i;\n\tDIGITS[CONTINUATION.charCodeAt(i)] = i + COMPRESSION_BASE;\n}\n\nfunction encodeVarint(value: number): string {\n\tlet encoded = '';\n\twhile(value >= COMPRESSION_BASE) {\n\t\tencoded += CONTINUATION[value % COMPRESSION_BASE];\n\t\tvalue = Math.floor(value / COMPRESSION_BASE);\n\t}\n\treturn encoded + TERMINAL[value];\n}\n\nconst FLOAT_BITS = new Float32Array(1);\nconst UINT_BITS = new Uint32Array(FLOAT_BITS.buffer);\n\n// The field text for a value, or undefined when this property can't represent it exactly.\nfunction encodeField(property: CompressedEntityProperty, value: unknown): string | undefined {\n\tswitch(property.type) {\n\t\tcase 'boolean':\n\t\t\treturn typeof value === 'boolean' ? TERMINAL[Number(value)] : undefined;\n\t\tcase 'string':\n\t\t\tif(value === null) {\n\t\t\t\treturn TERMINAL[0];\n\t\t\t}\n\t\t\treturn typeof value === 'string' && value.length ? encodeVarint(value.length) + value : undefined;\n\t\tcase 'float32':\n\t\t\tif(typeof value !== 'number' || !Number.isFinite(value) || Math.fround(value) !== value) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tFLOAT_BITS[0] = value;\n\t\t\treturn encodeVarint(UINT_BITS[0]);\n\t\tdefault: {\n\t\t\tconst stored = integerValue(property, value);\n\t\t\treturn stored === undefined ? undefined : encodeVarint(stored);\n\t\t}\n\t}\n}\n\nfunction integerValue(property: CompressedEntityProperty, value: unknown): number | undefined {\n\tif(typeof value !== 'number') {\n\t\treturn undefined;\n\t}\n\tconst stored = Math.round((value - (property.offset ?? 0)) * 10 ** (property.decimals ?? 0) / (property.step ?? 1));\n\t// Rejects anything that doesn't decode exactly, including values only near the step through floating point error.\n\tif(!Number.isSafeInteger(stored) || scaled(property, stored) !== value) {\n\t\treturn undefined;\n\t}\n\tif(property.type === 'uint') {\n\t\treturn stored >= 0 ? stored : undefined;\n\t}\n\t// Zigzag so small negatives stay short.\n\tconst zigzag = stored >= 0 ? stored * 2 : -stored * 2 - 1;\n\treturn Number.isSafeInteger(zigzag) ? zigzag : undefined;\n}\n\n// Divides by a power of ten rather than multiplying by a fraction: 1234 / 100 is exactly 12.34, 1234 * 0.01 is not.\nfunction scaled(property: CompressedEntityProperty, stored: number) {\n\treturn stored * (property.step ?? 1) / 10 ** (property.decimals ?? 0) + (property.offset ?? 0);\n}\n\nfunction loadedValue(property: CompressedEntityProperty, stored: number): DecompressedValue {\n\tswitch(property.type) {\n\t\tcase 'boolean':\n\t\t\treturn stored !== 0;\n\t\tcase 'float32':\n\t\t\tUINT_BITS[0] = stored;\n\t\t\treturn FLOAT_BITS[0];\n\t\tcase 'uint':\n\t\t\treturn scaled(property, stored);\n\t\tdefault:\n\t\t\treturn scaled(property, stored % 2 === 0 ? stored / 2 : -(stored + 1) / 2);\n\t}\n}\n\nfunction typesOf(definition: CompressedEntityDefinition): ReadonlyArray<string> {\n\treturn definition.types !== undefined ? definition.types : [definition.type];\n}\n\ninterface DefinitionGroup {\n\tkey: number\n\tdefinition: CompressedEntityDefinition\n\tindices: Map<string, number>\n}\ninterface DefinitionEncoder {\n\tprefix: string\n\tgroup: DefinitionGroup\n}\n\nexport class EntityCompressor {\n\tprivate readonly encoders = new Map<string, DefinitionEncoder>();\n\tprivate readonly used = new Set<DefinitionGroup>();\n\n\tconstructor(definitions: ReadonlyArray<CompressedEntityDefinition>) {\n\t\tlet key = 0;\n\t\tfor(const definition of definitions) {\n\t\t\tconst group: DefinitionGroup = {\n\t\t\t\tkey,\n\t\t\t\tdefinition,\n\t\t\t\tindices: new Map(definition.properties.map((property, index) => [property.name, index])),\n\t\t\t};\n\t\t\tfor(const type of typesOf(definition)) {\n\t\t\t\tif(this.encoders.has(type)) {\n\t\t\t\t\tthrow new Error(`Duplicate compressed entity definition for ${type}`);\n\t\t\t\t}\n\t\t\t\tthis.encoders.set(type, { prefix: encodeVarint(key++), group });\n\t\t\t}\n\t\t}\n\t}\n\n\t// Only the definitions some compressed string needs, so a game can define every type without bloating its saves.\n\tget entityDefinitions(): CompressedEntityDefinitions {\n\t\tconst definitions: CompressedEntityDefinitions = {};\n\t\tfor(const group of this.used) {\n\t\t\tdefinitions[group.key] = group.definition;\n\t\t}\n\t\treturn definitions;\n\t}\n\n\t// Returns the config unchanged when it carries anything its definition can't represent.\n\tcompress<Cfg extends CompressibleConfig>(config: Cfg): Cfg | string {\n\t\tconst encoder = config.type === undefined ? undefined : this.encoders.get(config.type);\n\t\tconst encoded = encoder && this.encode(encoder, config);\n\t\tif(!encoder || encoded === undefined) {\n\t\t\treturn config;\n\t\t}\n\t\tthis.used.add(encoder.group);\n\t\treturn encoded;\n\t}\n\n\tcompressAll<Cfg extends CompressibleConfig>(entities: ReadonlyArray<Cfg>): CompressedEntities<Cfg> {\n\t\tconst compressed = entities.map(config => this.compress(config));\n\t\treturn { entityDefinitions: this.entityDefinitions, entities: compressed };\n\t}\n\n\tprivate encode(encoder: DefinitionEncoder, config: CompressibleConfig): string | undefined {\n\t\tconst fields: Array<string | undefined> = [];\n\t\tfor(const [name, value] of Object.entries(config)) {\n\t\t\tif(name === 'type' || value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst index = encoder.group.indices.get(name);\n\t\t\tif(index === undefined) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst field = encodeField(encoder.group.definition.properties[index], value);\n\t\t\tif(field === undefined) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tfields[index] = field;\n\t\t}\n\n\t\tlet encoded = encoder.prefix;\n\t\tfor(let i = 0; i < fields.length; i++) {\n\t\t\tencoded += fields[i] ?? ABSENT;\n\t\t}\n\t\treturn encoded;\n\t}\n}\n\nexport function compressEntities<Cfg extends CompressibleConfig>(entities: ReadonlyArray<Cfg>, definitions: ReadonlyArray<CompressedEntityDefinition>): CompressedEntities<Cfg> {\n\treturn new EntityCompressor(definitions).compressAll(entities);\n}\n\ninterface ResolvedDefinition {\n\ttype: string\n\tproperties: ReadonlyArray<CompressedEntityProperty>\n}\n// Expanding shared definitions to one entry per key once per save, rather than once per entity.\nconst resolvedDefinitions = new WeakMap<CompressedEntityDefinitions, Map<number, ResolvedDefinition>>();\nfunction resolveDefinitions(definitions: CompressedEntityDefinitions): Map<number, ResolvedDefinition> {\n\tlet resolved = resolvedDefinitions.get(definitions);\n\tif(resolved) {\n\t\treturn resolved;\n\t}\n\tresolved = new Map();\n\tfor(const [key, definition] of Object.entries(definitions)) {\n\t\tconst types = typesOf(definition);\n\t\tfor(let i = 0; i < types.length; i++) {\n\t\t\tif(resolved.has(Number(key) + i)) {\n\t\t\t\tthrow new Error(`Compressed entity definitions overlap at key ${Number(key) + i}`);\n\t\t\t}\n\t\t\tresolved.set(Number(key) + i, { type: types[i], properties: definition.properties });\n\t\t}\n\t}\n\tresolvedDefinitions.set(definitions, resolved);\n\treturn resolved;\n}\n\nexport function decompressEntity(encoded: string, definitions: CompressedEntityDefinitions): Record<string, DecompressedValue | string> {\n\tlet position = 0;\n\tconst readVarint = (): number | undefined => {\n\t\tif(encoded[position] === ABSENT) {\n\t\t\tposition++;\n\t\t\treturn undefined;\n\t\t}\n\t\tlet value = 0;\n\t\tlet multiplier = 1;\n\t\twhile(position < encoded.length) {\n\t\t\tconst code = encoded.charCodeAt(position++);\n\t\t\tconst digit = code < 128 ? DIGITS[code] : -1;\n\t\t\tif(digit < 0) {\n\t\t\t\tthrow new Error(`Invalid compressed entity ${encoded}`);\n\t\t\t}\n\t\t\tif(digit < COMPRESSION_BASE) {\n\t\t\t\treturn value + digit * multiplier;\n\t\t\t}\n\t\t\tvalue += (digit - COMPRESSION_BASE) * multiplier;\n\t\t\tmultiplier *= COMPRESSION_BASE;\n\t\t}\n\t\tthrow new Error(`Truncated compressed entity ${encoded}`);\n\t};\n\n\tconst key = readVarint();\n\tconst definition = key === undefined ? undefined : resolveDefinitions(definitions).get(key);\n\tif(!definition) {\n\t\tthrow new Error(`No compressed entity definition for ${encoded}`);\n\t}\n\tconst config: Record<string, DecompressedValue | string> = { type: definition.type };\n\tfor(let i = 0; position < encoded.length; i++) {\n\t\tconst property = definition.properties[i];\n\t\tif(!property) {\n\t\t\tthrow new Error(`Compressed entity ${encoded} has more values than ${definition.type} defines`);\n\t\t}\n\t\tconst stored = readVarint();\n\t\tif(stored === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tif(property.type !== 'string') {\n\t\t\tconfig[property.name] = loadedValue(property, stored);\n\t\t} else if(stored === 0) {\n\t\t\tconfig[property.name] = null;\n\t\t} else {\n\t\t\tif(position + stored > encoded.length) {\n\t\t\t\tthrow new Error(`Truncated compressed entity ${encoded}`);\n\t\t\t}\n\t\t\tconfig[property.name] = encoded.slice(position, position += stored);\n\t\t}\n\t}\n\treturn config;\n}\n\n// Configs are flat records of the same shape a compressed string expands to, so the caller's Cfg is trusted here.\nexport function decompressEntities<Cfg>(entities: ReadonlyArray<Cfg | string>, definitions: CompressedEntityDefinitions | undefined): Array<Cfg> {\n\treturn entities.map(entity => {\n\t\tif(typeof entity !== 'string') {\n\t\t\treturn entity;\n\t\t}\n\t\tif(!definitions) {\n\t\t\tthrow new Error('Compressed entities need entityDefinitions to load');\n\t\t}\n\t\treturn decompressEntity(entity, definitions) as Cfg;\n\t});\n}\n","import type { ComponentMap } from '../component-definition';\nimport type { Scheduler, SchedulerContext, SchedulerUpdateResult } from './scheduler';\n\nexport default class DefaultScheduler<C extends ComponentMap = ComponentMap> implements Scheduler<C> {\n\tupdate(context: SchedulerContext<C>, elapsedTime: number): SchedulerUpdateResult {\n\t\tlet lastSystemError: Error | null = null;\n\t\tcontext.systems.forEach(system => {\n\t\t\tlet shouldRun = true;\n\t\t\tlet ran = false;\n\t\t\tlet failed = false;\n\t\t\tcontext.emit(`system-${system.name}-started`);\n\t\t\ttry {\n\t\t\t\tshouldRun = system.shouldRun();\n\t\t\t\tif(shouldRun) {\n\t\t\t\t\tran = system.update(elapsedTime);\n\t\t\t\t}\n\t\t\t} catch(e) {\n\t\t\t\tconst error = e as Error;\n\t\t\t\tconsole.error(error.message, error);\n\t\t\t\tfailed = true;\n\t\t\t\tlastSystemError = error;\n\t\t\t\tcontext.emit('system-error', { system: system.name, error, phase: 'run' });\n\t\t\t}\n\t\t\tcontext.emit(`system-${system.name}-finished`, {\n\t\t\t\tran,\n\t\t\t\tshouldRun,\n\t\t\t\tfailed,\n\t\t\t});\n\t\t});\n\n\t\treturn { lastSystemError };\n\t}\n}\n","import { EventEmitter } from 'eventemitter3';\nimport MemoryHeap from '@daneren2005/shared-memory-objects/memory-heap';\nimport type { GrowBufferData } from '@daneren2005/shared-memory-objects/memory-heap';\nimport type AllocatedMemory from '@daneren2005/shared-memory-objects/allocated-memory';\nimport type { SharedAllocatedMemory } from '@daneren2005/shared-memory-objects/allocated-memory';\nimport type { SharedPoolMemory } from '@daneren2005/shared-memory-objects/shared-pool';\nimport { MAX_BYTE_OFFSET_LENGTH } from '@daneren2005/shared-memory-objects/utils/pointer';\nimport MemoryComponent from './memory-component';\nimport ConstantStringCache from './constant-string-cache';\nimport type BaseEntity from './entity';\nimport type System from './systems/system';\nimport type { EntityBatch } from './systems/system';\nimport EntitySystem from './systems/entity-system';\nimport EntityWorkerSystem from './systems/entity-worker-system';\nimport type { WorkerCreatedEntity } from './systems/entity-worker-system';\nimport type {\n\tBaseComponent, ComponentDefinitionMap, ComponentMap, ComponentRegistry, ComponentsOf,\n\tEntityConfigOf, RegisteredComponentDefinition, RegisteredComponentRegistry,\n} from './component-definition';\nimport { entityDefinition, type EntityComponent } from './entity-component';\nimport EntityFactory from './entity-factory';\nimport { decompressEntities, type CompressedEntities } from './entity-compression';\nimport DefaultScheduler from './scheduling/default-scheduler';\nimport type { Scheduler, SchedulerUpdateResult } from './scheduling/scheduler';\n\nconst DEFAULT_HEAP_SIZE = MAX_BYTE_OFFSET_LENGTH;\nconst FREE_BUFFER_STUCK_MS = 10000;\n\ninterface DeferredComponentFree {\n\tmemoryComponent: MemoryComponent\n\tindex: number\n\t// The definition's free hook, deferred to fire alongside the block free rather than the instant the entity dies.\n\tfree?: () => void\n}\n// A batch of component blocks queued to be freed, plus the systems that must each finish a run before it is safe to free them\ninterface QueryKeys {\n\trequired: ReadonlyArray<PropertyKey>\n\toptional?: ReadonlyArray<PropertyKey>\n\tnot?: ReadonlyArray<PropertyKey>\n}\ninterface WorkerQueryKeys extends QueryKeys {\n\tqueries?: { [name: string]: QueryKeys }\n}\n\ninterface ComponentFreeBuffer<C extends ComponentMap> {\n\tfrees: Array<DeferredComponentFree>\n\twaitingSystems: Set<System<C>>\n\twaitElapsed: number\n}\n\nexport interface WorldOptions<\n\tC extends ComponentMap = ComponentMap,\n\tCfg = any,\n\tE extends BaseEntity<C, Cfg> = BaseEntity<C, Cfg>,\n> {\n\theapSize?: number\n\tfactory?: EntityFactory<C, Cfg, E>\n\tscheduler?: Scheduler<C>\n}\n\nexport interface WorldConfig<Cfg = any> {\n\tentities: Array<Cfg>\n\tgameTime?: number\n\tplayerTime?: number\n\ttimeScale?: number\n}\n\n// A save whose entities may be strings packed by compressEntities; load expands them with the bundled definitions.\nexport type CompressedWorldConfig<Cfg = any> = Omit<WorldConfig<Cfg>, 'entities'> & CompressedEntities<Cfg>;\n\n// Shipped to a worker so it can reconstruct handles over this world's shared state (see getSharedComponentMemory).\nexport interface WorldSharedMemory {\n\tcomponents: { [name: string]: SharedPoolMemory }\n\teidCounter: SharedAllocatedMemory\n}\n\nexport default class BaseWorld<\n\tR extends ComponentDefinitionMap = ComponentDefinitionMap,\n\tC extends ComponentMap = ComponentsOf<R>,\n\tCfg = EntityConfigOf<R>,\n\tE extends BaseEntity<C, Cfg> = BaseEntity<C, Cfg>,\n> extends EventEmitter {\n\theap: MemoryHeap;\n\t// Interns entity type names (and any other constant strings) in the heap\n\tconstantStrings: ConstantStringCache;\n\t// Single heap-backed counter every thread bumps atomically, so eids stay unique whether an entity is created on\n\t// the main thread or inside a worker.\n\tprivate eidCounter: AllocatedMemory;\n\tregistry: RegisteredComponentRegistry<C> & { entity: RegisteredComponentDefinition<EntityComponent> };\n\tfactory: EntityFactory<C, Cfg, E>;\n\n\t// Keyed by eid: entities leave from the middle one at a time (every death), so a Map deletes in constant\n\t// time while still iterating in insertion order, preserving load/save order.\n\tentities: Map<number, E> = new Map();\n\tsystems: Array<System<C>> = [];\n\treadonly scheduler: Scheduler<C>;\n\n\tgameTime = 0;\n\t// Keeps advancing while paused and is never scaled by timeScale (unlike gameTime).\n\tplayerTime = 0;\n\ttimeScale = 1;\n\tprivate isPaused = false;\n\tdestroyed = false;\n\t// True while the world has never been loaded into\n\tpristine = true;\n\t// True while load() adds its batch: systems ignore per-entity events and are handed every entity at the end.\n\tisBulkLoading = false;\n\n\t// Two rolling buffers of component blocks awaiting a safe free. New deferrals land in `next`; `active` is the\n\t// one currently waiting for its systems to each finish a run before its blocks can be reused\n\tprivate activeFreeBuffer: ComponentFreeBuffer<C> = { frees: [], waitingSystems: new Set(), waitElapsed: 0 };\n\tprivate nextFreeBuffer: ComponentFreeBuffer<C> = { frees: [], waitingSystems: new Set(), waitElapsed: 0 };\n\tprivate clearing = false;\n\n\t// The entity component is added automatically, so it must not be part of the passed registry.\n\tconstructor(registry: R, options: WorldOptions<C, Cfg, E> = {}) {\n\t\tsuper();\n\n\t\tthis.scheduler = options.scheduler ?? new DefaultScheduler<C>();\n\t\tthis.heap = new MemoryHeap({ bufferSize: options.heapSize ?? DEFAULT_HEAP_SIZE });\n\t\tthis.constantStrings = new ConstantStringCache(this.heap);\n\t\tthis.eidCounter = this.heap.allocUI32(1);\n\t\t// A grown buffer must reach every worker's reconstructed heap so pointers into it still resolve.\n\t\tthis.heap.addOnGrowBufferHandlers((data: GrowBufferData) => this.emit('grow-buffer', data));\n\n\t\tconst inputRegistry = { ...registry, entity: entityDefinition } as ComponentRegistry<C> & { entity: typeof entityDefinition };\n\t\tconst registry_: Record<string, RegisteredComponentDefinition<BaseComponent>> = {};\n\t\tfor(let name of Object.keys(inputRegistry)) {\n\t\t\tconst definition = inputRegistry[name as keyof typeof inputRegistry];\n\t\t\tregistry_[name] = {\n\t\t\t\t...definition,\n\t\t\t\tmemoryComponent: new MemoryComponent(this.heap, definition.type, definition.size),\n\t\t\t};\n\t\t}\n\t\tthis.registry = registry_ as RegisteredComponentRegistry<C> & { entity: RegisteredComponentDefinition<EntityComponent> };\n\n\t\tthis.factory = options.factory ?? new EntityFactory<C, Cfg, E>();\n\t\tthis.factory.setWorld(this);\n\t}\n\n\t// Returns a fresh, unique entity id. Backed by a heap atomic so a worker allocating an entity gets an id that can\n\t// never collide with one the main thread (or another worker) hands out. First id is 1, matching the old counter.\n\tallocateEid(): number {\n\t\treturn Atomics.add(this.eidCounter.data, 0, 1) + 1;\n\t}\n\t// Everything a worker needs to reconstruct handles over this world's shared state: one SharedPoolMemory per\n\t// registered component (so it can allocate/read blocks) plus the eid counter (so it can mint unique ids).\n\tgetSharedComponentMemory(): WorldSharedMemory {\n\t\tconst components: { [name: string]: SharedPoolMemory } = {};\n\t\tfor(let name of Object.keys(this.registry)) {\n\t\t\tcomponents[name] = this.registry[name as keyof typeof this.registry].memoryComponent.getSharedMemory();\n\t\t}\n\t\treturn {\n\t\t\tcomponents,\n\t\t\teidCounter: this.eidCounter.getSharedMemory(),\n\t\t};\n\t}\n\t// A buffer that was grown inside a worker: adopt it into the main heap (if not already present) and fan it out to\n\t// every other worker so their heaps can resolve pointers into it. The heap's BUFFER_COUNT is authoritative, so\n\t// re-adding an already-known position is a harmless overwrite of the same SharedArrayBuffer.\n\taddGrownBuffer(data: GrowBufferData) {\n\t\tif(this.heap.buffers[data.bufferPosition] === undefined) {\n\t\t\tthis.heap.addSharedBuffer(data);\n\t\t}\n\t\tthis.emit('grow-buffer', data);\n\t}\n\n\t// Only an off-thread EntityWorkerSystem that creates entities or adds components allocates in a worker, so only\n\t// then is a pre-fanned-out spare buffer worth keeping. The main-thread fallback allocates on the main thread, where\n\t// growth fans out inline, so it never needs one.\n\tprivate get needsSpareBuffer(): boolean {\n\t\treturn this.systems.some(system => system instanceof EntityWorkerSystem\n\t\t\t&& system.isWorkerThread\n\t\t\t&& (!!system.options.createsEntities || !!system.options.addsComponents));\n\t}\n\n\tasync init() {\n\t\tawait Promise.all(this.systems.map(system => system.init()).filter(promise => promise instanceof Promise));\n\t}\n\tprivate async finishLoadingSystems(): Promise<void> {\n\t\tawait Promise.all(this.systems.map(system => system.finishLoading()).filter(promise => promise instanceof Promise));\n\t}\n\n\taddEntity(entity: E, created = true): E {\n\t\tthis.entities.set(entity.eid, entity);\n\t\tentity.world = this;\n\t\t// Any entity in the world means there is state to tear down on the next load/clear.\n\t\tthis.pristine = false;\n\n\t\tentity.on('component-added', (name: keyof C) => {\n\t\t\tthis.addEntityToEntityWorkerSystem(entity, name);\n\t\t});\n\t\tentity.on('component-removed', (name: keyof C) => {\n\t\t\tthis.removeEntityFromEntityWorkerSystem(entity, name);\n\t\t});\n\n\t\tif(created) {\n\t\t\tentity.finishLoading();\n\t\t\tthis.emit('entity-added', entity);\n\t\t\tentity.on('death', () => {\n\t\t\t\tthis.onEntityDied(entity);\n\t\t\t});\n\t\t}\n\n\t\treturn entity;\n\t}\n\tloadEntity(config: Cfg, created = true): E {\n\t\treturn this.factory.loadEntity(config, created);\n\t}\n\t// Materializes an entity a worker created off-thread (see createEntityWorker): the worker already minted the id and\n\t// allocated + wrote every game-component block, so this only builds the `entity` component on the main thread\n\t// (interning its type) and adopts each worker-allocated block by index, then wires it into the world like any new\n\t// entity. The factory selects the same class wrapper a main-thread load would use.\n\tadoptEntity(descriptor: WorkerCreatedEntity): E {\n\t\tlet entity: E | undefined;\n\t\tconst attached = new Set<string>();\n\t\ttry {\n\t\t\tfor(const name of Object.keys(descriptor.components)) {\n\t\t\t\tif(!(name in this.registry)) {\n\t\t\t\t\tthrow new Error(`Worker-created entity contains unknown component ${name}`);\n\t\t\t\t}\n\t\t\t\tif(!this.factory.isComponentAllowed(descriptor.class, name)) {\n\t\t\t\t\tthrow new Error(`Component ${name} is not allowed for entity class ${descriptor.class ?? ''}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tentity = this.factory.createAdoptedEntity(descriptor.type, descriptor.class, descriptor.eid);\n\t\t\tentity.loadComponent('entity', { type: descriptor.type, class: descriptor.class, isStatic: descriptor.isStatic }, false);\n\t\t\tfor(let name of Object.keys(descriptor.components)) {\n\t\t\t\tentity.attachComponent(name, descriptor.components[name]);\n\t\t\t\tattached.add(name);\n\t\t\t}\n\t\t\treturn this.addEntity(entity, true);\n\t\t} catch(error) {\n\t\t\tentity?.deleteAllComponentMemory();\n\t\t\tfor(const name of Object.keys(descriptor.components)) {\n\t\t\t\tif(!attached.has(name) && name in this.registry) {\n\t\t\t\t\tthis.deferComponentMemoryFree(this.registry[name as keyof C].memoryComponent, descriptor.components[name]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\t// Replaces the world's contents. Entities load with created = false so no finishLoading runs mid-batch;\n\t// finishLoading is called on each once the whole batch exists, so cross-entity dependencies can resolve.\n\tload(config: WorldConfig<Cfg> | CompressedWorldConfig<Cfg>): Promise<void> {\n\t\t// A pristine world (fresh or just cleared) has nothing to tear down, so skip the per-system clear.\n\t\tif(!this.pristine || (this.scheduler.prepareEffects && this.systems.some(system => system.isCurrentlyRunning()))) {\n\t\t\t// clear() drops a worker run's bookkeeping without waiting for it, so the old blocks must outlive that run.\n\t\t\tconst abandoned = this.systems.filter(system => system.isCurrentlyRunning());\n\t\t\t// Iterate over a copy since removeEntity mutates `this.entities`.\n\t\t\tfor(let entity of Array.from(this.entities.values())) {\n\t\t\t\tthis.removeEntity(entity);\n\t\t\t}\n\t\t\tthis.systems.forEach(system => system.clear());\n\t\t\tthis.scheduler.reset?.(this);\n\t\t\tthis.consolidateFreeBuffersForReload(abandoned);\n\t\t}\n\n\t\t// Intern a constant string for every type the factory knows, so a worker can resolve any type - even one no\n\t\t// currently-loaded entity uses. Deduped, so the types actually loaded below cost nothing extra.\n\t\tfor(let type of Object.keys(this.factory.configs)) {\n\t\t\tthis.constantStrings.getOrCreate(type);\n\t\t}\n\t\tfor(let entityClass of Object.keys(this.factory.classes)) {\n\t\t\tthis.constantStrings.getOrCreate(entityClass);\n\t\t}\n\n\t\tthis.isBulkLoading = true;\n\t\ttry {\n\t\t\tconst configs = 'entityDefinitions' in config ? decompressEntities(config.entities, config.entityDefinitions) : config.entities;\n\t\t\tconst entities = configs.map(entityConfig => this.loadEntity(entityConfig, false));\n\t\t\tfor(let entity of entities) {\n\t\t\t\tentity.finishLoading();\n\t\t\t\tthis.emit('entity-added', entity);\n\t\t\t\tentity.on('death', () => {\n\t\t\t\t\tthis.onEntityDied(entity);\n\t\t\t\t});\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.isBulkLoading = false;\n\t\t}\n\t\t// Read back from the world rather than the batch, so entities created or removed by listeners mid-load are\n\t\t// reflected. The world was empty beforehand, so no system holds any of these yet.\n\t\tconst batch = batchByComponents(this.entities.values());\n\t\tthis.systems.forEach(system => system.addEntities(batch));\n\n\t\tthis.gameTime = config.gameTime ?? 0;\n\t\tthis.playerTime = config.playerTime ?? 0;\n\t\tthis.timeScale = config.timeScale ?? 1;\n\n\t\t// EntityWorkerSystem re-sends its init data here.\n\t\treturn this.finishLoadingSystems();\n\t}\n\tasync clear(): Promise<void> {\n\t\tif(this.pristine && !this.scheduler.beforeClear) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.clearing = true;\n\t\ttry {\n\t\t\tthis.scheduler.beforeClear?.(this);\n\t\t\t// Await active workers before their component blocks can be reused.\n\t\t\tawait Promise.all(\n\t\t\t\tthis.systems\n\t\t\t\t\t.map(system => system.waitForRunToComplete())\n\t\t\t\t\t.filter(promise => promise instanceof Promise),\n\t\t\t);\n\t\t\tfor(let entity of Array.from(this.entities.values())) {\n\t\t\t\tthis.removeEntity(entity);\n\t\t\t}\n\t\t\tthis.systems.forEach(system => system.clear());\n\t\t\tthis.scheduler.reset?.(this);\n\t\t\tthis.freeAllPendingBuffers();\n\n\t\t\tthis.pristine = true;\n\t\t} finally {\n\t\t\tthis.clearing = false;\n\t\t}\n\t}\n\tremoveEntity(entity: E) {\n\t\t// Match the instance as well as the eid: a stale entity must not remove a newer entity that owns the same key.\n\t\tif(this.entities.get(entity.eid) !== entity) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.entities.delete(entity.eid);\n\t\tthis.emit('entity-removed', entity);\n\t\tentity.deleteAllComponentMemory();\n\t}\n\t// Fires the death hooks then removes the entity\n\tonEntityDied(entity: E) {\n\t\tif(this.entities.get(entity.eid) !== entity) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst registry = this.registry as RegisteredComponentRegistry<C>;\n\t\tconst components = entity.components as Partial<C>;\n\t\tfor(let name of Object.keys(components) as Array<keyof C>) {\n\t\t\tconst definition = registry[name];\n\t\t\tconst component = components[name];\n\t\t\tif(definition?.died && component) {\n\t\t\t\t// A bad hook must not abort the death; mirror the update-loop convention and surface a system-error.\n\t\t\t\ttry {\n\t\t\t\t\tdefinition.died(component, entity, this as unknown as BaseWorld);\n\t\t\t\t} catch(e) {\n\t\t\t\t\tconst error = e as Error;\n\t\t\t\t\tconsole.error(`Error in died hook for component ${String(name)} (entity ${entity.eid}): ${error.message}`, error);\n\t\t\t\t\tthis.emit('system-error', { system: String(name), error, entityId: entity.eid, phase: 'died' });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.emit('entity-died', entity);\n\t\tthis.removeEntity(entity);\n\t}\n\tgetEntityByEid(eid: number): E | undefined {\n\t\treturn this.entities.get(eid);\n\t}\n\n\t// Queues a component block to be freed when all systems done using it, running the definition's free hook (if any)\n\t// at that same deferred point so a system still mid-run can't observe the resource being torn down early.\n\tdeferComponentMemoryFree(memoryComponent: MemoryComponent, index: number, free?: () => void) {\n\t\tthis.nextFreeBuffer.frees.push({ memoryComponent, index, free });\n\t}\n\t// A system finished a run; if the active buffer was waiting on it, drop it and, once nothing is left to wait\n\t// for, free the buffer. One completion is enough: the system is now done touching the block for that run, and\n\t// every later run applies the pending removed-delta before its update loop, so it can never process the freed\n\t// entity again.\n\tnotifySystemRunCompleted(system: System<C>) {\n\t\tif(this.activeFreeBuffer.waitingSystems.delete(system) && this.activeFreeBuffer.waitingSystems.size === 0) {\n\t\t\tthis.processFreeBuffers();\n\t\t}\n\t\tthis.scheduler.runCompleted?.(this, system);\n\t}\n\t// A worker run abandoned by clear() finally replied, so it's done with the old world's blocks. Not while a newer\n\t// run is in flight: that one still reports completion itself.\n\tnotifyAbandonedRunFinished(system: System<C>) {\n\t\tif(system.isCurrentlyRunning()) {\n\t\t\treturn;\n\t\t}\n\t\tif(this.activeFreeBuffer.waitingSystems.delete(system) && this.activeFreeBuffer.waitingSystems.size === 0) {\n\t\t\tthis.processFreeBuffers();\n\t\t}\n\t}\n\tprivate processFreeBuffers() {\n\t\t// Loop so a promoted buffer with no systems to wait for is freed the same tick rather than a frame later.\n\t\twhile(this.activeFreeBuffer.waitingSystems.size === 0) {\n\t\t\tif(this.activeFreeBuffer.frees.length > 0) {\n\t\t\t\tthis.performFrees(this.activeFreeBuffer);\n\t\t\t}\n\t\t\tif(this.nextFreeBuffer.frees.length === 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.promoteNextFreeBuffer();\n\t\t}\n\t}\n\tprivate promoteNextFreeBuffer() {\n\t\t// active is now empty (its frees were performed); swap roles and reuse it as the new next buffer.\n\t\tconst emptied = this.activeFreeBuffer;\n\t\tthis.activeFreeBuffer = this.nextFreeBuffer;\n\t\tthis.nextFreeBuffer = emptied;\n\n\t\tconst active = this.activeFreeBuffer;\n\t\tactive.waitElapsed = 0;\n\t\tactive.waitingSystems.clear();\n\t\tfor(let system of this.systems) {\n\t\t\t// Only an in-flight run can be holding these blocks: a run that starts later only sees live entities, since\n\t\t\t// workers apply the removed-delta before touching memory.\n\t\t\tif(system.isCurrentlyRunning()) {\n\t\t\t\tactive.waitingSystems.add(system);\n\t\t\t}\n\t\t}\n\t}\n\t// On reload every system was just cleared, so the old targets no longer apply. Collapse whatever was pending into\n\t// `active`, waiting only on runs the clear abandoned mid-flight (each releases itself when its stale reply lands).\n\tprivate consolidateFreeBuffersForReload(abandoned: ReadonlyArray<System<C>>) {\n\t\tconst active = this.activeFreeBuffer;\n\t\tactive.frees.push(...this.nextFreeBuffer.frees);\n\t\tthis.nextFreeBuffer.frees.length = 0;\n\t\tactive.waitingSystems.clear();\n\t\tabandoned.forEach(system => active.waitingSystems.add(system));\n\t\tactive.waitElapsed = 0;\n\t}\n\t// Frees both buffers outright. Only safe once every system's in-flight run has finished (see clear()), since it\n\t// skips the per-system wait the update loop normally enforces.\n\tprivate freeAllPendingBuffers() {\n\t\tthis.performFrees(this.activeFreeBuffer);\n\t\tthis.performFrees(this.nextFreeBuffer);\n\t\tthis.activeFreeBuffer.waitingSystems.clear();\n\t\tthis.activeFreeBuffer.waitElapsed = 0;\n\t\tthis.nextFreeBuffer.waitingSystems.clear();\n\t\tthis.nextFreeBuffer.waitElapsed = 0;\n\t}\n\tprivate performFrees(buffer: ComponentFreeBuffer<C>) {\n\t\tfor(let deferred of buffer.frees) {\n\t\t\tdeferred.free?.();\n\t\t\tdeferred.memoryComponent.delete(deferred.index);\n\t\t}\n\t\tbuffer.frees.length = 0;\n\t}\n\tprivate checkFreeBufferTimeout(elapsedTime: number) {\n\t\tconst active = this.activeFreeBuffer;\n\t\tif(active.waitingSystems.size === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tactive.waitElapsed += elapsedTime;\n\t\tif(active.waitElapsed >= FREE_BUFFER_STUCK_MS) {\n\t\t\tconst stuck = Array.from(active.waitingSystems).map(system => system.name).join(', ');\n\t\t\tconsole.warn(`shared-memory-ecs: deferred component free waited over ${FREE_BUFFER_STUCK_MS}ms on system(s): ${stuck}; freeing anyway`);\n\t\t\tactive.waitingSystems.clear();\n\t\t\tthis.processFreeBuffers();\n\t\t}\n\t}\n\n\taddSystem<T extends System<C>>(system: T): T {\n\t\tthis.systems.push(system);\n\t\tthis.scheduler.systemAdded?.(this, system);\n\t\tthis.emit('system-added', system);\n\t\treturn system;\n\t}\n\taddSystemIfNotExists(system: System<C>) {\n\t\tlet index = this.systems.findIndex(otherSystem => system.name === otherSystem.name);\n\t\tif(index === -1) {\n\t\t\tthis.systems.push(system);\n\t\t\tthis.scheduler.systemAdded?.(this, system);\n\t\t\tthis.emit('system-added', system);\n\t\t}\n\t}\n\tremoveSystem(name: string) {\n\t\tlet index = this.systems.findIndex(system => system.name === name);\n\t\tif(index !== -1) {\n\t\t\tconst [system] = this.systems.splice(index, 1);\n\t\t\tthis.scheduler.systemRemoved?.(this, system);\n\t\t\tthis.emit('system-removed', system);\n\t\t\tif(this.activeFreeBuffer.waitingSystems.delete(system) && this.activeFreeBuffer.waitingSystems.size === 0) {\n\t\t\t\tthis.processFreeBuffers();\n\t\t\t}\n\t\t}\n\t}\n\n\tupdate(elapsedTime: number): SchedulerUpdateResult {\n\t\tthis.emit('update-started', elapsedTime);\n\t\tconst result = this.runUpdate(elapsedTime);\n\t\tthis.emit('update-finished', elapsedTime);\n\n\t\treturn result;\n\t}\n\tprivate runUpdate(elapsedTime: number): SchedulerUpdateResult {\n\t\tthis.playerTime += elapsedTime;\n\t\tif(this.paused) {\n\t\t\treturn {};\n\t\t}\n\t\tconst unscaledElapsedTime = elapsedTime;\n\t\telapsedTime = this.timeScale * elapsedTime;\n\n\t\tthis.gameTime += elapsedTime;\n\n\t\t// Promote before running: a run this same update then counts toward the wait, instead of after it.\n\t\tthis.processFreeBuffers();\n\n\t\t// Keep an empty heap buffer fanned out ahead of any worker that allocates off-thread, so its allocations land in\n\t\t// a buffer every thread already holds. Done here (before dispatching runs) so the resulting grow-buffer message\n\t\t// is queued to each worker before its run message - postMessage is FIFO, so the worker has the buffer first.\n\t\tif(this.needsSpareBuffer) {\n\t\t\tthis.heap.ensureSpareBuffer();\n\t\t}\n\n\t\tconst result = this.scheduler.update(this, elapsedTime);\n\n\t\tthis.checkFreeBufferTimeout(unscaledElapsedTime);\n\n\t\treturn result;\n\t}\n\tpause() {\n\t\tthis.paused = true;\n\t}\n\tget paused(): boolean {\n\t\treturn this.isPaused;\n\t}\n\tset paused(paused: boolean) {\n\t\tif(this.isPaused === paused) {\n\t\t\treturn;\n\t\t}\n\t\tthis.isPaused = paused;\n\t\tif(paused) {\n\t\t\tthis.scheduler.pause?.(this);\n\t\t}\n\t}\n\tprepareForSystemDispatch(): boolean {\n\t\tif(!this.dispatchAllowed) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.needsSpareBuffer) {\n\t\t\tthis.heap.ensureSpareBuffer();\n\t\t}\n\t\treturn true;\n\t}\n\tget dispatchAllowed(): boolean {\n\t\treturn !this.clearing && !this.destroyed;\n\t}\n\tresume() {\n\t\tthis.paused = false;\n\t}\n\n\taddEntityToEntityWorkerSystem(entity: BaseEntity<C>, component: keyof C) {\n\t\tif(this.isBulkLoading) {\n\t\t\treturn;\n\t\t}\n\t\tthis.systems.forEach(system => {\n\t\t\tif(system instanceof EntitySystem && system.options.components?.includes(component)) {\n\t\t\t\tsystem.checkAddEntity(entity);\n\t\t\t} else if(system instanceof EntityWorkerSystem) {\n\t\t\t\tif(this.queriesReferenceComponent(system.options, component)) {\n\t\t\t\t\tsystem.checkAddEntity(entity);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tremoveEntityFromEntityWorkerSystem(entity: BaseEntity<C>, component: keyof C) {\n\t\tif(this.isBulkLoading) {\n\t\t\treturn;\n\t\t}\n\t\tthis.systems.forEach(system => {\n\t\t\tif(system instanceof EntitySystem && system.options.components?.includes(component)) {\n\t\t\t\tsystem.removeEntity(entity);\n\t\t\t} else if(system instanceof EntityWorkerSystem) {\n\t\t\t\tif(this.queriesReferenceComponent(system.options, component)) {\n\t\t\t\t\tsystem.checkAddEntity(entity);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t// Takes only query keys: an EntityWorkerSystem<C> parameter would make BaseWorld (and BaseEntity) invariant in C.\n\tprivate queriesReferenceComponent(options: WorkerQueryKeys, component: keyof C): boolean {\n\t\tconst affectsMainQuery = options.required.includes(component)\n\t\t\t|| !!options.not?.includes(component)\n\t\t\t|| !!options.optional?.includes(component);\n\t\tconst affectsSubQuery = Object.values(options.queries ?? {}).some(query => {\n\t\t\treturn query.required.includes(component)\n\t\t\t\t|| !!query.not?.includes(component)\n\t\t\t\t|| !!query.optional?.includes(component);\n\t\t});\n\n\t\treturn affectsMainQuery || affectsSubQuery;\n\t}\n\n\tdestroy() {\n\t\tif(this.destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.systems.forEach(system => {\n\t\t\tsystem.destroy();\n\t\t});\n\t\tthis.scheduler.destroy?.(this);\n\t\tthis.destroyed = true;\n\t}\n}\n\n// Removed components are deleted from the bag, so the key list alone identifies the component set.\nfunction batchByComponents<C extends ComponentMap>(entities: Iterable<BaseEntity<C>>): EntityBatch<C> {\n\tconst batch: EntityBatch<C> = { entities: [], groupIndexes: [], groups: [] };\n\tconst groupIndexByKey = new Map<string, number>();\n\tfor(let entity of entities) {\n\t\tconst key = Object.keys(entity.components).sort().join(',');\n\t\tlet groupIndex = groupIndexByKey.get(key);\n\t\tif(groupIndex === undefined) {\n\t\t\tgroupIndex = batch.groups.push(entity) - 1;\n\t\t\tgroupIndexByKey.set(key, groupIndex);\n\t\t}\n\t\tbatch.entities.push(entity);\n\t\tbatch.groupIndexes.push(groupIndex);\n\t}\n\treturn batch;\n}\n","import type { ComponentMap } from '../component-definition';\nimport type System from '../systems/system';\nimport IterableSystem from '../systems/iterable-system';\nimport type { Scheduler, SchedulerContext, SchedulerEffects, SchedulerUpdateResult } from './scheduler';\n\nexport interface ConflictSchedule<C extends ComponentMap = ComponentMap> {\n\treadonly order: ReadonlyArray<System<C>>\n\treadonly batches: ReadonlyArray<ReadonlyArray<System<C>>>\n}\n\ninterface SystemAccess {\n\treads: Set<PropertyKey>\n\tcreationReads: Set<PropertyKey>\n\tcreationQueries?: ReadonlyArray<ReadonlyArray<PropertyKey>>\n\twrites: Set<PropertyKey>\n\tcreates: Set<PropertyKey>\n\texclusive: boolean\n}\n\ntype RunState = 'pending' | 'running' | 'complete';\n\ninterface ScheduledUpdate<C extends ComponentMap> {\n\tsystem: System<C>\n\taccess: SystemAccess\n\telapsedTime: number\n\tgameTime: number\n\tstate: RunState\n\tdependencies: number\n\tdependents: Array<ScheduledUpdate<C>>\n\tpublicationDependencies: number\n\tpublicationDependents: Array<ScheduledUpdate<C>>\n\teffects?: SchedulerEffects\n}\n\ninterface ComponentFrontier<C extends ComponentMap> {\n\twriter?: ScheduledUpdate<C>\n\tcreator?: ScheduledUpdate<C>\n\treaders: Map<System<C>, ScheduledUpdate<C>>\n}\n\nexport default class ConflictScheduler<C extends ComponentMap = ComponentMap> implements Scheduler<C> {\n\tprivate compiled: ConflictSchedule<C> = Object.freeze({ order: Object.freeze([]), batches: Object.freeze([]) });\n\tprivate registeredSystems: Array<System<C>> = [];\n\tprivate access = new Map<System<C>, SystemAccess>();\n\tprivate nodes = new Set<ScheduledUpdate<C>>();\n\tprivate tails = new Map<System<C>, ScheduledUpdate<C>>();\n\tprivate frontiers = new Map<PropertyKey, ComponentFrontier<C>>();\n\tprivate creators = new Map<SystemAccess, ScheduledUpdate<C>>();\n\tprivate creationReaders = new Map<SystemAccess, ScheduledUpdate<C>>();\n\tprivate exclusiveTail: ScheduledUpdate<C> | undefined;\n\tprivate running = new Map<System<C>, ScheduledUpdate<C>>();\n\tprivate ready: Array<ScheduledUpdate<C>> = [];\n\tprivate readyIndex = 0;\n\tprivate gameTime = 0;\n\tprivate pumping = false;\n\tprivate resumeQueued = false;\n\tprivate continuationTimer: ReturnType<typeof setTimeout> | undefined;\n\tprivate generation = 0;\n\tprivate publications = new Set<ScheduledUpdate<C>>();\n\tprivate publicationReady: Array<ScheduledUpdate<C>> = [];\n\tprivate publishing = false;\n\n\tget schedule(): ConflictSchedule<C> {\n\t\treturn this.compiled;\n\t}\n\n\trebuild(context: SchedulerContext<C>): ConflictSchedule<C> {\n\t\tconst systems = Array.from(new Set(context.systems));\n\t\tconst access = systems.map(system => {\n\t\t\tconst reads = system.readComponents;\n\t\t\tconst queries = system.creationReadQueries;\n\t\t\treturn {\n\t\t\t\treads: new Set(reads),\n\t\t\t\tcreationReads: new Set(queries === undefined ? system.creationReadComponents : system.reads),\n\t\t\t\tcreationQueries: queries?.map(query => Array.from(query)),\n\t\t\t\twrites: new Set(system.writes),\n\t\t\t\tcreates: new Set(system.createdComponents),\n\t\t\t\texclusive: system.requiresExclusiveScheduling || reads === undefined || system.writes === undefined,\n\t\t\t};\n\t\t});\n\t\tthis.access = new Map(systems.map((system, index) => [system, access[index]]));\n\t\tconst batches: Array<Array<System<C>>> = [];\n\t\tconst levels: Array<number> = [];\n\t\tfor(let i = 0; i < systems.length; i++) {\n\t\t\tlet level = 0;\n\t\t\tfor(let j = 0; j < i; j++) {\n\t\t\t\tif(this.conflicts(access[j], access[i])) {\n\t\t\t\t\tlevel = Math.max(level, levels[j] + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlevels.push(level);\n\t\t\t(batches[level] ??= []).push(systems[i]);\n\t\t}\n\t\tthis.registeredSystems = context.systems.slice();\n\t\tthis.compiled = Object.freeze({\n\t\t\torder: Object.freeze(batches.flat()),\n\t\t\tbatches: Object.freeze(batches.map(batch => Object.freeze(batch))),\n\t\t});\n\t\treturn this.compiled;\n\t}\n\n\tsystemAdded(context: SchedulerContext<C>): void {\n\t\tthis.rebuild(context);\n\t}\n\tsystemRemoved(context: SchedulerContext<C>): void {\n\t\tthis.rebuild(context);\n\t}\n\n\tupdate(context: SchedulerContext<C>, elapsedTime: number): SchedulerUpdateResult {\n\t\tif(this.pumping) {\n\t\t\tthrow new Error('ConflictScheduler does not support reentrant updates');\n\t\t}\n\t\tthis.refreshMembership(context);\n\t\tthis.gameTime = context.gameTime ?? this.gameTime + elapsedTime;\n\t\tfor(const system of new Set(context.systems)) {\n\t\t\tthis.enqueue(system, this.access.get(system)!, elapsedTime, this.gameTime);\n\t\t}\n\t\treturn this.pump(context, true);\n\t}\n\n\trunCompleted(context: SchedulerContext<C>, system: System<C>): void {\n\t\tconst node = this.running.get(system);\n\t\tif(!node) {\n\t\t\treturn;\n\t\t}\n\t\tthis.complete(node);\n\t\tif(this.pumping || this.resumeQueued) {\n\t\t\treturn;\n\t\t}\n\t\tthis.resumeQueued = true;\n\t\tconst generation = this.generation;\n\t\t// Let the worker settle its completion promise before dispatching another run on that worker.\n\t\tqueueMicrotask(() => {\n\t\t\tif(generation !== this.generation) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.resumeQueued = false;\n\t\t\tthis.pump(context, false);\n\t\t});\n\t}\n\n\tpause(context: SchedulerContext<C>): void {\n\t\tthis.scheduleContinuation(context);\n\t}\n\n\tprivate scheduleContinuation(context: SchedulerContext<C>): void {\n\t\tif(this.continuationTimer !== undefined || !context.paused || !this.dispatchAllowed(context)\n\t\t\t|| !Array.from(this.running.values()).some(node => this.isSliced(node))) {\n\t\t\treturn;\n\t\t}\n\t\tconst generation = this.generation;\n\t\t// Yield between slices so draining cannot starve worker replies or lifecycle calls.\n\t\tthis.continuationTimer = setTimeout(() => {\n\t\t\tif(generation !== this.generation) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.continuationTimer = undefined;\n\t\t\tif(context.paused) {\n\t\t\t\tthis.pump(context, 'sliced');\n\t\t\t}\n\t\t}, 0);\n\t}\n\n\tprivate isSliced(node: ScheduledUpdate<C>): boolean {\n\t\treturn node.system instanceof IterableSystem && node.system.remainingInstancesToRun.length > 0;\n\t}\n\n\treset(): void {\n\t\tif(this.continuationTimer !== undefined) {\n\t\t\tclearTimeout(this.continuationTimer);\n\t\t\tthis.continuationTimer = undefined;\n\t\t}\n\t\tconst effects = Array.from(this.publications, node => node.effects!);\n\t\tthis.publications.clear();\n\t\tthis.publicationReady = [];\n\t\tthis.nodes.clear();\n\t\tthis.tails.clear();\n\t\tthis.frontiers.clear();\n\t\tthis.creators.clear();\n\t\tthis.creationReaders.clear();\n\t\tthis.exclusiveTail = undefined;\n\t\tthis.running.clear();\n\t\tthis.ready = [];\n\t\tthis.readyIndex = 0;\n\t\tthis.gameTime = 0;\n\t\tthis.resumeQueued = false;\n\t\tthis.generation++;\n\t\teffects.forEach(effect => effect.discard());\n\t}\n\n\tbeforeClear(): void {\n\t\tthis.reset();\n\t}\n\n\tprepareEffects(context: SchedulerContext<C>, system: System<C>): (effects: SchedulerEffects) => void {\n\t\tconst node = this.running.get(system);\n\t\tconst generation = this.generation;\n\t\treturn effects => {\n\t\t\tif(!node || generation !== this.generation || !this.nodes.has(node)) {\n\t\t\t\teffects.discard();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnode.effects = effects;\n\t\t\tthis.publications.add(node);\n\t\t\tif(node.publicationDependencies === 0) {\n\t\t\t\tthis.publicationReady.push(node);\n\t\t\t}\n\t\t\tthis.publish();\n\t\t};\n\t}\n\n\tprivate publish(): void {\n\t\tif(this.publishing) {\n\t\t\treturn;\n\t\t}\n\t\tthis.publishing = true;\n\t\tconst generation = this.generation;\n\t\ttry {\n\t\t\twhile(this.publicationReady.length && generation === this.generation) {\n\t\t\t\tconst node = this.publicationReady.pop()!;\n\t\t\t\tthis.publications.delete(node);\n\t\t\t\tconst effects = node.effects!;\n\t\t\t\tnode.effects = undefined;\n\t\t\t\teffects.apply();\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.publishing = false;\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.reset();\n\t}\n\n\tprivate refreshMembership(context: SchedulerContext<C>): void {\n\t\tif(context.systems.length !== this.registeredSystems.length\n\t\t\t|| context.systems.some((system, i) => system !== this.registeredSystems[i])) {\n\t\t\tthis.rebuild(context);\n\t\t}\n\t}\n\n\tprivate pump(context: SchedulerContext<C>, continueRuns: boolean | 'sliced'): SchedulerUpdateResult {\n\t\tthis.pumping = true;\n\t\tlet lastSystemError: Error | null = null;\n\t\tconst generation = this.generation;\n\t\ttry {\n\t\t\tif(continueRuns) {\n\t\t\t\tfor(const node of Array.from(this.running.values())) {\n\t\t\t\t\tif(!node.system.isCurrentlyRunning() || (continueRuns === 'sliced' && !this.isSliced(node))) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif(!this.prepare(context)) {\n\t\t\t\t\t\treturn { lastSystemError };\n\t\t\t\t\t}\n\t\t\t\t\tconst result = this.dispatch(context, node, true);\n\t\t\t\t\tlastSystemError = result?.lastSystemError ?? lastSystemError;\n\t\t\t\t\tif(!result || generation !== this.generation) {\n\t\t\t\t\t\treturn { lastSystemError };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile(this.readyIndex < this.ready.length && generation === this.generation) {\n\t\t\t\tif(!this.prepare(context)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst node = this.ready[this.readyIndex++];\n\t\t\t\tconst result = this.dispatch(context, node, false);\n\t\t\t\tlastSystemError = result?.lastSystemError ?? lastSystemError;\n\t\t\t\tif(!result) {\n\t\t\t\t\tif(this.nodes.has(node) && node.state === 'pending') {\n\t\t\t\t\t\tthis.ready.push(node);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.ready = this.ready.slice(this.readyIndex);\n\t\t\tthis.readyIndex = 0;\n\t\t\tthis.pumping = false;\n\t\t\tthis.scheduleContinuation(context);\n\t\t}\n\t\treturn { lastSystemError };\n\t}\n\n\tprivate enqueue(system: System<C>, access: SystemAccess, elapsedTime: number, gameTime: number): void {\n\t\tconst node: ScheduledUpdate<C> = {\n\t\t\tsystem, access, elapsedTime, gameTime, state: 'pending', dependencies: 0, dependents: [],\n\t\t\tpublicationDependencies: 0, publicationDependents: [],\n\t\t};\n\t\tconst dependencies = new Set<ScheduledUpdate<C>>();\n\t\tconst publicationDependencies = new Set<ScheduledUpdate<C>>();\n\t\tconst dependOn = (previous: ScheduledUpdate<C> | undefined) => {\n\t\t\tif(previous && previous.state !== 'complete') {\n\t\t\t\tdependencies.add(previous);\n\t\t\t}\n\t\t};\n\t\tdependOn(this.tails.get(system));\n\t\tdependOn(this.exclusiveTail);\n\t\tif(access.exclusive) {\n\t\t\tthis.tails.forEach(dependOn);\n\t\t\tthis.exclusiveTail = node;\n\t\t} else {\n\t\t\tconst publishAfter = (previous: ScheduledUpdate<C> | undefined) => {\n\t\t\t\tif(previous && previous.state !== 'complete') {\n\t\t\t\t\tpublicationDependencies.add(previous);\n\t\t\t\t}\n\t\t\t};\n\t\t\tfor(const component of access.creates) {\n\t\t\t\tconst frontier = this.frontier(component);\n\t\t\t\tpublishAfter(frontier.writer);\n\t\t\t\tpublishAfter(frontier.creator);\n\t\t\t}\n\t\t\tif(access.creates.size) {\n\t\t\t\tfor(const reader of this.creationReaders.values()) {\n\t\t\t\t\tif(this.observesCreation(access, reader.access)) {\n\t\t\t\t\t\tpublishAfter(reader);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor(const component of access.reads) {\n\t\t\t\tif(!access.writes.has(component)) {\n\t\t\t\t\tconst frontier = this.frontier(component);\n\t\t\t\t\tdependOn(frontier.writer);\n\t\t\t\t\tfrontier.readers.set(system, node);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor(const creator of this.creators.values()) {\n\t\t\t\tif(this.observesCreation(creator.access, access)) {\n\t\t\t\t\tdependOn(creator);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(access.creationReads.size || access.creationQueries?.length) {\n\t\t\t\tthis.creationReaders.set(access, node);\n\t\t\t}\n\t\t\tfor(const component of access.writes) {\n\t\t\t\tconst frontier = this.frontier(component);\n\t\t\t\tdependOn(frontier.writer);\n\t\t\t\tdependOn(frontier.creator);\n\t\t\t\tfrontier.readers.forEach(dependOn);\n\t\t\t\tfrontier.readers.clear();\n\t\t\t\tfrontier.writer = node;\n\t\t\t}\n\t\t\tfor(const component of access.creates) {\n\t\t\t\tthis.frontier(component).creator = node;\n\t\t\t}\n\t\t\tif(access.creates.size) {\n\t\t\t\t// Keep distinct creation bounds so an unrelated later creator cannot hide a matching one.\n\t\t\t\tthis.creators.set(access, node);\n\t\t\t}\n\t\t}\n\t\tfor(const dependency of dependencies) {\n\t\t\tdependency.dependents.push(node);\n\t\t}\n\t\tnode.dependencies = dependencies.size;\n\t\tfor(const dependency of publicationDependencies) {\n\t\t\tdependency.publicationDependents.push(node);\n\t\t}\n\t\tnode.publicationDependencies = publicationDependencies.size;\n\t\tthis.nodes.add(node);\n\t\tthis.tails.set(system, node);\n\t\tif(!node.dependencies) {\n\t\t\tthis.ready.push(node);\n\t\t}\n\t}\n\n\tprivate frontier(component: PropertyKey): ComponentFrontier<C> {\n\t\tlet frontier = this.frontiers.get(component);\n\t\tif(!frontier) {\n\t\t\tfrontier = { readers: new Map() };\n\t\t\tthis.frontiers.set(component, frontier);\n\t\t}\n\t\treturn frontier;\n\t}\n\n\tprivate complete(node: ScheduledUpdate<C>): void {\n\t\tif(node.state === 'complete') {\n\t\t\treturn;\n\t\t}\n\t\tnode.state = 'complete';\n\t\tthis.nodes.delete(node);\n\t\tthis.running.delete(node.system);\n\t\tif(this.tails.get(node.system) === node) {\n\t\t\tthis.tails.delete(node.system);\n\t\t}\n\t\tif(this.exclusiveTail === node) {\n\t\t\tthis.exclusiveTail = undefined;\n\t\t}\n\t\tif(this.creators.get(node.access) === node) {\n\t\t\tthis.creators.delete(node.access);\n\t\t}\n\t\tif(this.creationReaders.get(node.access) === node) {\n\t\t\tthis.creationReaders.delete(node.access);\n\t\t}\n\t\tfor(const component of new Set([...node.access.reads, ...node.access.writes, ...node.access.creates])) {\n\t\t\tconst frontier = this.frontiers.get(component);\n\t\t\tif(frontier?.writer === node) {\n\t\t\t\tfrontier.writer = undefined;\n\t\t\t}\n\t\t\tif(frontier?.creator === node) {\n\t\t\t\tfrontier.creator = undefined;\n\t\t\t}\n\t\t\tif(frontier?.readers.get(node.system) === node) {\n\t\t\t\tfrontier.readers.delete(node.system);\n\t\t\t}\n\t\t\tif(frontier && !frontier.writer && !frontier.creator && !frontier.readers.size) {\n\t\t\t\tthis.frontiers.delete(component);\n\t\t\t}\n\t\t}\n\t\tfor(const dependent of node.dependents) {\n\t\t\tif(--dependent.dependencies === 0) {\n\t\t\t\tthis.ready.push(dependent);\n\t\t\t}\n\t\t}\n\t\tnode.dependents.length = 0;\n\t\tfor(const dependent of node.publicationDependents) {\n\t\t\tdependent.publicationDependencies--;\n\t\t\tif(dependent.publicationDependencies === 0 && dependent.effects) {\n\t\t\t\tthis.publicationReady.push(dependent);\n\t\t\t}\n\t\t}\n\t\tnode.publicationDependents.length = 0;\n\t\tthis.publish();\n\t}\n\n\tprivate dispatch(context: SchedulerContext<C>, node: ScheduledUpdate<C>, continuation: boolean): SchedulerUpdateResult | undefined {\n\t\tconst system = node.system;\n\t\tif(!continuation && !context.systems.includes(system)) {\n\t\t\tthis.complete(node);\n\t\t\treturn {};\n\t\t}\n\t\tconst generation = this.generation;\n\t\tlet shouldRun = true;\n\t\tlet ran = false;\n\t\tlet failed = false;\n\t\tlet lastSystemError: Error | null = null;\n\t\tcontext.emit(`system-${system.name}-started`);\n\t\tif(!this.nodes.has(node) || !this.dispatchAllowed(context)) {\n\t\t\treturn undefined;\n\t\t}\n\t\ttry {\n\t\t\tconst dispatched = system.withGameTime(node.gameTime, () => {\n\t\t\t\tshouldRun = continuation || system.shouldRun();\n\t\t\t\tif(!this.nodes.has(node) || !this.dispatchAllowed(context)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif(shouldRun) {\n\t\t\t\t\tnode.state = 'running';\n\t\t\t\t\tthis.running.set(system, node);\n\t\t\t\t\tran = system.update(continuation ? 0 : node.elapsedTime);\n\t\t\t\t\tif(generation === this.generation && !system.isCurrentlyRunning()) {\n\t\t\t\t\t\tthis.complete(node);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.complete(node);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\t\tif(!dispatched) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t} catch(e) {\n\t\t\tconst error = e as Error;\n\t\t\tconsole.error(error.message, error);\n\t\t\tfailed = true;\n\t\t\tlastSystemError = error;\n\t\t\tif(generation === this.generation) {\n\t\t\t\tif(system.isCurrentlyRunning()) {\n\t\t\t\t\tnode.state = 'running';\n\t\t\t\t\tthis.running.set(system, node);\n\t\t\t\t} else {\n\t\t\t\t\tthis.complete(node);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.emit('system-error', { system: system.name, error, phase: 'run' });\n\t\t}\n\t\tcontext.emit(`system-${system.name}-finished`, { ran, shouldRun, failed });\n\t\treturn { lastSystemError };\n\t}\n\n\tprivate prepare(context: SchedulerContext<C>): boolean {\n\t\treturn this.dispatchAllowed(context) && context.prepareForSystemDispatch?.() !== false;\n\t}\n\n\tprivate dispatchAllowed(context: SchedulerContext<C>): boolean {\n\t\treturn context.dispatchAllowed !== false;\n\t}\n\tprivate observesCreation(creator: SystemAccess, reader: SystemAccess): boolean {\n\t\tfor(const component of reader.creationReads) {\n\t\t\tif(creator.creates.has(component)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn reader.creationQueries?.some(query => query.every(component => creator.creates.has(component))) ?? false;\n\t}\n\n\tprivate conflicts(a: SystemAccess, b: SystemAccess): boolean {\n\t\tif(a.exclusive || b.exclusive) {\n\t\t\treturn true;\n\t\t}\n\t\tfor(const component of a.writes) {\n\t\t\tif(b.reads.has(component) || b.writes.has(component)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tfor(const component of b.writes) {\n\t\t\tif(a.reads.has(component)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tfor(const component of a.creates) {\n\t\t\tif(b.writes.has(component)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn a.creates.size > 0 && this.observesCreation(a, b);\n\t}\n}\n","import type { ComponentDefinitionMap, EntityConfigOf } from './component-definition';\n\nexport type EntityClassConstructor = abstract new (...args: never[]) => { readonly eid: number };\n\nexport interface EntityClassDefinition {\n\tentity: EntityClassConstructor\n\tcomponents: ReadonlyArray<string>\n}\n\nexport type EntityClassRegistry = Record<string, EntityClassDefinition>;\n\ndeclare const ENTITY_CLASSES_TYPE: unique symbol;\n\nexport type DefinedEntityClasses<\n\tR extends ComponentDefinitionMap,\n\tClasses extends EntityClassRegistry,\n> = Classes & { readonly [ENTITY_CLASSES_TYPE]: R };\n\nexport type EntityInstancesOf<Classes extends EntityClassRegistry> = InstanceType<Classes[keyof Classes & string]['entity']>;\n\ntype RegistryOf<Classes extends EntityClassRegistry> = Classes extends DefinedEntityClasses<infer R, EntityClassRegistry> ? R : never;\ntype ComponentKeysOf<Definition> = Definition extends { components: ReadonlyArray<infer K> } ? K : never;\n\nexport type EntityClassTemplateConfig<\n\tClasses extends EntityClassRegistry,\n\tClassName extends keyof Classes & string,\n\tR extends ComponentDefinitionMap = RegistryOf<Classes>,\n> = EntityConfigOf<Pick<R, Extract<ComponentKeysOf<Classes[ClassName]>, keyof R>>> & {\n\ttype: string\n\tclass: ClassName\n};\n\nexport type EntityTemplateConfigOf<Classes extends EntityClassRegistry> = {\n\t[ClassName in keyof Classes & string]: EntityClassTemplateConfig<Classes, ClassName>\n}[keyof Classes & string];\n\nexport type EntityInstanceConfigOf<Classes extends EntityClassRegistry> = EntityTemplateConfigOf<Classes> extends infer Config\n\t? Config extends object ? Omit<Config, 'class'> & { class?: never } : never\n\t: never;\n\ntype EntityClassInput<R extends ComponentDefinitionMap> = Record<string, {\n\tentity: EntityClassConstructor\n\tcomponents: ReadonlyArray<keyof R & string>\n}>;\n\ntype ExactEntityConfig<Classes extends EntityClassRegistry, ClassName extends keyof Classes & string, Type, Config> = Config\n\t& EntityClassTemplateConfig<Classes, ClassName>\n\t& { type: Type }\n\t& Record<Exclude<keyof Config, keyof EntityClassTemplateConfig<Classes, ClassName>>, never>;\n\ntype CheckedEntityConfig<Classes extends EntityClassRegistry, Type, Config> =\n\tConfig extends { class: infer ClassName }\n\t\t? ClassName extends keyof Classes & string\n\t\t\t? ExactEntityConfig<Classes, ClassName, Type, Config>\n\t\t\t: never\n\t\t: never;\n\ntype CheckedEntityConfigs<Classes extends EntityClassRegistry, Configs> = {\n\t[K in keyof Configs]: CheckedEntityConfig<Classes, K, Configs[K]>\n};\n\nexport function defineEntityClasses<\n\tR extends ComponentDefinitionMap,\n\tconst Classes extends EntityClassInput<R>,\n>(_registry: R, classes: Classes): DefinedEntityClasses<R, Classes> {\n\treturn classes as DefinedEntityClasses<R, Classes>;\n}\n\nexport function defineEntityConfigs<\n\tClasses extends EntityClassRegistry,\n\tconst Configs extends Record<string, { type: string, class: keyof Classes & string }>,\n>(_classes: Classes, configs: Configs & CheckedEntityConfigs<Classes, Configs>): Configs {\n\treturn configs;\n}\n\nexport interface WorkerEntityClassDefinition {\n\tcomponents: Array<string>\n}\n\nexport type WorkerEntityClassRegistry = Record<string, WorkerEntityClassDefinition>;\n","import type BaseEntity from '../entity';\n\n// Flags the entity dead in shared memory and emits `death`; BaseWorld listens for it to remove the entity.\nexport default function killEntity(entity: BaseEntity): void {\n\tentity.components.entity.dead = true;\n\tentity.emit('death');\n}\n","import { EventEmitter } from 'eventemitter3';\nimport type BaseWorld from './world';\nimport type { ComponentDefinitionMap, ComponentMap } from './component-definition';\nimport type System from './systems/system';\nimport type { EntityWorkBatch } from './systems/workers/entity-system-worker-message';\n\nexport const DEFAULT_TICKS_BETWEEN_UPDATES = 1_000;\n\nexport interface TimingStats {\n\tavg: number\n\tmin: number\n\tmax: number\n\tsamples: number\n}\n\nexport interface SystemTimingStats {\n\tname: string\n\trun: TimingStats\n\tevents: TimingStats\n}\n\nexport interface PerformanceStats {\n\tupdate: TimingStats\n\tsystems: Array<SystemTimingStats>\n\tevents: TimingStats\n}\n\nexport interface PerformanceTimingOptions {\n\tticksBetweenUpdates?: number\n\tautoUpdate?: boolean\n}\n\ninterface SystemTiming {\n\trun: Array<number>\n\tevents: Array<number>\n\tpendingRun: number\n\tpendingEvents: number\n\t// -1 when no run is being dispatched.\n\teventStart: number\n\tonRunFinished: (runTime: number, batch?: Pick<EntityWorkBatch, 'first' | 'last'>) => void\n\tonEventsFinished: (runTime: number, batch?: Pick<EntityWorkBatch, 'first' | 'last'>) => void\n}\n\nconst EMPTY_TIMING: TimingStats = { avg: 0, min: 0, max: 0, samples: 0 };\n\n// An empty window reads as zeroes (not an infinite min) so a snapshot is always safe to render.\nfunction summarize(samples: Array<number>): TimingStats {\n\tif(!samples.length) {\n\t\treturn { ...EMPTY_TIMING };\n\t}\n\n\tlet total = 0;\n\tlet min = Infinity;\n\tlet max = 0;\n\tfor(let sample of samples) {\n\t\ttotal += sample;\n\t\tif(sample < min) {\n\t\t\tmin = sample;\n\t\t}\n\t\tif(sample > max) {\n\t\t\tmax = sample;\n\t\t}\n\t}\n\n\treturn {\n\t\tavg: total / samples.length,\n\t\tmin,\n\t\tmax,\n\t\tsamples: samples.length,\n\t};\n}\n\n// Watches a world and reports what it costs to run, driven off events the world emits. Emits `stats-updated`\n// every `ticksBetweenUpdates`; paused frames are skipped.\nexport default class PerformanceTiming<C extends ComponentMap = ComponentMap> extends EventEmitter {\n\tworld: BaseWorld<ComponentDefinitionMap, C>;\n\tticksBetweenUpdates: number;\n\tstats: PerformanceStats = {\n\t\tupdate: { ...EMPTY_TIMING },\n\t\tsystems: [],\n\t\tevents: { ...EMPTY_TIMING },\n\t};\n\n\tprivate readonly autoUpdate: boolean;\n\tprivate ticks = 0;\n\tprivate updateStart = 0;\n\tprivate updateTimes: Array<number> = [];\n\tprivate systemTimings = new Map<string, SystemTiming>();\n\tprivate destroyed = false;\n\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: PerformanceTimingOptions = {}) {\n\t\tsuper();\n\n\t\tthis.world = world;\n\t\tthis.autoUpdate = options.autoUpdate ?? true;\n\t\tthis.ticksBetweenUpdates = options.ticksBetweenUpdates ?? DEFAULT_TICKS_BETWEEN_UPDATES;\n\n\t\tworld.on('update-started', this.onUpdateStarted);\n\t\tworld.on('update-finished', this.onUpdateFinished);\n\t\tworld.on('system-added', this.onSystemAdded);\n\t\tworld.on('system-removed', this.onSystemRemoved);\n\t\tworld.systems.forEach(system => this.trackSystem(system));\n\t}\n\n\tgetSystemStats(name: string): SystemTimingStats | undefined {\n\t\treturn this.stats.systems.find(system => system.name === name);\n\t}\n\n\treset() {\n\t\tthis.ticks = 0;\n\t\tthis.updateTimes = [];\n\t\tthis.systemTimings.forEach(timing => {\n\t\t\ttiming.run = [];\n\t\t\ttiming.events = [];\n\t\t\ttiming.eventStart = -1;\n\t\t\ttiming.pendingRun = 0;\n\t\t\ttiming.pendingEvents = 0;\n\t\t});\n\t\tthis.stats = {\n\t\t\tupdate: { ...EMPTY_TIMING },\n\t\t\tsystems: [],\n\t\t\tevents: { ...EMPTY_TIMING },\n\t\t};\n\t}\n\n\tdestroy() {\n\t\tif(this.destroyed) {\n\t\t\treturn;\n\t\t}\n\t\tthis.destroyed = true;\n\n\t\tthis.world.off('update-started', this.onUpdateStarted);\n\t\tthis.world.off('update-finished', this.onUpdateFinished);\n\t\tthis.world.off('system-added', this.onSystemAdded);\n\t\tthis.world.off('system-removed', this.onSystemRemoved);\n\t\tArray.from(this.systemTimings.keys()).forEach(name => this.untrackSystem(name));\n\t\tthis.removeAllListeners();\n\t}\n\n\tprivate onUpdateStarted = () => {\n\t\tthis.updateStart = performance.now();\n\t};\n\n\tprivate onUpdateFinished = (elapsedTime: number) => {\n\t\tif(this.world.paused) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateTimes.push(performance.now() - this.updateStart);\n\n\t\tthis.ticks += elapsedTime;\n\t\tif(this.autoUpdate && this.ticks >= this.ticksBetweenUpdates) {\n\t\t\tthis.flush();\n\t\t}\n\t};\n\n\tprivate onSystemAdded = (system: System<C>) => {\n\t\tthis.trackSystem(system);\n\t};\n\n\tprivate onSystemRemoved = (system: System<C>) => {\n\t\tthis.untrackSystem(system.name);\n\t};\n\n\t// The gap between `-worker-finished` (before events dispatch) and `-worker-events-finished` (after) is what\n\t// that run cost this thread. Both fire for the main-thread fallback too.\n\tprivate trackSystem(system: System<C>) {\n\t\tif(this.systemTimings.has(system.name)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst timing: SystemTiming = {\n\t\t\trun: [],\n\t\t\tevents: [],\n\t\t\teventStart: -1,\n\t\t\tpendingRun: 0,\n\t\t\tpendingEvents: 0,\n\t\t\tonRunFinished: (runTime, batch) => {\n\t\t\t\tif(!batch || batch.first) {\n\t\t\t\t\ttiming.pendingRun = 0;\n\t\t\t\t\ttiming.pendingEvents = 0;\n\t\t\t\t}\n\t\t\t\ttiming.pendingRun += runTime;\n\t\t\t\tif(!batch || batch.last) {\n\t\t\t\t\ttiming.run.push(timing.pendingRun);\n\t\t\t\t\ttiming.pendingRun = 0;\n\t\t\t\t}\n\t\t\t\ttiming.eventStart = performance.now();\n\t\t\t},\n\t\t\tonEventsFinished: (_runTime, batch) => {\n\t\t\t\tif(timing.eventStart < 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttiming.pendingEvents += performance.now() - timing.eventStart;\n\t\t\t\tif(!batch || batch.last) {\n\t\t\t\t\ttiming.events.push(timing.pendingEvents);\n\t\t\t\t\ttiming.pendingEvents = 0;\n\t\t\t\t}\n\t\t\t\ttiming.eventStart = -1;\n\t\t\t},\n\t\t};\n\n\t\tthis.world.on(`system-${system.name}-worker-finished`, timing.onRunFinished);\n\t\tthis.world.on(`system-${system.name}-worker-events-finished`, timing.onEventsFinished);\n\t\tthis.systemTimings.set(system.name, timing);\n\t}\n\n\tprivate untrackSystem(name: string) {\n\t\tconst timing = this.systemTimings.get(name);\n\t\tif(!timing) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.world.off(`system-${name}-worker-finished`, timing.onRunFinished);\n\t\tthis.world.off(`system-${name}-worker-events-finished`, timing.onEventsFinished);\n\t\tthis.systemTimings.delete(name);\n\t}\n\n\tflush(): PerformanceStats {\n\t\tif(this.destroyed) {\n\t\t\treturn this.stats;\n\t\t}\n\n\t\tconst systems = this.world.systems.map(system => {\n\t\t\tconst timing = this.systemTimings.get(system.name);\n\t\t\treturn {\n\t\t\t\tname: system.name,\n\t\t\t\trun: summarize(timing?.run ?? []),\n\t\t\t\tevents: summarize(timing?.events ?? []),\n\t\t\t};\n\t\t});\n\n\t\tconst events: TimingStats = { ...EMPTY_TIMING };\n\t\tsystems.forEach(system => {\n\t\t\tevents.avg += system.events.avg;\n\t\t\tevents.min += system.events.min;\n\t\t\tevents.max += system.events.max;\n\t\t\tevents.samples += system.events.samples;\n\t\t});\n\n\t\tthis.stats = {\n\t\t\tupdate: summarize(this.updateTimes),\n\t\t\tsystems,\n\t\t\tevents,\n\t\t};\n\n\t\tthis.ticks = 0;\n\t\tthis.updateTimes = [];\n\t\tthis.systemTimings.forEach(timing => {\n\t\t\ttiming.run = [];\n\t\t\ttiming.events = [];\n\t\t});\n\n\t\tthis.emit('stats-updated', this.stats);\n\t\treturn this.stats;\n\t}\n}\n","import type BaseWorld from '../world';\nimport type { ComponentDefinitionMap, ComponentMap } from '../component-definition';\nimport type { SystemConfig } from './system';\nimport EntityWorkerSystem, {\n\ttype EntityWorkerSystemQuery, type EntityWorkerSystemWorld, type EntityUpdateComponents,\n} from './entity-worker-system';\nimport { toEntityUpdateFunction, type WorkerSystemInitFunction, type WorkerSystemRunFunction } from './workers/create-system-worker';\n\n// An EntityWorkerSystem that runs its update function once per tick instead of once per entity. It accepts the same\n// named `queries` (so it can count/scan other entities), runs on its own worker, can create entities off-thread, and\n// receives fresh per-run data via addDataToWorld — all reusing the EntityWorkerSystem machinery. It has no main query:\n// all work happens in the single run function over the named sub-queries.\nexport default class WorkerSystem<\n\tC extends ComponentMap,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> extends EntityWorkerSystem<C, EntityUpdateComponents<C>, W, D> {\n\tconstructor(world: BaseWorld<ComponentDefinitionMap, C>, options: WorkerSystemConfig<C, W, D>) {\n\t\tsuper(world, {\n\t\t\t...options,\n\t\t\t// No main query: the run function works entirely over the named sub-queries.\n\t\t\trequired: [],\n\t\t\tupdateFunction: toEntityUpdateFunction(options.updateFunction),\n\t\t});\n\t}\n\n\t// Sub-query membership is maintained as usual so the run function still sees it.\n\tprotected get tracksMainQuery(): boolean {\n\t\treturn false;\n\t}\n\n\t// Runs every interval regardless of membership, since its work is the single run function over sub-queries.\n\tshouldRun(): boolean {\n\t\treturn true;\n\t}\n}\n\nexport interface WorkerSystemConfig<\n\tC extends ComponentMap,\n\tW extends EntityWorkerSystemWorld = EntityWorkerSystemWorld,\n\tD = unknown,\n> extends SystemConfig<C> {\n\tupdateFunction: WorkerSystemRunFunction<C, W, D>\n\tgetWorker: () => Worker\n\tforceMainThread?: boolean\n\tgetInitData?: () => D\n\tcreatesEntities?: boolean | ReadonlyArray<keyof C>\n\tqueries?: { [key: string]: EntityWorkerSystemQuery<C> }\n}\n\nexport type { WorkerSystemInitFunction, WorkerSystemRunFunction };\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|
package/dist/world.d.ts
CHANGED
|
@@ -69,6 +69,7 @@ export default class BaseWorld<R extends ComponentDefinitionMap = ComponentDefin
|
|
|
69
69
|
getEntityByEid(eid: number): E | undefined;
|
|
70
70
|
deferComponentMemoryFree(memoryComponent: MemoryComponent, index: number, free?: () => void): void;
|
|
71
71
|
notifySystemRunCompleted(system: System<C>): void;
|
|
72
|
+
notifyAbandonedRunFinished(system: System<C>): void;
|
|
72
73
|
private processFreeBuffers;
|
|
73
74
|
private promoteNextFreeBuffer;
|
|
74
75
|
private consolidateFreeBuffersForReload;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@daneren2005/shared-memory-ecs",
|
|
3
3
|
"description": "A small, reusable Entity/Component/System core backed by shared memory.",
|
|
4
4
|
"author": "Scott Jackson",
|
|
5
|
-
"version": "1.10.
|
|
5
|
+
"version": "1.10.3",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"license": "MIT",
|