koota 0.2.1 → 0.2.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/react/index.cjs CHANGED
@@ -69,6 +69,99 @@ var getEntityGeneration = (entity) => entity >>> GENERATION_SHIFT & GENERATION_M
69
69
  var incrementGeneration = (entity) => entity & ~(GENERATION_MASK << GENERATION_SHIFT) | // Clear current generation bits
70
70
  ((entity >>> GENERATION_SHIFT & GENERATION_MASK) + 1 & GENERATION_MASK) << GENERATION_SHIFT;
71
71
 
72
+ // ../core/src/world/utils/world-index.ts
73
+ function createWorldIndex() {
74
+ return {
75
+ worldCursor: 0,
76
+ releasedWorldIds: [],
77
+ maxWorlds: 2 ** WORLD_ID_BITS
78
+ };
79
+ }
80
+ function allocateWorldId(index) {
81
+ if (index.releasedWorldIds.length > 0) {
82
+ return index.releasedWorldIds.pop();
83
+ }
84
+ if (index.worldCursor >= index.maxWorlds) {
85
+ throw new Error(`Koota: Too many worlds created. The maximum is ${index.maxWorlds}.`);
86
+ }
87
+ return index.worldCursor++;
88
+ }
89
+ function releaseWorldId(index, worldId) {
90
+ if (worldId < 0 || worldId >= index.maxWorlds) {
91
+ throw new Error(`Invalid world ID: ${worldId}`);
92
+ }
93
+ if (worldId === index.worldCursor - 1) {
94
+ index.worldCursor--;
95
+ } else if (worldId < index.worldCursor && !index.releasedWorldIds.includes(worldId)) {
96
+ index.releasedWorldIds.push(worldId);
97
+ }
98
+ }
99
+
100
+ // ../core/src/universe/universe.ts
101
+ var universe = {
102
+ worlds: new Array(WORLD_ID_BITS ** 2),
103
+ cachedQueries: /* @__PURE__ */ new Map(),
104
+ worldIndex: createWorldIndex(),
105
+ reset: () => {
106
+ universe.worlds = new Array(WORLD_ID_BITS ** 2);
107
+ universe.cachedQueries = /* @__PURE__ */ new Map();
108
+ universe.worldIndex = createWorldIndex();
109
+ }
110
+ };
111
+
112
+ // ../core/src/query/modifier.ts
113
+ var ModifierData = class {
114
+ constructor(type, id, traits) {
115
+ this.type = type;
116
+ this.id = id;
117
+ this.traits = traits;
118
+ __publicField(this, "traitIds");
119
+ this.traitIds = traits.map((trait2) => trait2[$internal].id);
120
+ }
121
+ };
122
+
123
+ // ../core/src/query/utils/tracking-cursor.ts
124
+ var cursor = 3;
125
+ function getTrackingCursor() {
126
+ return cursor;
127
+ }
128
+ function setTrackingMasks(world, id) {
129
+ const ctx = world[$internal];
130
+ const snapshot = structuredClone(ctx.entityMasks);
131
+ ctx.trackingSnapshots.set(id, snapshot);
132
+ ctx.dirtyMasks.set(
133
+ id,
134
+ snapshot.map((mask) => mask.map(() => 0))
135
+ );
136
+ ctx.changedMasks.set(
137
+ id,
138
+ snapshot.map((mask) => mask.map(() => 0))
139
+ );
140
+ }
141
+
142
+ // ../core/src/query/modifiers/changed.ts
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
+
72
165
  // ../core/src/relation/relation.ts
73
166
  function defineRelation(definition) {
74
167
  const pairsMap = /* @__PURE__ */ new Map();
@@ -315,7 +408,7 @@ function addTrait(world, entity, ...traits) {
315
408
  } else {
316
409
  trait2 = traits[i];
317
410
  }
318
- if (entity.has(trait2)) return;
411
+ if (hasTrait(world, entity, trait2)) return;
319
412
  const traitCtx = trait2[$internal];
320
413
  if (!ctx.traitData.has(trait2)) registerTrait(world, trait2);
321
414
  const data = ctx.traitData.get(trait2);
@@ -337,8 +430,8 @@ function addTrait(world, entity, ...traits) {
337
430
  const target = traitCtx.pairTarget;
338
431
  if (traitCtx.isPairTrait && relation2 !== null && target !== null) {
339
432
  ctx.relationTargetEntities.add(target);
340
- entity.add(Pair(Wildcard, target));
341
- entity.add(Pair(relation2, Wildcard));
433
+ addTrait(world, entity, Pair(Wildcard, target));
434
+ addTrait(world, entity, Pair(relation2, Wildcard));
342
435
  if (relation2[$internal].exclusive === true && target !== Wildcard) {
343
436
  const oldTarget = getRelationTargets(world, relation2, entity)[0];
344
437
  if (oldTarget !== null && oldTarget !== void 0 && oldTarget !== target) {
@@ -355,10 +448,10 @@ function addTrait(world, entity, ...traits) {
355
448
  defaults[key] = data.schema[key];
356
449
  }
357
450
  }
358
- entity.set(trait2, { ...defaults, ...params }, false);
451
+ setTrait(world, entity, trait2, { ...defaults, ...params }, false);
359
452
  } else {
360
453
  const state = params ?? data.schema();
361
- entity.set(trait2, state, false);
454
+ setTrait(world, entity, trait2, state, false);
362
455
  }
363
456
  }
364
457
  }
@@ -367,7 +460,7 @@ function removeTrait(world, entity, ...traits) {
367
460
  for (let i = 0; i < traits.length; i++) {
368
461
  const trait2 = traits[i];
369
462
  const traitCtx = trait2[$internal];
370
- if (!entity.has(trait2)) return;
463
+ if (!hasTrait(world, entity, trait2)) return;
371
464
  const data = ctx.traitData.get(trait2);
372
465
  const { generationId, bitflag, queries } = data;
373
466
  const eid = getEntityId(entity);
@@ -410,6 +503,25 @@ function getStore(world, trait2) {
410
503
  const store = data.store;
411
504
  return store;
412
505
  }
506
+ function setTrait(world, entity, trait2, value, triggerChanged = true) {
507
+ const ctx = trait2[$internal];
508
+ const index = entity & ENTITY_ID_MASK;
509
+ const store = getStore(world, trait2);
510
+ value instanceof Function && (value = value(ctx.get(index, store)));
511
+ ctx.set(index, store, value);
512
+ triggerChanged && setChanged(world, entity, trait2);
513
+ }
514
+ function getTrait(world, entity, trait2) {
515
+ const worldCtx = world[$internal];
516
+ const data = worldCtx.traitData.get(trait2);
517
+ if (!data) return void 0;
518
+ const index = getEntityId(entity);
519
+ const mask = worldCtx.entityMasks[data.generationId][index];
520
+ if ((mask & data.bitflag) !== data.bitflag) return void 0;
521
+ const traitCtx = trait2[$internal];
522
+ const store = getStore(world, trait2);
523
+ return traitCtx.get(index, store);
524
+ }
413
525
 
414
526
  // ../core/src/entity/utils/entity-index.ts
415
527
  var createEntityIndex = (worldId) => ({
@@ -457,99 +569,6 @@ var getAliveEntities = (index) => {
457
569
  return index.dense.slice(0, index.aliveCount);
458
570
  };
459
571
 
460
- // ../core/src/world/utils/world-index.ts
461
- function createWorldIndex() {
462
- return {
463
- worldCursor: 0,
464
- releasedWorldIds: [],
465
- maxWorlds: 2 ** WORLD_ID_BITS
466
- };
467
- }
468
- function allocateWorldId(index) {
469
- if (index.releasedWorldIds.length > 0) {
470
- return index.releasedWorldIds.pop();
471
- }
472
- if (index.worldCursor >= index.maxWorlds) {
473
- throw new Error(`Koota: Too many worlds created. The maximum is ${index.maxWorlds}.`);
474
- }
475
- return index.worldCursor++;
476
- }
477
- function releaseWorldId(index, worldId) {
478
- if (worldId < 0 || worldId >= index.maxWorlds) {
479
- throw new Error(`Invalid world ID: ${worldId}`);
480
- }
481
- if (worldId === index.worldCursor - 1) {
482
- index.worldCursor--;
483
- } else if (worldId < index.worldCursor && !index.releasedWorldIds.includes(worldId)) {
484
- index.releasedWorldIds.push(worldId);
485
- }
486
- }
487
-
488
- // ../core/src/universe/universe.ts
489
- var universe = {
490
- worlds: new Array(WORLD_ID_BITS ** 2),
491
- cachedQueries: /* @__PURE__ */ new Map(),
492
- worldIndex: createWorldIndex(),
493
- reset: () => {
494
- universe.worlds = new Array(WORLD_ID_BITS ** 2);
495
- universe.cachedQueries = /* @__PURE__ */ new Map();
496
- universe.worldIndex = createWorldIndex();
497
- }
498
- };
499
-
500
- // ../core/src/query/modifier.ts
501
- var ModifierData = class {
502
- constructor(type, id, traits) {
503
- this.type = type;
504
- this.id = id;
505
- this.traits = traits;
506
- __publicField(this, "traitIds");
507
- this.traitIds = traits.map((trait2) => trait2[$internal].id);
508
- }
509
- };
510
-
511
- // ../core/src/query/utils/tracking-cursor.ts
512
- var cursor = 3;
513
- function getTrackingCursor() {
514
- return cursor;
515
- }
516
- function setTrackingMasks(world, id) {
517
- const ctx = world[$internal];
518
- const snapshot = structuredClone(ctx.entityMasks);
519
- ctx.trackingSnapshots.set(id, snapshot);
520
- ctx.dirtyMasks.set(
521
- id,
522
- snapshot.map((mask) => mask.map(() => 0))
523
- );
524
- ctx.changedMasks.set(
525
- id,
526
- snapshot.map((mask) => mask.map(() => 0))
527
- );
528
- }
529
-
530
- // ../core/src/query/modifiers/changed.ts
531
- function setChanged(world, entity, trait2) {
532
- const ctx = world[$internal];
533
- if (!entity.has(trait2)) return;
534
- if (!ctx.traitData.has(trait2)) registerTrait(world, trait2);
535
- const data = ctx.traitData.get(trait2);
536
- for (const changedMask of ctx.changedMasks.values()) {
537
- const eid = getEntityId(entity);
538
- if (!changedMask[eid]) changedMask[eid] = new Array();
539
- const traitId2 = trait2[$internal].id;
540
- changedMask[eid][traitId2] = 1;
541
- }
542
- for (const query of data.queries) {
543
- if (!query.hasChangedModifiers) continue;
544
- let match = query.check(world, entity, { type: "change", traitData: data });
545
- if (match) query.add(entity);
546
- else query.remove(world, entity);
547
- }
548
- for (const sub of data.changedSubscriptions) {
549
- sub(entity);
550
- }
551
- }
552
-
553
572
  // ../core/src/entity/entity-methods-patch.ts
554
573
  Number.prototype.add = function(...traits) {
555
574
  const worldId = this >>> WORLD_ID_SHIFT;
@@ -579,24 +598,12 @@ Number.prototype.changed = function(trait2) {
579
598
  Number.prototype.get = function(trait2) {
580
599
  const worldId = this >>> WORLD_ID_SHIFT;
581
600
  const world = universe.worlds[worldId];
582
- const worldCtx = world[$internal];
583
- const data = worldCtx.traitData.get(trait2);
584
- if (!data) return void 0;
585
- const index = this & ENTITY_ID_MASK;
586
- const mask = worldCtx.entityMasks[data.generationId][index];
587
- if ((mask & data.bitflag) !== data.bitflag) return void 0;
588
- const traitCtx = trait2[$internal];
589
- const store = traitCtx.stores[worldId];
590
- return traitCtx.get(index, store);
601
+ return getTrait(world, this, trait2);
591
602
  };
592
603
  Number.prototype.set = function(trait2, value, triggerChanged = true) {
593
- const ctx = trait2[$internal];
594
- const index = this & ENTITY_ID_MASK;
595
604
  const worldId = this >>> WORLD_ID_SHIFT;
596
- const store = ctx.stores[worldId];
597
- value instanceof Function && (value = value(ctx.get(index, store)));
598
- ctx.set(index, store, value);
599
- triggerChanged && setChanged(universe.worlds[worldId], this, trait2);
605
+ const world = universe.worlds[worldId];
606
+ setTrait(world, this, trait2, value, triggerChanged);
600
607
  };
601
608
  Number.prototype.targetsFor = function(relation2) {
602
609
  const worldId = this >>> WORLD_ID_SHIFT;
@@ -612,6 +619,11 @@ Number.prototype.id = function() {
612
619
  const id = this & ENTITY_ID_MASK;
613
620
  return id;
614
621
  };
622
+ Number.prototype.isAlive = function() {
623
+ const worldId = this >>> WORLD_ID_SHIFT;
624
+ const world = universe.worlds[worldId];
625
+ return isEntityAlive(world[$internal].entityIndex, this);
626
+ };
615
627
 
616
628
  // ../core/src/entity/entity.ts
617
629
  function createEntity(world, ...traits) {
@@ -620,10 +632,10 @@ function createEntity(world, ...traits) {
620
632
  for (const query of ctx.notQueries) {
621
633
  const match = query.check(world, entity);
622
634
  if (match) query.add(entity);
623
- query.resetTrackingBitmasks(entity.id());
635
+ query.resetTrackingBitmasks(getEntityId(entity));
624
636
  }
625
637
  ctx.entityTraits.set(entity, /* @__PURE__ */ new Set());
626
- entity.add(...traits);
638
+ addTrait(world, entity, ...traits);
627
639
  return entity;
628
640
  }
629
641
  var cachedSet = /* @__PURE__ */ new Set();
@@ -664,6 +676,8 @@ function destroyEntity(world, entity) {
664
676
  }
665
677
  }
666
678
  releaseEntity(ctx.entityIndex, currentEntity);
679
+ const allQuery = ctx.queriesHashMap.get("");
680
+ if (allQuery) allQuery.remove(world, currentEntity);
667
681
  ctx.entityTraits.delete(entity);
668
682
  const eid = getEntityId(currentEntity);
669
683
  for (let i = 0; i < ctx.entityMasks.length; i++) {
@@ -950,6 +964,7 @@ var Query = class {
950
964
  for (const sub of this.removeSubscriptions) {
951
965
  sub(entity);
952
966
  }
967
+ this.version++;
953
968
  }
954
969
  check(world, entity, event) {
955
970
  const { bitmasks, generations } = this;
@@ -1111,7 +1126,7 @@ function createQueryResult(query, world, params) {
1111
1126
  }
1112
1127
  for (let i = 0; i < changedPairs.length; i++) {
1113
1128
  const [entity, trait2] = changedPairs[i];
1114
- entity.changed(trait2);
1129
+ setChanged(world, entity, trait2);
1115
1130
  }
1116
1131
  } else if (options.changeDetection === "always") {
1117
1132
  const changedPairs = [];
@@ -1146,7 +1161,7 @@ function createQueryResult(query, world, params) {
1146
1161
  }
1147
1162
  for (let i = 0; i < changedPairs.length; i++) {
1148
1163
  const [entity, trait2] = changedPairs[i];
1149
- entity.changed(trait2);
1164
+ setChanged(world, entity, trait2);
1150
1165
  }
1151
1166
  } else if (options.changeDetection === "never") {
1152
1167
  for (let i = 0; i < entities.length; i++) {
@@ -1255,19 +1270,19 @@ var World = class {
1255
1270
  return createEntity(this, ...traits);
1256
1271
  }
1257
1272
  has(target) {
1258
- return typeof target === "number" ? isEntityAlive(this[$internal].entityIndex, target) : this[$internal].worldEntity.has(target);
1273
+ return typeof target === "number" ? isEntityAlive(this[$internal].entityIndex, target) : hasTrait(this, this[$internal].worldEntity, target);
1259
1274
  }
1260
1275
  add(...traits) {
1261
- this[$internal].worldEntity.add(...traits);
1276
+ addTrait(this, this[$internal].worldEntity, ...traits);
1262
1277
  }
1263
1278
  remove(...traits) {
1264
- this[$internal].worldEntity.remove(...traits);
1279
+ removeTrait(this, this[$internal].worldEntity, ...traits);
1265
1280
  }
1266
1281
  get(trait2) {
1267
- return this[$internal].worldEntity.get(trait2);
1282
+ return getTrait(this, this[$internal].worldEntity, trait2);
1268
1283
  }
1269
1284
  set(trait2, value) {
1270
- this[$internal].worldEntity.set(trait2, value);
1285
+ setTrait(this, this[$internal].worldEntity, trait2, value);
1271
1286
  }
1272
1287
  destroy() {
1273
1288
  destroyEntity(this, this[$internal].worldEntity);
package/react/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Q as QueryParameter, o as QueryResult, W as World, T as Trait, k as Entity, g as TraitInstance } from '../dist/world-DQXl4lI8.cjs';
1
+ import { Q as QueryParameter, o as QueryResult, W as World, T as Trait, k as Entity, g as TraitInstance } from '../dist/world-CHO2npCL.cjs';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
 
4
4
  declare function useQuery<T extends QueryParameter[]>(...parameters: T): QueryResult<T>;
package/react/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Q as QueryParameter, o as QueryResult, W as World, T as Trait, k as Entity, g as TraitInstance } from '../dist/world-DQXl4lI8.js';
1
+ import { Q as QueryParameter, o as QueryResult, W as World, T as Trait, k as Entity, g as TraitInstance } from '../dist/world-CHO2npCL.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
 
4
4
  declare function useQuery<T extends QueryParameter[]>(...parameters: T): QueryResult<T>;
package/react/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  $internal,
3
3
  cacheQuery,
4
4
  createWorld
5
- } from "../dist/chunk-4QEK6BHY.js";
5
+ } from "../dist/chunk-ZHBGFPP2.js";
6
6
 
7
7
  // ../react/src/hooks/use-query.ts
8
8
  import { useEffect, useMemo, useState } from "react";