koota 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -3
- package/dist/{chunk-4QEK6BHY.js → chunk-G375UJC5.js} +295 -288
- package/dist/index.cjs +267 -258
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1 -1
- package/dist/react.cjs +256 -259
- package/dist/react.d.cts +2 -4
- package/dist/react.d.ts +2 -4
- package/dist/react.js +7 -14
- package/dist/{world-DQXl4lI8.d.cts → world-BFj5O4_U.d.cts} +14 -3
- package/dist/{world-DQXl4lI8.d.ts → world-BFj5O4_U.d.ts} +14 -3
- package/package.json +3 -3
- package/react/index.cjs +256 -259
- package/react/index.d.cts +2 -4
- package/react/index.d.ts +2 -4
- package/react/index.js +7 -14
package/dist/index.cjs
CHANGED
|
@@ -3,10 +3,6 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __typeError = (msg) => {
|
|
7
|
-
throw TypeError(msg);
|
|
8
|
-
};
|
|
9
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
6
|
var __export = (target, all) => {
|
|
11
7
|
for (var name in all)
|
|
12
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -20,19 +16,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
20
16
|
return to;
|
|
21
17
|
};
|
|
22
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
24
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
25
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
26
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
27
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
28
|
-
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
29
|
-
set _(value) {
|
|
30
|
-
__privateSet(obj, member, value, setter);
|
|
31
|
-
},
|
|
32
|
-
get _() {
|
|
33
|
-
return __privateGet(obj, member, getter);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
19
|
|
|
37
20
|
// src/index.ts
|
|
38
21
|
var index_exports = {};
|
|
@@ -75,6 +58,110 @@ var getEntityGeneration = (entity) => entity >>> GENERATION_SHIFT & GENERATION_M
|
|
|
75
58
|
var incrementGeneration = (entity) => entity & ~(GENERATION_MASK << GENERATION_SHIFT) | // Clear current generation bits
|
|
76
59
|
((entity >>> GENERATION_SHIFT & GENERATION_MASK) + 1 & GENERATION_MASK) << GENERATION_SHIFT;
|
|
77
60
|
|
|
61
|
+
// ../core/src/world/utils/world-index.ts
|
|
62
|
+
function createWorldIndex() {
|
|
63
|
+
return {
|
|
64
|
+
worldCursor: 0,
|
|
65
|
+
releasedWorldIds: [],
|
|
66
|
+
maxWorlds: 2 ** WORLD_ID_BITS
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function allocateWorldId(index) {
|
|
70
|
+
if (index.releasedWorldIds.length > 0) {
|
|
71
|
+
return index.releasedWorldIds.pop();
|
|
72
|
+
}
|
|
73
|
+
if (index.worldCursor >= index.maxWorlds) {
|
|
74
|
+
throw new Error(`Koota: Too many worlds created. The maximum is ${index.maxWorlds}.`);
|
|
75
|
+
}
|
|
76
|
+
return index.worldCursor++;
|
|
77
|
+
}
|
|
78
|
+
function releaseWorldId(index, worldId) {
|
|
79
|
+
if (worldId < 0 || worldId >= index.maxWorlds) {
|
|
80
|
+
throw new Error(`Invalid world ID: ${worldId}`);
|
|
81
|
+
}
|
|
82
|
+
if (worldId === index.worldCursor - 1) {
|
|
83
|
+
index.worldCursor--;
|
|
84
|
+
} else if (worldId < index.worldCursor && !index.releasedWorldIds.includes(worldId)) {
|
|
85
|
+
index.releasedWorldIds.push(worldId);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ../core/src/universe/universe.ts
|
|
90
|
+
var universe = {
|
|
91
|
+
worlds: new Array(WORLD_ID_BITS ** 2),
|
|
92
|
+
cachedQueries: /* @__PURE__ */ new Map(),
|
|
93
|
+
worldIndex: createWorldIndex(),
|
|
94
|
+
reset: () => {
|
|
95
|
+
universe.worlds = new Array(WORLD_ID_BITS ** 2).fill(null);
|
|
96
|
+
universe.cachedQueries = /* @__PURE__ */ new Map();
|
|
97
|
+
universe.worldIndex = createWorldIndex();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// ../core/src/query/modifier.ts
|
|
102
|
+
var ModifierData = class {
|
|
103
|
+
constructor(type, id, traits) {
|
|
104
|
+
this.type = type;
|
|
105
|
+
this.id = id;
|
|
106
|
+
this.traits = traits;
|
|
107
|
+
this.traitIds = traits.map((trait2) => trait2[$internal].id);
|
|
108
|
+
}
|
|
109
|
+
traitIds;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// ../core/src/query/utils/tracking-cursor.ts
|
|
113
|
+
var cursor = 3;
|
|
114
|
+
function createTrackingId() {
|
|
115
|
+
return cursor++;
|
|
116
|
+
}
|
|
117
|
+
function getTrackingCursor() {
|
|
118
|
+
return cursor;
|
|
119
|
+
}
|
|
120
|
+
function setTrackingMasks(world, id) {
|
|
121
|
+
const ctx = world[$internal];
|
|
122
|
+
const snapshot = structuredClone(ctx.entityMasks);
|
|
123
|
+
ctx.trackingSnapshots.set(id, snapshot);
|
|
124
|
+
ctx.dirtyMasks.set(
|
|
125
|
+
id,
|
|
126
|
+
snapshot.map((mask) => mask.map(() => 0))
|
|
127
|
+
);
|
|
128
|
+
ctx.changedMasks.set(
|
|
129
|
+
id,
|
|
130
|
+
snapshot.map((mask) => mask.map(() => 0))
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ../core/src/query/modifiers/changed.ts
|
|
135
|
+
function createChanged() {
|
|
136
|
+
const id = createTrackingId();
|
|
137
|
+
for (const world of universe.worlds) {
|
|
138
|
+
if (!world) continue;
|
|
139
|
+
setTrackingMasks(world.deref(), id);
|
|
140
|
+
}
|
|
141
|
+
return (...traits) => new ModifierData(`changed-${id}`, id, traits);
|
|
142
|
+
}
|
|
143
|
+
function setChanged(world, entity, trait2) {
|
|
144
|
+
const ctx = world[$internal];
|
|
145
|
+
if (!hasTrait(world, entity, trait2)) return;
|
|
146
|
+
if (!ctx.traitData.has(trait2)) registerTrait(world, trait2);
|
|
147
|
+
const data = ctx.traitData.get(trait2);
|
|
148
|
+
for (const changedMask of ctx.changedMasks.values()) {
|
|
149
|
+
const eid = getEntityId(entity);
|
|
150
|
+
if (!changedMask[eid]) changedMask[eid] = new Array();
|
|
151
|
+
const traitId2 = trait2[$internal].id;
|
|
152
|
+
changedMask[eid][traitId2] = 1;
|
|
153
|
+
}
|
|
154
|
+
for (const query of data.queries) {
|
|
155
|
+
if (!query.hasChangedModifiers) continue;
|
|
156
|
+
let match = query.check(world, entity, { type: "change", traitData: data });
|
|
157
|
+
if (match) query.add(entity);
|
|
158
|
+
else query.remove(world, entity);
|
|
159
|
+
}
|
|
160
|
+
for (const sub of data.changedSubscriptions) {
|
|
161
|
+
sub(entity);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
78
165
|
// ../core/src/relation/relation.ts
|
|
79
166
|
function defineRelation(definition) {
|
|
80
167
|
const pairsMap = /* @__PURE__ */ new Map();
|
|
@@ -112,8 +199,9 @@ function getRelationTrait(relation2, traitFactory, pairsMap, target) {
|
|
|
112
199
|
}
|
|
113
200
|
var getRelationTargets = (world, relation2, entity) => {
|
|
114
201
|
const ctx = world[$internal];
|
|
115
|
-
const traits = ctx.entityTraits.get(entity)
|
|
202
|
+
const traits = ctx.entityTraits.get(entity);
|
|
116
203
|
const targets = [];
|
|
204
|
+
if (!traits) return targets;
|
|
117
205
|
for (const trait2 of traits) {
|
|
118
206
|
const traitCtx = trait2[$internal];
|
|
119
207
|
if (traitCtx.relation === relation2 && traitCtx.pairTarget !== Wildcard) {
|
|
@@ -145,15 +233,15 @@ var incrementWorldBitflag = (world) => {
|
|
|
145
233
|
|
|
146
234
|
// ../core/src/trait/trait-data.ts
|
|
147
235
|
var TraitData = class {
|
|
236
|
+
generationId;
|
|
237
|
+
bitflag;
|
|
238
|
+
trait;
|
|
239
|
+
store;
|
|
240
|
+
queries;
|
|
241
|
+
notQueries;
|
|
242
|
+
schema;
|
|
243
|
+
changedSubscriptions;
|
|
148
244
|
constructor(world, trait2) {
|
|
149
|
-
__publicField(this, "generationId");
|
|
150
|
-
__publicField(this, "bitflag");
|
|
151
|
-
__publicField(this, "trait");
|
|
152
|
-
__publicField(this, "store");
|
|
153
|
-
__publicField(this, "queries");
|
|
154
|
-
__publicField(this, "notQueries");
|
|
155
|
-
__publicField(this, "schema");
|
|
156
|
-
__publicField(this, "changedSubscriptions");
|
|
157
245
|
const ctx = world[$internal];
|
|
158
246
|
const traitCtx = trait2[$internal];
|
|
159
247
|
this.generationId = ctx.entityMasks.length - 1;
|
|
@@ -322,7 +410,7 @@ function addTrait(world, entity, ...traits) {
|
|
|
322
410
|
} else {
|
|
323
411
|
trait2 = traits[i];
|
|
324
412
|
}
|
|
325
|
-
if (entity
|
|
413
|
+
if (hasTrait(world, entity, trait2)) return;
|
|
326
414
|
const traitCtx = trait2[$internal];
|
|
327
415
|
if (!ctx.traitData.has(trait2)) registerTrait(world, trait2);
|
|
328
416
|
const data = ctx.traitData.get(trait2);
|
|
@@ -344,8 +432,8 @@ function addTrait(world, entity, ...traits) {
|
|
|
344
432
|
const target = traitCtx.pairTarget;
|
|
345
433
|
if (traitCtx.isPairTrait && relation2 !== null && target !== null) {
|
|
346
434
|
ctx.relationTargetEntities.add(target);
|
|
347
|
-
entity
|
|
348
|
-
entity
|
|
435
|
+
addTrait(world, entity, Pair(Wildcard, target));
|
|
436
|
+
addTrait(world, entity, Pair(relation2, Wildcard));
|
|
349
437
|
if (relation2[$internal].exclusive === true && target !== Wildcard) {
|
|
350
438
|
const oldTarget = getRelationTargets(world, relation2, entity)[0];
|
|
351
439
|
if (oldTarget !== null && oldTarget !== void 0 && oldTarget !== target) {
|
|
@@ -362,10 +450,10 @@ function addTrait(world, entity, ...traits) {
|
|
|
362
450
|
defaults[key] = data.schema[key];
|
|
363
451
|
}
|
|
364
452
|
}
|
|
365
|
-
entity
|
|
453
|
+
setTrait(world, entity, trait2, { ...defaults, ...params }, false);
|
|
366
454
|
} else {
|
|
367
455
|
const state = params ?? data.schema();
|
|
368
|
-
entity
|
|
456
|
+
setTrait(world, entity, trait2, state, false);
|
|
369
457
|
}
|
|
370
458
|
}
|
|
371
459
|
}
|
|
@@ -374,7 +462,7 @@ function removeTrait(world, entity, ...traits) {
|
|
|
374
462
|
for (let i = 0; i < traits.length; i++) {
|
|
375
463
|
const trait2 = traits[i];
|
|
376
464
|
const traitCtx = trait2[$internal];
|
|
377
|
-
if (!entity
|
|
465
|
+
if (!hasTrait(world, entity, trait2)) return;
|
|
378
466
|
const data = ctx.traitData.get(trait2);
|
|
379
467
|
const { generationId, bitflag, queries } = data;
|
|
380
468
|
const eid = getEntityId(entity);
|
|
@@ -417,6 +505,25 @@ function getStore(world, trait2) {
|
|
|
417
505
|
const store = data.store;
|
|
418
506
|
return store;
|
|
419
507
|
}
|
|
508
|
+
function setTrait(world, entity, trait2, value, triggerChanged = true) {
|
|
509
|
+
const ctx = trait2[$internal];
|
|
510
|
+
const index = entity & ENTITY_ID_MASK;
|
|
511
|
+
const store = getStore(world, trait2);
|
|
512
|
+
value instanceof Function && (value = value(ctx.get(index, store)));
|
|
513
|
+
ctx.set(index, store, value);
|
|
514
|
+
triggerChanged && setChanged(world, entity, trait2);
|
|
515
|
+
}
|
|
516
|
+
function getTrait(world, entity, trait2) {
|
|
517
|
+
const worldCtx = world[$internal];
|
|
518
|
+
const data = worldCtx.traitData.get(trait2);
|
|
519
|
+
if (!data) return void 0;
|
|
520
|
+
const index = getEntityId(entity);
|
|
521
|
+
const mask = worldCtx.entityMasks[data.generationId][index];
|
|
522
|
+
if ((mask & data.bitflag) !== data.bitflag) return void 0;
|
|
523
|
+
const traitCtx = trait2[$internal];
|
|
524
|
+
const store = getStore(world, trait2);
|
|
525
|
+
return traitCtx.get(index, store);
|
|
526
|
+
}
|
|
420
527
|
|
|
421
528
|
// ../core/src/entity/utils/entity-index.ts
|
|
422
529
|
var createEntityIndex = (worldId) => ({
|
|
@@ -464,172 +571,61 @@ var getAliveEntities = (index) => {
|
|
|
464
571
|
return index.dense.slice(0, index.aliveCount);
|
|
465
572
|
};
|
|
466
573
|
|
|
467
|
-
// ../core/src/world/utils/world-index.ts
|
|
468
|
-
function createWorldIndex() {
|
|
469
|
-
return {
|
|
470
|
-
worldCursor: 0,
|
|
471
|
-
releasedWorldIds: [],
|
|
472
|
-
maxWorlds: 2 ** WORLD_ID_BITS
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
function allocateWorldId(index) {
|
|
476
|
-
if (index.releasedWorldIds.length > 0) {
|
|
477
|
-
return index.releasedWorldIds.pop();
|
|
478
|
-
}
|
|
479
|
-
if (index.worldCursor >= index.maxWorlds) {
|
|
480
|
-
throw new Error(`Koota: Too many worlds created. The maximum is ${index.maxWorlds}.`);
|
|
481
|
-
}
|
|
482
|
-
return index.worldCursor++;
|
|
483
|
-
}
|
|
484
|
-
function releaseWorldId(index, worldId) {
|
|
485
|
-
if (worldId < 0 || worldId >= index.maxWorlds) {
|
|
486
|
-
throw new Error(`Invalid world ID: ${worldId}`);
|
|
487
|
-
}
|
|
488
|
-
if (worldId === index.worldCursor - 1) {
|
|
489
|
-
index.worldCursor--;
|
|
490
|
-
} else if (worldId < index.worldCursor && !index.releasedWorldIds.includes(worldId)) {
|
|
491
|
-
index.releasedWorldIds.push(worldId);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
// ../core/src/universe/universe.ts
|
|
496
|
-
var universe = {
|
|
497
|
-
worlds: new Array(WORLD_ID_BITS ** 2),
|
|
498
|
-
cachedQueries: /* @__PURE__ */ new Map(),
|
|
499
|
-
worldIndex: createWorldIndex(),
|
|
500
|
-
reset: () => {
|
|
501
|
-
universe.worlds = new Array(WORLD_ID_BITS ** 2);
|
|
502
|
-
universe.cachedQueries = /* @__PURE__ */ new Map();
|
|
503
|
-
universe.worldIndex = createWorldIndex();
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
// ../core/src/query/modifier.ts
|
|
508
|
-
var ModifierData = class {
|
|
509
|
-
constructor(type, id, traits) {
|
|
510
|
-
this.type = type;
|
|
511
|
-
this.id = id;
|
|
512
|
-
this.traits = traits;
|
|
513
|
-
__publicField(this, "traitIds");
|
|
514
|
-
this.traitIds = traits.map((trait2) => trait2[$internal].id);
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
// ../core/src/query/utils/tracking-cursor.ts
|
|
519
|
-
var cursor = 3;
|
|
520
|
-
function createTrackingId() {
|
|
521
|
-
return cursor++;
|
|
522
|
-
}
|
|
523
|
-
function getTrackingCursor() {
|
|
524
|
-
return cursor;
|
|
525
|
-
}
|
|
526
|
-
function setTrackingMasks(world, id) {
|
|
527
|
-
const ctx = world[$internal];
|
|
528
|
-
const snapshot = structuredClone(ctx.entityMasks);
|
|
529
|
-
ctx.trackingSnapshots.set(id, snapshot);
|
|
530
|
-
ctx.dirtyMasks.set(
|
|
531
|
-
id,
|
|
532
|
-
snapshot.map((mask) => mask.map(() => 0))
|
|
533
|
-
);
|
|
534
|
-
ctx.changedMasks.set(
|
|
535
|
-
id,
|
|
536
|
-
snapshot.map((mask) => mask.map(() => 0))
|
|
537
|
-
);
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
// ../core/src/query/modifiers/changed.ts
|
|
541
|
-
function createChanged() {
|
|
542
|
-
const id = createTrackingId();
|
|
543
|
-
for (const world of universe.worlds) {
|
|
544
|
-
if (!world) continue;
|
|
545
|
-
setTrackingMasks(world, id);
|
|
546
|
-
}
|
|
547
|
-
return (...traits) => new ModifierData(`changed-${id}`, id, traits);
|
|
548
|
-
}
|
|
549
|
-
function setChanged(world, entity, trait2) {
|
|
550
|
-
const ctx = world[$internal];
|
|
551
|
-
if (!entity.has(trait2)) return;
|
|
552
|
-
if (!ctx.traitData.has(trait2)) registerTrait(world, trait2);
|
|
553
|
-
const data = ctx.traitData.get(trait2);
|
|
554
|
-
for (const changedMask of ctx.changedMasks.values()) {
|
|
555
|
-
const eid = getEntityId(entity);
|
|
556
|
-
if (!changedMask[eid]) changedMask[eid] = new Array();
|
|
557
|
-
const traitId2 = trait2[$internal].id;
|
|
558
|
-
changedMask[eid][traitId2] = 1;
|
|
559
|
-
}
|
|
560
|
-
for (const query of data.queries) {
|
|
561
|
-
if (!query.hasChangedModifiers) continue;
|
|
562
|
-
let match = query.check(world, entity, { type: "change", traitData: data });
|
|
563
|
-
if (match) query.add(entity);
|
|
564
|
-
else query.remove(world, entity);
|
|
565
|
-
}
|
|
566
|
-
for (const sub of data.changedSubscriptions) {
|
|
567
|
-
sub(entity);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
574
|
// ../core/src/entity/entity-methods-patch.ts
|
|
572
575
|
Number.prototype.add = function(...traits) {
|
|
573
576
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
574
|
-
const world = universe.worlds[worldId];
|
|
577
|
+
const world = universe.worlds[worldId].deref();
|
|
575
578
|
return addTrait(world, this, ...traits);
|
|
576
579
|
};
|
|
577
580
|
Number.prototype.remove = function(...traits) {
|
|
578
581
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
579
|
-
const world = universe.worlds[worldId];
|
|
582
|
+
const world = universe.worlds[worldId].deref();
|
|
580
583
|
return removeTrait(world, this, ...traits);
|
|
581
584
|
};
|
|
582
585
|
Number.prototype.has = function(trait2) {
|
|
583
586
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
584
|
-
const world = universe.worlds[worldId];
|
|
587
|
+
const world = universe.worlds[worldId].deref();
|
|
585
588
|
return hasTrait(world, this, trait2);
|
|
586
589
|
};
|
|
587
590
|
Number.prototype.destroy = function() {
|
|
588
591
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
589
|
-
const world = universe.worlds[worldId];
|
|
592
|
+
const world = universe.worlds[worldId].deref();
|
|
590
593
|
return destroyEntity(world, this);
|
|
591
594
|
};
|
|
592
595
|
Number.prototype.changed = function(trait2) {
|
|
593
596
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
594
|
-
const world = universe.worlds[worldId];
|
|
597
|
+
const world = universe.worlds[worldId].deref();
|
|
595
598
|
return setChanged(world, this, trait2);
|
|
596
599
|
};
|
|
597
600
|
Number.prototype.get = function(trait2) {
|
|
598
601
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
599
|
-
const world = universe.worlds[worldId];
|
|
600
|
-
|
|
601
|
-
const data = worldCtx.traitData.get(trait2);
|
|
602
|
-
if (!data) return void 0;
|
|
603
|
-
const index = this & ENTITY_ID_MASK;
|
|
604
|
-
const mask = worldCtx.entityMasks[data.generationId][index];
|
|
605
|
-
if ((mask & data.bitflag) !== data.bitflag) return void 0;
|
|
606
|
-
const traitCtx = trait2[$internal];
|
|
607
|
-
const store = traitCtx.stores[worldId];
|
|
608
|
-
return traitCtx.get(index, store);
|
|
602
|
+
const world = universe.worlds[worldId].deref();
|
|
603
|
+
return getTrait(world, this, trait2);
|
|
609
604
|
};
|
|
610
605
|
Number.prototype.set = function(trait2, value, triggerChanged = true) {
|
|
611
|
-
const ctx = trait2[$internal];
|
|
612
|
-
const index = this & ENTITY_ID_MASK;
|
|
613
606
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
ctx.set(index, store, value);
|
|
617
|
-
triggerChanged && setChanged(universe.worlds[worldId], this, trait2);
|
|
607
|
+
const world = universe.worlds[worldId].deref();
|
|
608
|
+
setTrait(world, this, trait2, value, triggerChanged);
|
|
618
609
|
};
|
|
619
610
|
Number.prototype.targetsFor = function(relation2) {
|
|
620
611
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
621
|
-
const world = universe.worlds[worldId];
|
|
612
|
+
const world = universe.worlds[worldId].deref();
|
|
622
613
|
return getRelationTargets(world, relation2, this);
|
|
623
614
|
};
|
|
624
615
|
Number.prototype.targetFor = function(relation2) {
|
|
625
616
|
const worldId = this >>> WORLD_ID_SHIFT;
|
|
626
|
-
const world = universe.worlds[worldId];
|
|
617
|
+
const world = universe.worlds[worldId].deref();
|
|
627
618
|
return getRelationTargets(world, relation2, this)[0];
|
|
628
619
|
};
|
|
629
620
|
Number.prototype.id = function() {
|
|
630
621
|
const id = this & ENTITY_ID_MASK;
|
|
631
622
|
return id;
|
|
632
623
|
};
|
|
624
|
+
Number.prototype.isAlive = function() {
|
|
625
|
+
const worldId = this >>> WORLD_ID_SHIFT;
|
|
626
|
+
const world = universe.worlds[worldId].deref();
|
|
627
|
+
return isEntityAlive(world[$internal].entityIndex, this);
|
|
628
|
+
};
|
|
633
629
|
|
|
634
630
|
// ../core/src/entity/entity.ts
|
|
635
631
|
function createEntity(world, ...traits) {
|
|
@@ -638,10 +634,10 @@ function createEntity(world, ...traits) {
|
|
|
638
634
|
for (const query of ctx.notQueries) {
|
|
639
635
|
const match = query.check(world, entity);
|
|
640
636
|
if (match) query.add(entity);
|
|
641
|
-
query.resetTrackingBitmasks(entity
|
|
637
|
+
query.resetTrackingBitmasks(getEntityId(entity));
|
|
642
638
|
}
|
|
643
639
|
ctx.entityTraits.set(entity, /* @__PURE__ */ new Set());
|
|
644
|
-
entity
|
|
640
|
+
addTrait(world, entity, ...traits);
|
|
645
641
|
return entity;
|
|
646
642
|
}
|
|
647
643
|
var cachedSet = /* @__PURE__ */ new Set();
|
|
@@ -682,6 +678,8 @@ function destroyEntity(world, entity) {
|
|
|
682
678
|
}
|
|
683
679
|
}
|
|
684
680
|
releaseEntity(ctx.entityIndex, currentEntity);
|
|
681
|
+
const allQuery = ctx.queriesHashMap.get("");
|
|
682
|
+
if (allQuery) allQuery.remove(world, currentEntity);
|
|
685
683
|
ctx.entityTraits.delete(entity);
|
|
686
684
|
const eid = getEntityId(currentEntity);
|
|
687
685
|
for (let i = 0; i < ctx.entityMasks.length; i++) {
|
|
@@ -691,57 +689,51 @@ function destroyEntity(world, entity) {
|
|
|
691
689
|
}
|
|
692
690
|
|
|
693
691
|
// ../core/src/utils/sparse-set.ts
|
|
694
|
-
var _dense, _sparse, _cursor;
|
|
695
692
|
var SparseSet = class {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
__privateAdd(this, _cursor, 0);
|
|
700
|
-
}
|
|
693
|
+
#dense = [];
|
|
694
|
+
#sparse = [];
|
|
695
|
+
#cursor = 0;
|
|
701
696
|
has(val) {
|
|
702
|
-
const index =
|
|
703
|
-
return index <
|
|
697
|
+
const index = this.#sparse[val];
|
|
698
|
+
return index < this.#cursor && this.#dense[index] === val;
|
|
704
699
|
}
|
|
705
700
|
add(val) {
|
|
706
701
|
if (this.has(val)) return;
|
|
707
|
-
|
|
708
|
-
|
|
702
|
+
this.#sparse[val] = this.#cursor;
|
|
703
|
+
this.#dense[this.#cursor++] = val;
|
|
709
704
|
}
|
|
710
705
|
remove(val) {
|
|
711
706
|
if (!this.has(val)) return;
|
|
712
|
-
const index =
|
|
713
|
-
|
|
714
|
-
const swapped =
|
|
707
|
+
const index = this.#sparse[val];
|
|
708
|
+
this.#cursor--;
|
|
709
|
+
const swapped = this.#dense[this.#cursor];
|
|
715
710
|
if (swapped !== val) {
|
|
716
|
-
|
|
717
|
-
|
|
711
|
+
this.#dense[index] = swapped;
|
|
712
|
+
this.#sparse[swapped] = index;
|
|
718
713
|
}
|
|
719
714
|
}
|
|
720
715
|
clear() {
|
|
721
|
-
for (let i = 0; i <
|
|
722
|
-
|
|
716
|
+
for (let i = 0; i < this.#cursor; i++) {
|
|
717
|
+
this.#sparse[this.#dense[i]] = 0;
|
|
723
718
|
}
|
|
724
|
-
|
|
719
|
+
this.#cursor = 0;
|
|
725
720
|
}
|
|
726
721
|
sort() {
|
|
727
|
-
|
|
728
|
-
for (let i = 0; i <
|
|
729
|
-
|
|
722
|
+
this.#dense.sort((a, b) => a - b);
|
|
723
|
+
for (let i = 0; i < this.#dense.length; i++) {
|
|
724
|
+
this.#sparse[this.#dense[i]] = i;
|
|
730
725
|
}
|
|
731
726
|
}
|
|
732
727
|
getIndex(val) {
|
|
733
|
-
return
|
|
728
|
+
return this.#sparse[val];
|
|
734
729
|
}
|
|
735
730
|
get dense() {
|
|
736
|
-
return
|
|
731
|
+
return this.#dense.slice(0, this.#cursor);
|
|
737
732
|
}
|
|
738
733
|
get sparse() {
|
|
739
|
-
return
|
|
734
|
+
return this.#sparse;
|
|
740
735
|
}
|
|
741
736
|
};
|
|
742
|
-
_dense = new WeakMap();
|
|
743
|
-
_sparse = new WeakMap();
|
|
744
|
-
_cursor = new WeakMap();
|
|
745
737
|
|
|
746
738
|
// ../core/src/query/utils/create-query-hash.ts
|
|
747
739
|
var sortedIDs = new Float32Array(1024);
|
|
@@ -771,22 +763,22 @@ var createQueryHash = (parameters) => {
|
|
|
771
763
|
// ../core/src/query/query.ts
|
|
772
764
|
var IsExcluded = trait();
|
|
773
765
|
var Query = class {
|
|
766
|
+
version = 0;
|
|
767
|
+
world;
|
|
768
|
+
parameters;
|
|
769
|
+
hash;
|
|
770
|
+
traits = [];
|
|
771
|
+
traitData = { required: [], forbidden: [], or: [], added: [], removed: [], changed: [], all: [] };
|
|
772
|
+
bitmasks = [];
|
|
773
|
+
generations;
|
|
774
|
+
entities = new SparseSet();
|
|
775
|
+
isTracking = false;
|
|
776
|
+
hasChangedModifiers = false;
|
|
777
|
+
changedTraits = /* @__PURE__ */ new Set();
|
|
778
|
+
toRemove = new SparseSet();
|
|
779
|
+
addSubscriptions = /* @__PURE__ */ new Set();
|
|
780
|
+
removeSubscriptions = /* @__PURE__ */ new Set();
|
|
774
781
|
constructor(world, parameters = []) {
|
|
775
|
-
__publicField(this, "version", 0);
|
|
776
|
-
__publicField(this, "world");
|
|
777
|
-
__publicField(this, "parameters");
|
|
778
|
-
__publicField(this, "hash");
|
|
779
|
-
__publicField(this, "traits", []);
|
|
780
|
-
__publicField(this, "traitData", { required: [], forbidden: [], or: [], added: [], removed: [], changed: [], all: [] });
|
|
781
|
-
__publicField(this, "bitmasks", []);
|
|
782
|
-
__publicField(this, "generations");
|
|
783
|
-
__publicField(this, "entities", new SparseSet());
|
|
784
|
-
__publicField(this, "isTracking", false);
|
|
785
|
-
__publicField(this, "hasChangedModifiers", false);
|
|
786
|
-
__publicField(this, "changedTraits", /* @__PURE__ */ new Set());
|
|
787
|
-
__publicField(this, "toRemove", new SparseSet());
|
|
788
|
-
__publicField(this, "addSubscriptions", /* @__PURE__ */ new Set());
|
|
789
|
-
__publicField(this, "removeSubscriptions", /* @__PURE__ */ new Set());
|
|
790
782
|
this.world = world;
|
|
791
783
|
this.parameters = parameters;
|
|
792
784
|
const ctx = world[$internal];
|
|
@@ -968,6 +960,7 @@ var Query = class {
|
|
|
968
960
|
for (const sub of this.removeSubscriptions) {
|
|
969
961
|
sub(entity);
|
|
970
962
|
}
|
|
963
|
+
this.version++;
|
|
971
964
|
}
|
|
972
965
|
check(world, entity, event) {
|
|
973
966
|
const { bitmasks, generations } = this;
|
|
@@ -1129,7 +1122,7 @@ function createQueryResult(query, world, params) {
|
|
|
1129
1122
|
}
|
|
1130
1123
|
for (let i = 0; i < changedPairs.length; i++) {
|
|
1131
1124
|
const [entity, trait2] = changedPairs[i];
|
|
1132
|
-
entity
|
|
1125
|
+
setChanged(world, entity, trait2);
|
|
1133
1126
|
}
|
|
1134
1127
|
} else if (options.changeDetection === "always") {
|
|
1135
1128
|
const changedPairs = [];
|
|
@@ -1164,7 +1157,7 @@ function createQueryResult(query, world, params) {
|
|
|
1164
1157
|
}
|
|
1165
1158
|
for (let i = 0; i < changedPairs.length; i++) {
|
|
1166
1159
|
const [entity, trait2] = changedPairs[i];
|
|
1167
|
-
entity
|
|
1160
|
+
setChanged(world, entity, trait2);
|
|
1168
1161
|
}
|
|
1169
1162
|
} else if (options.changeDetection === "never") {
|
|
1170
1163
|
for (let i = 0; i < entities.length; i++) {
|
|
@@ -1195,6 +1188,10 @@ function createQueryResult(query, world, params) {
|
|
|
1195
1188
|
stores.length = 0;
|
|
1196
1189
|
getQueryStores(params2, traits, stores, world);
|
|
1197
1190
|
return results;
|
|
1191
|
+
},
|
|
1192
|
+
sort(callback = (a, b) => getEntityId(a) - getEntityId(b)) {
|
|
1193
|
+
Array.prototype.sort.call(entities, callback);
|
|
1194
|
+
return results;
|
|
1198
1195
|
}
|
|
1199
1196
|
});
|
|
1200
1197
|
return results;
|
|
@@ -1219,46 +1216,44 @@ function getQueryStores(params, traits, stores, world) {
|
|
|
1219
1216
|
}
|
|
1220
1217
|
|
|
1221
1218
|
// ../core/src/world/world.ts
|
|
1222
|
-
var _a, _id, _isInitialized;
|
|
1223
|
-
_a = $internal;
|
|
1224
1219
|
var World = class {
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
});
|
|
1244
|
-
__privateAdd(this, _isInitialized, false);
|
|
1245
|
-
__publicField(this, "traits", /* @__PURE__ */ new Set());
|
|
1246
|
-
this.init(...traits);
|
|
1247
|
-
}
|
|
1220
|
+
#id = allocateWorldId(universe.worldIndex);
|
|
1221
|
+
[$internal] = {
|
|
1222
|
+
entityIndex: createEntityIndex(this.#id),
|
|
1223
|
+
entityMasks: [[]],
|
|
1224
|
+
entityTraits: /* @__PURE__ */ new Map(),
|
|
1225
|
+
bitflag: 1,
|
|
1226
|
+
traitData: /* @__PURE__ */ new Map(),
|
|
1227
|
+
queries: /* @__PURE__ */ new Set(),
|
|
1228
|
+
queriesHashMap: /* @__PURE__ */ new Map(),
|
|
1229
|
+
notQueries: /* @__PURE__ */ new Set(),
|
|
1230
|
+
dirtyQueries: /* @__PURE__ */ new Set(),
|
|
1231
|
+
relationTargetEntities: /* @__PURE__ */ new Set(),
|
|
1232
|
+
dirtyMasks: /* @__PURE__ */ new Map(),
|
|
1233
|
+
trackingSnapshots: /* @__PURE__ */ new Map(),
|
|
1234
|
+
changedMasks: /* @__PURE__ */ new Map(),
|
|
1235
|
+
worldEntity: null,
|
|
1236
|
+
trackedTraits: /* @__PURE__ */ new Set()
|
|
1237
|
+
};
|
|
1248
1238
|
get id() {
|
|
1249
|
-
return
|
|
1239
|
+
return this.#id;
|
|
1250
1240
|
}
|
|
1241
|
+
#isInitialized = false;
|
|
1251
1242
|
get isInitialized() {
|
|
1252
|
-
return
|
|
1243
|
+
return this.#isInitialized;
|
|
1253
1244
|
}
|
|
1254
1245
|
get entities() {
|
|
1255
1246
|
return getAliveEntities(this[$internal].entityIndex);
|
|
1256
1247
|
}
|
|
1248
|
+
traits = /* @__PURE__ */ new Set();
|
|
1249
|
+
constructor(...traits) {
|
|
1250
|
+
this.init(...traits);
|
|
1251
|
+
}
|
|
1257
1252
|
init(...traits) {
|
|
1258
1253
|
const ctx = this[$internal];
|
|
1259
|
-
if (
|
|
1260
|
-
|
|
1261
|
-
universe.worlds[
|
|
1254
|
+
if (this.#isInitialized) return;
|
|
1255
|
+
this.#isInitialized = true;
|
|
1256
|
+
universe.worlds[this.#id] = new WeakRef(this);
|
|
1262
1257
|
const cursor2 = getTrackingCursor();
|
|
1263
1258
|
for (let i = 0; i < cursor2; i++) {
|
|
1264
1259
|
setTrackingMasks(this, i);
|
|
@@ -1273,41 +1268,47 @@ var World = class {
|
|
|
1273
1268
|
return createEntity(this, ...traits);
|
|
1274
1269
|
}
|
|
1275
1270
|
has(target) {
|
|
1276
|
-
return typeof target === "number" ? isEntityAlive(this[$internal].entityIndex, target) : this[$internal].worldEntity
|
|
1271
|
+
return typeof target === "number" ? isEntityAlive(this[$internal].entityIndex, target) : hasTrait(this, this[$internal].worldEntity, target);
|
|
1277
1272
|
}
|
|
1278
1273
|
add(...traits) {
|
|
1279
|
-
this[$internal].worldEntity
|
|
1274
|
+
addTrait(this, this[$internal].worldEntity, ...traits);
|
|
1280
1275
|
}
|
|
1281
1276
|
remove(...traits) {
|
|
1282
|
-
this[$internal].worldEntity
|
|
1277
|
+
removeTrait(this, this[$internal].worldEntity, ...traits);
|
|
1283
1278
|
}
|
|
1284
1279
|
get(trait2) {
|
|
1285
|
-
return this[$internal].worldEntity
|
|
1280
|
+
return getTrait(this, this[$internal].worldEntity, trait2);
|
|
1286
1281
|
}
|
|
1287
1282
|
set(trait2, value) {
|
|
1288
|
-
this[$internal].worldEntity
|
|
1283
|
+
setTrait(this, this[$internal].worldEntity, trait2, value);
|
|
1289
1284
|
}
|
|
1290
1285
|
destroy() {
|
|
1291
1286
|
destroyEntity(this, this[$internal].worldEntity);
|
|
1292
1287
|
this[$internal].worldEntity = null;
|
|
1293
1288
|
this.entities.forEach((entity) => destroyEntity(this, entity));
|
|
1294
1289
|
this.reset();
|
|
1295
|
-
|
|
1296
|
-
releaseWorldId(universe.worldIndex,
|
|
1297
|
-
universe.worlds
|
|
1290
|
+
this.#isInitialized = false;
|
|
1291
|
+
releaseWorldId(universe.worldIndex, this.#id);
|
|
1292
|
+
universe.worlds[this.#id] = null;
|
|
1298
1293
|
}
|
|
1299
|
-
reset() {
|
|
1294
|
+
reset(options = {}) {
|
|
1300
1295
|
const ctx = this[$internal];
|
|
1301
|
-
|
|
1296
|
+
const shouldPreserveTraits = options.preserveTraits || options.preserveSubscriptions;
|
|
1297
|
+
const shouldPreserveQueries = options.preserveQueries || options.preserveSubscriptions;
|
|
1298
|
+
ctx.entityIndex = createEntityIndex(this.#id);
|
|
1302
1299
|
ctx.entityTraits.clear();
|
|
1303
|
-
ctx.notQueries.clear();
|
|
1304
1300
|
ctx.entityMasks = [[]];
|
|
1305
1301
|
ctx.bitflag = 1;
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1302
|
+
if (!shouldPreserveTraits) {
|
|
1303
|
+
ctx.traitData.clear();
|
|
1304
|
+
this.traits.clear();
|
|
1305
|
+
}
|
|
1306
|
+
if (!shouldPreserveQueries) {
|
|
1307
|
+
ctx.queries.clear();
|
|
1308
|
+
ctx.queriesHashMap.clear();
|
|
1309
|
+
ctx.dirtyQueries.clear();
|
|
1310
|
+
ctx.notQueries.clear();
|
|
1311
|
+
}
|
|
1311
1312
|
ctx.relationTargetEntities.clear();
|
|
1312
1313
|
ctx.trackingSnapshots.clear();
|
|
1313
1314
|
ctx.dirtyMasks.clear();
|
|
@@ -1369,10 +1370,14 @@ var World = class {
|
|
|
1369
1370
|
};
|
|
1370
1371
|
}
|
|
1371
1372
|
};
|
|
1372
|
-
|
|
1373
|
-
|
|
1373
|
+
var worldFinalizer = new FinalizationRegistry((worldId) => {
|
|
1374
|
+
universe.worlds[worldId] = null;
|
|
1375
|
+
releaseWorldId(universe.worldIndex, worldId);
|
|
1376
|
+
});
|
|
1374
1377
|
function createWorld(...traits) {
|
|
1375
|
-
|
|
1378
|
+
const world = new World(...traits);
|
|
1379
|
+
worldFinalizer.register(world, world.id);
|
|
1380
|
+
return world;
|
|
1376
1381
|
}
|
|
1377
1382
|
|
|
1378
1383
|
// ../core/src/query/modifiers/added.ts
|
|
@@ -1380,7 +1385,7 @@ function createAdded() {
|
|
|
1380
1385
|
const id = createTrackingId();
|
|
1381
1386
|
for (const world of universe.worlds) {
|
|
1382
1387
|
if (!world) continue;
|
|
1383
|
-
setTrackingMasks(world, id);
|
|
1388
|
+
setTrackingMasks(world.deref(), id);
|
|
1384
1389
|
}
|
|
1385
1390
|
return (...traits) => new ModifierData(`added-${id}`, id, traits);
|
|
1386
1391
|
}
|
|
@@ -1390,7 +1395,7 @@ function createRemoved() {
|
|
|
1390
1395
|
const id = createTrackingId();
|
|
1391
1396
|
for (const world of universe.worlds) {
|
|
1392
1397
|
if (!world) continue;
|
|
1393
|
-
setTrackingMasks(world, id);
|
|
1398
|
+
setTrackingMasks(world.deref(), id);
|
|
1394
1399
|
}
|
|
1395
1400
|
return (...traits) => new ModifierData(`removed-${id}`, id, traits);
|
|
1396
1401
|
}
|
|
@@ -1404,8 +1409,9 @@ var Or = (...traits) => new ModifierData("or", 2, traits);
|
|
|
1404
1409
|
// ../core/src/query/utils/cache-query.ts
|
|
1405
1410
|
function cacheQuery(...parameters) {
|
|
1406
1411
|
const hash = createQueryHash(parameters);
|
|
1407
|
-
for (const
|
|
1408
|
-
if (!
|
|
1412
|
+
for (const worldRef of universe.worlds) {
|
|
1413
|
+
if (!worldRef) continue;
|
|
1414
|
+
const world = worldRef.deref();
|
|
1409
1415
|
const ctx = world[$internal];
|
|
1410
1416
|
if (!ctx.queriesHashMap.has(hash)) {
|
|
1411
1417
|
const query = new Query(world, parameters);
|
|
@@ -1433,6 +1439,9 @@ function createActions(actionSet) {
|
|
|
1433
1439
|
return actions;
|
|
1434
1440
|
};
|
|
1435
1441
|
}
|
|
1442
|
+
|
|
1443
|
+
// ../core/src/query/types.ts
|
|
1444
|
+
var $parameters = Symbol();
|
|
1436
1445
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1437
1446
|
0 && (module.exports = {
|
|
1438
1447
|
$internal,
|