koota 0.2.3 → 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 CHANGED
@@ -446,7 +446,15 @@ world.entities
446
446
  const id = world.id()
447
447
 
448
448
  // Resets the world as if it were just created
449
- world.reset()
449
+ // Options can be passed in to modify the reset behavior
450
+ world.reset({
451
+ // Default false. If true, does not clear cached queries
452
+ preserveQueries: false
453
+ // Default false. If true, does not clear cached traits
454
+ preserveTraits: false
455
+ // Default false. If true, does not clear subscrptions, queries or traits
456
+ preserveSubscriptions: false
457
+ })
450
458
 
451
459
  // Nukes the world and releases its ID
452
460
  world.destroy()
@@ -647,7 +655,7 @@ return player ? (
647
655
 
648
656
  ### `useWorld`
649
657
 
650
- Returns the default world. If a world is passed in via `WorldProvider` then this is returned instead. The default world can be gotten at any time with `getDefaultWorld`.
658
+ Returns the world held in context via `WorldProvider`.
651
659
 
652
660
  ```js
653
661
  // Get the default world
@@ -663,7 +671,7 @@ useEffect(() => {
663
671
 
664
672
  ### `WorldProvider`
665
673
 
666
- The provider for the world context. A world must be created and passed in, which then overrides the default world.
674
+ The provider for the world context. A world must be created and passed in.
667
675
 
668
676
  ```js
669
677
  // Create a world and pass it to the provider
@@ -1,22 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __typeError = (msg) => {
3
- throw TypeError(msg);
4
- };
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
- 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);
10
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
- var __privateWrapper = (obj, member, setter, getter) => ({
12
- set _(value) {
13
- __privateSet(obj, member, value, setter);
14
- },
15
- get _() {
16
- return __privateGet(obj, member, getter);
17
- }
18
- });
19
-
20
1
  // ../core/src/common.ts
21
2
  var $internal = Symbol("internal");
22
3
 
@@ -72,7 +53,7 @@ var universe = {
72
53
  cachedQueries: /* @__PURE__ */ new Map(),
73
54
  worldIndex: createWorldIndex(),
74
55
  reset: () => {
75
- universe.worlds = new Array(WORLD_ID_BITS ** 2);
56
+ universe.worlds = new Array(WORLD_ID_BITS ** 2).fill(null);
76
57
  universe.cachedQueries = /* @__PURE__ */ new Map();
77
58
  universe.worldIndex = createWorldIndex();
78
59
  }
@@ -84,9 +65,9 @@ var ModifierData = class {
84
65
  this.type = type;
85
66
  this.id = id;
86
67
  this.traits = traits;
87
- __publicField(this, "traitIds");
88
68
  this.traitIds = traits.map((trait2) => trait2[$internal].id);
89
69
  }
70
+ traitIds;
90
71
  };
91
72
 
92
73
  // ../core/src/query/utils/tracking-cursor.ts
@@ -148,8 +129,9 @@ function getRelationTrait(relation2, traitFactory, pairsMap, target) {
148
129
  }
149
130
  var getRelationTargets = (world, relation2, entity) => {
150
131
  const ctx = world[$internal];
151
- const traits = ctx.entityTraits.get(entity) || [];
132
+ const traits = ctx.entityTraits.get(entity);
152
133
  const targets = [];
134
+ if (!traits) return targets;
153
135
  for (const trait2 of traits) {
154
136
  const traitCtx = trait2[$internal];
155
137
  if (traitCtx.relation === relation2 && traitCtx.pairTarget !== Wildcard) {
@@ -181,15 +163,15 @@ var incrementWorldBitflag = (world) => {
181
163
 
182
164
  // ../core/src/trait/trait-data.ts
183
165
  var TraitData = class {
166
+ generationId;
167
+ bitflag;
168
+ trait;
169
+ store;
170
+ queries;
171
+ notQueries;
172
+ schema;
173
+ changedSubscriptions;
184
174
  constructor(world, trait2) {
185
- __publicField(this, "generationId");
186
- __publicField(this, "bitflag");
187
- __publicField(this, "trait");
188
- __publicField(this, "store");
189
- __publicField(this, "queries");
190
- __publicField(this, "notQueries");
191
- __publicField(this, "schema");
192
- __publicField(this, "changedSubscriptions");
193
175
  const ctx = world[$internal];
194
176
  const traitCtx = trait2[$internal];
195
177
  this.generationId = ctx.entityMasks.length - 1;
@@ -478,7 +460,7 @@ function createChanged() {
478
460
  const id = createTrackingId();
479
461
  for (const world of universe.worlds) {
480
462
  if (!world) continue;
481
- setTrackingMasks(world, id);
463
+ setTrackingMasks(world.deref(), id);
482
464
  }
483
465
  return (...traits) => new ModifierData(`changed-${id}`, id, traits);
484
466
  }
@@ -553,47 +535,47 @@ var getAliveEntities = (index) => {
553
535
  // ../core/src/entity/entity-methods-patch.ts
554
536
  Number.prototype.add = function(...traits) {
555
537
  const worldId = this >>> WORLD_ID_SHIFT;
556
- const world = universe.worlds[worldId];
538
+ const world = universe.worlds[worldId].deref();
557
539
  return addTrait(world, this, ...traits);
558
540
  };
559
541
  Number.prototype.remove = function(...traits) {
560
542
  const worldId = this >>> WORLD_ID_SHIFT;
561
- const world = universe.worlds[worldId];
543
+ const world = universe.worlds[worldId].deref();
562
544
  return removeTrait(world, this, ...traits);
563
545
  };
564
546
  Number.prototype.has = function(trait2) {
565
547
  const worldId = this >>> WORLD_ID_SHIFT;
566
- const world = universe.worlds[worldId];
548
+ const world = universe.worlds[worldId].deref();
567
549
  return hasTrait(world, this, trait2);
568
550
  };
569
551
  Number.prototype.destroy = function() {
570
552
  const worldId = this >>> WORLD_ID_SHIFT;
571
- const world = universe.worlds[worldId];
553
+ const world = universe.worlds[worldId].deref();
572
554
  return destroyEntity(world, this);
573
555
  };
574
556
  Number.prototype.changed = function(trait2) {
575
557
  const worldId = this >>> WORLD_ID_SHIFT;
576
- const world = universe.worlds[worldId];
558
+ const world = universe.worlds[worldId].deref();
577
559
  return setChanged(world, this, trait2);
578
560
  };
579
561
  Number.prototype.get = function(trait2) {
580
562
  const worldId = this >>> WORLD_ID_SHIFT;
581
- const world = universe.worlds[worldId];
563
+ const world = universe.worlds[worldId].deref();
582
564
  return getTrait(world, this, trait2);
583
565
  };
584
566
  Number.prototype.set = function(trait2, value, triggerChanged = true) {
585
567
  const worldId = this >>> WORLD_ID_SHIFT;
586
- const world = universe.worlds[worldId];
568
+ const world = universe.worlds[worldId].deref();
587
569
  setTrait(world, this, trait2, value, triggerChanged);
588
570
  };
589
571
  Number.prototype.targetsFor = function(relation2) {
590
572
  const worldId = this >>> WORLD_ID_SHIFT;
591
- const world = universe.worlds[worldId];
573
+ const world = universe.worlds[worldId].deref();
592
574
  return getRelationTargets(world, relation2, this);
593
575
  };
594
576
  Number.prototype.targetFor = function(relation2) {
595
577
  const worldId = this >>> WORLD_ID_SHIFT;
596
- const world = universe.worlds[worldId];
578
+ const world = universe.worlds[worldId].deref();
597
579
  return getRelationTargets(world, relation2, this)[0];
598
580
  };
599
581
  Number.prototype.id = function() {
@@ -602,7 +584,7 @@ Number.prototype.id = function() {
602
584
  };
603
585
  Number.prototype.isAlive = function() {
604
586
  const worldId = this >>> WORLD_ID_SHIFT;
605
- const world = universe.worlds[worldId];
587
+ const world = universe.worlds[worldId].deref();
606
588
  return isEntityAlive(world[$internal].entityIndex, this);
607
589
  };
608
590
 
@@ -668,64 +650,58 @@ function destroyEntity(world, entity) {
668
650
  }
669
651
 
670
652
  // ../core/src/utils/sparse-set.ts
671
- var _dense, _sparse, _cursor;
672
653
  var SparseSet = class {
673
- constructor() {
674
- __privateAdd(this, _dense, []);
675
- __privateAdd(this, _sparse, []);
676
- __privateAdd(this, _cursor, 0);
677
- }
654
+ #dense = [];
655
+ #sparse = [];
656
+ #cursor = 0;
678
657
  has(val) {
679
- const index = __privateGet(this, _sparse)[val];
680
- return index < __privateGet(this, _cursor) && __privateGet(this, _dense)[index] === val;
658
+ const index = this.#sparse[val];
659
+ return index < this.#cursor && this.#dense[index] === val;
681
660
  }
682
661
  add(val) {
683
662
  if (this.has(val)) return;
684
- __privateGet(this, _sparse)[val] = __privateGet(this, _cursor);
685
- __privateGet(this, _dense)[__privateWrapper(this, _cursor)._++] = val;
663
+ this.#sparse[val] = this.#cursor;
664
+ this.#dense[this.#cursor++] = val;
686
665
  }
687
666
  remove(val) {
688
667
  if (!this.has(val)) return;
689
- const index = __privateGet(this, _sparse)[val];
690
- __privateWrapper(this, _cursor)._--;
691
- const swapped = __privateGet(this, _dense)[__privateGet(this, _cursor)];
668
+ const index = this.#sparse[val];
669
+ this.#cursor--;
670
+ const swapped = this.#dense[this.#cursor];
692
671
  if (swapped !== val) {
693
- __privateGet(this, _dense)[index] = swapped;
694
- __privateGet(this, _sparse)[swapped] = index;
672
+ this.#dense[index] = swapped;
673
+ this.#sparse[swapped] = index;
695
674
  }
696
675
  }
697
676
  clear() {
698
- for (let i = 0; i < __privateGet(this, _cursor); i++) {
699
- __privateGet(this, _sparse)[__privateGet(this, _dense)[i]] = 0;
677
+ for (let i = 0; i < this.#cursor; i++) {
678
+ this.#sparse[this.#dense[i]] = 0;
700
679
  }
701
- __privateSet(this, _cursor, 0);
680
+ this.#cursor = 0;
702
681
  }
703
682
  sort() {
704
- __privateGet(this, _dense).sort((a, b) => a - b);
705
- for (let i = 0; i < __privateGet(this, _dense).length; i++) {
706
- __privateGet(this, _sparse)[__privateGet(this, _dense)[i]] = i;
683
+ this.#dense.sort((a, b) => a - b);
684
+ for (let i = 0; i < this.#dense.length; i++) {
685
+ this.#sparse[this.#dense[i]] = i;
707
686
  }
708
687
  }
709
688
  getIndex(val) {
710
- return __privateGet(this, _sparse)[val];
689
+ return this.#sparse[val];
711
690
  }
712
691
  get dense() {
713
- return __privateGet(this, _dense).slice(0, __privateGet(this, _cursor));
692
+ return this.#dense.slice(0, this.#cursor);
714
693
  }
715
694
  get sparse() {
716
- return __privateGet(this, _sparse);
695
+ return this.#sparse;
717
696
  }
718
697
  };
719
- _dense = new WeakMap();
720
- _sparse = new WeakMap();
721
- _cursor = new WeakMap();
722
698
 
723
699
  // ../core/src/query/modifiers/added.ts
724
700
  function createAdded() {
725
701
  const id = createTrackingId();
726
702
  for (const world of universe.worlds) {
727
703
  if (!world) continue;
728
- setTrackingMasks(world, id);
704
+ setTrackingMasks(world.deref(), id);
729
705
  }
730
706
  return (...traits) => new ModifierData(`added-${id}`, id, traits);
731
707
  }
@@ -735,7 +711,7 @@ function createRemoved() {
735
711
  const id = createTrackingId();
736
712
  for (const world of universe.worlds) {
737
713
  if (!world) continue;
738
- setTrackingMasks(world, id);
714
+ setTrackingMasks(world.deref(), id);
739
715
  }
740
716
  return (...traits) => new ModifierData(`removed-${id}`, id, traits);
741
717
  }
@@ -749,8 +725,9 @@ var Or = (...traits) => new ModifierData("or", 2, traits);
749
725
  // ../core/src/query/utils/cache-query.ts
750
726
  function cacheQuery(...parameters) {
751
727
  const hash = createQueryHash(parameters);
752
- for (const world of universe.worlds) {
753
- if (!world) continue;
728
+ for (const worldRef of universe.worlds) {
729
+ if (!worldRef) continue;
730
+ const world = worldRef.deref();
754
731
  const ctx = world[$internal];
755
732
  if (!ctx.queriesHashMap.has(hash)) {
756
733
  const query = new Query(world, parameters);
@@ -779,6 +756,9 @@ function createActions(actionSet) {
779
756
  };
780
757
  }
781
758
 
759
+ // ../core/src/query/types.ts
760
+ var $parameters = Symbol();
761
+
782
762
  // ../core/src/query/utils/create-query-hash.ts
783
763
  var sortedIDs = new Float32Array(1024);
784
764
  var createQueryHash = (parameters) => {
@@ -807,22 +787,22 @@ var createQueryHash = (parameters) => {
807
787
  // ../core/src/query/query.ts
808
788
  var IsExcluded = trait();
809
789
  var Query = class {
790
+ version = 0;
791
+ world;
792
+ parameters;
793
+ hash;
794
+ traits = [];
795
+ traitData = { required: [], forbidden: [], or: [], added: [], removed: [], changed: [], all: [] };
796
+ bitmasks = [];
797
+ generations;
798
+ entities = new SparseSet();
799
+ isTracking = false;
800
+ hasChangedModifiers = false;
801
+ changedTraits = /* @__PURE__ */ new Set();
802
+ toRemove = new SparseSet();
803
+ addSubscriptions = /* @__PURE__ */ new Set();
804
+ removeSubscriptions = /* @__PURE__ */ new Set();
810
805
  constructor(world, parameters = []) {
811
- __publicField(this, "version", 0);
812
- __publicField(this, "world");
813
- __publicField(this, "parameters");
814
- __publicField(this, "hash");
815
- __publicField(this, "traits", []);
816
- __publicField(this, "traitData", { required: [], forbidden: [], or: [], added: [], removed: [], changed: [], all: [] });
817
- __publicField(this, "bitmasks", []);
818
- __publicField(this, "generations");
819
- __publicField(this, "entities", new SparseSet());
820
- __publicField(this, "isTracking", false);
821
- __publicField(this, "hasChangedModifiers", false);
822
- __publicField(this, "changedTraits", /* @__PURE__ */ new Set());
823
- __publicField(this, "toRemove", new SparseSet());
824
- __publicField(this, "addSubscriptions", /* @__PURE__ */ new Set());
825
- __publicField(this, "removeSubscriptions", /* @__PURE__ */ new Set());
826
806
  this.world = world;
827
807
  this.parameters = parameters;
828
808
  const ctx = world[$internal];
@@ -1232,6 +1212,10 @@ function createQueryResult(query, world, params) {
1232
1212
  stores.length = 0;
1233
1213
  getQueryStores(params2, traits, stores, world);
1234
1214
  return results;
1215
+ },
1216
+ sort(callback = (a, b) => getEntityId(a) - getEntityId(b)) {
1217
+ Array.prototype.sort.call(entities, callback);
1218
+ return results;
1235
1219
  }
1236
1220
  });
1237
1221
  return results;
@@ -1256,46 +1240,44 @@ function getQueryStores(params, traits, stores, world) {
1256
1240
  }
1257
1241
 
1258
1242
  // ../core/src/world/world.ts
1259
- var _a, _id, _isInitialized;
1260
- _a = $internal;
1261
1243
  var World = class {
1262
- constructor(...traits) {
1263
- __privateAdd(this, _id, allocateWorldId(universe.worldIndex));
1264
- __publicField(this, _a, {
1265
- entityIndex: createEntityIndex(__privateGet(this, _id)),
1266
- entityMasks: [[]],
1267
- entityTraits: /* @__PURE__ */ new Map(),
1268
- bitflag: 1,
1269
- traitData: /* @__PURE__ */ new Map(),
1270
- queries: /* @__PURE__ */ new Set(),
1271
- queriesHashMap: /* @__PURE__ */ new Map(),
1272
- notQueries: /* @__PURE__ */ new Set(),
1273
- dirtyQueries: /* @__PURE__ */ new Set(),
1274
- relationTargetEntities: /* @__PURE__ */ new Set(),
1275
- dirtyMasks: /* @__PURE__ */ new Map(),
1276
- trackingSnapshots: /* @__PURE__ */ new Map(),
1277
- changedMasks: /* @__PURE__ */ new Map(),
1278
- worldEntity: null,
1279
- trackedTraits: /* @__PURE__ */ new Set()
1280
- });
1281
- __privateAdd(this, _isInitialized, false);
1282
- __publicField(this, "traits", /* @__PURE__ */ new Set());
1283
- this.init(...traits);
1284
- }
1244
+ #id = allocateWorldId(universe.worldIndex);
1245
+ [$internal] = {
1246
+ entityIndex: createEntityIndex(this.#id),
1247
+ entityMasks: [[]],
1248
+ entityTraits: /* @__PURE__ */ new Map(),
1249
+ bitflag: 1,
1250
+ traitData: /* @__PURE__ */ new Map(),
1251
+ queries: /* @__PURE__ */ new Set(),
1252
+ queriesHashMap: /* @__PURE__ */ new Map(),
1253
+ notQueries: /* @__PURE__ */ new Set(),
1254
+ dirtyQueries: /* @__PURE__ */ new Set(),
1255
+ relationTargetEntities: /* @__PURE__ */ new Set(),
1256
+ dirtyMasks: /* @__PURE__ */ new Map(),
1257
+ trackingSnapshots: /* @__PURE__ */ new Map(),
1258
+ changedMasks: /* @__PURE__ */ new Map(),
1259
+ worldEntity: null,
1260
+ trackedTraits: /* @__PURE__ */ new Set()
1261
+ };
1285
1262
  get id() {
1286
- return __privateGet(this, _id);
1263
+ return this.#id;
1287
1264
  }
1265
+ #isInitialized = false;
1288
1266
  get isInitialized() {
1289
- return __privateGet(this, _isInitialized);
1267
+ return this.#isInitialized;
1290
1268
  }
1291
1269
  get entities() {
1292
1270
  return getAliveEntities(this[$internal].entityIndex);
1293
1271
  }
1272
+ traits = /* @__PURE__ */ new Set();
1273
+ constructor(...traits) {
1274
+ this.init(...traits);
1275
+ }
1294
1276
  init(...traits) {
1295
1277
  const ctx = this[$internal];
1296
- if (__privateGet(this, _isInitialized)) return;
1297
- __privateSet(this, _isInitialized, true);
1298
- universe.worlds[__privateGet(this, _id)] = this;
1278
+ if (this.#isInitialized) return;
1279
+ this.#isInitialized = true;
1280
+ universe.worlds[this.#id] = new WeakRef(this);
1299
1281
  const cursor2 = getTrackingCursor();
1300
1282
  for (let i = 0; i < cursor2; i++) {
1301
1283
  setTrackingMasks(this, i);
@@ -1329,22 +1311,28 @@ var World = class {
1329
1311
  this[$internal].worldEntity = null;
1330
1312
  this.entities.forEach((entity) => destroyEntity(this, entity));
1331
1313
  this.reset();
1332
- __privateSet(this, _isInitialized, false);
1333
- releaseWorldId(universe.worldIndex, __privateGet(this, _id));
1334
- universe.worlds.splice(universe.worlds.indexOf(this), 1);
1314
+ this.#isInitialized = false;
1315
+ releaseWorldId(universe.worldIndex, this.#id);
1316
+ universe.worlds[this.#id] = null;
1335
1317
  }
1336
- reset() {
1318
+ reset(options = {}) {
1337
1319
  const ctx = this[$internal];
1338
- ctx.entityIndex = createEntityIndex(__privateGet(this, _id));
1320
+ const shouldPreserveTraits = options.preserveTraits || options.preserveSubscriptions;
1321
+ const shouldPreserveQueries = options.preserveQueries || options.preserveSubscriptions;
1322
+ ctx.entityIndex = createEntityIndex(this.#id);
1339
1323
  ctx.entityTraits.clear();
1340
- ctx.notQueries.clear();
1341
1324
  ctx.entityMasks = [[]];
1342
1325
  ctx.bitflag = 1;
1343
- ctx.traitData.clear();
1344
- this.traits.clear();
1345
- ctx.queries.clear();
1346
- ctx.queriesHashMap.clear();
1347
- ctx.dirtyQueries.clear();
1326
+ if (!shouldPreserveTraits) {
1327
+ ctx.traitData.clear();
1328
+ this.traits.clear();
1329
+ }
1330
+ if (!shouldPreserveQueries) {
1331
+ ctx.queries.clear();
1332
+ ctx.queriesHashMap.clear();
1333
+ ctx.dirtyQueries.clear();
1334
+ ctx.notQueries.clear();
1335
+ }
1348
1336
  ctx.relationTargetEntities.clear();
1349
1337
  ctx.trackingSnapshots.clear();
1350
1338
  ctx.dirtyMasks.clear();
@@ -1406,10 +1394,14 @@ var World = class {
1406
1394
  };
1407
1395
  }
1408
1396
  };
1409
- _id = new WeakMap();
1410
- _isInitialized = new WeakMap();
1397
+ var worldFinalizer = new FinalizationRegistry((worldId) => {
1398
+ universe.worlds[worldId] = null;
1399
+ releaseWorldId(universe.worldIndex, worldId);
1400
+ });
1411
1401
  function createWorld(...traits) {
1412
- return new World(...traits);
1402
+ const world = new World(...traits);
1403
+ worldFinalizer.register(world, world.id);
1404
+ return world;
1413
1405
  }
1414
1406
 
1415
1407
  export {