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/dist/index.cjs CHANGED
@@ -75,6 +75,110 @@ var getEntityGeneration = (entity) => entity >>> GENERATION_SHIFT & GENERATION_M
75
75
  var incrementGeneration = (entity) => entity & ~(GENERATION_MASK << GENERATION_SHIFT) | // Clear current generation bits
76
76
  ((entity >>> GENERATION_SHIFT & GENERATION_MASK) + 1 & GENERATION_MASK) << GENERATION_SHIFT;
77
77
 
78
+ // ../core/src/world/utils/world-index.ts
79
+ function createWorldIndex() {
80
+ return {
81
+ worldCursor: 0,
82
+ releasedWorldIds: [],
83
+ maxWorlds: 2 ** WORLD_ID_BITS
84
+ };
85
+ }
86
+ function allocateWorldId(index) {
87
+ if (index.releasedWorldIds.length > 0) {
88
+ return index.releasedWorldIds.pop();
89
+ }
90
+ if (index.worldCursor >= index.maxWorlds) {
91
+ throw new Error(`Koota: Too many worlds created. The maximum is ${index.maxWorlds}.`);
92
+ }
93
+ return index.worldCursor++;
94
+ }
95
+ function releaseWorldId(index, worldId) {
96
+ if (worldId < 0 || worldId >= index.maxWorlds) {
97
+ throw new Error(`Invalid world ID: ${worldId}`);
98
+ }
99
+ if (worldId === index.worldCursor - 1) {
100
+ index.worldCursor--;
101
+ } else if (worldId < index.worldCursor && !index.releasedWorldIds.includes(worldId)) {
102
+ index.releasedWorldIds.push(worldId);
103
+ }
104
+ }
105
+
106
+ // ../core/src/universe/universe.ts
107
+ var universe = {
108
+ worlds: new Array(WORLD_ID_BITS ** 2),
109
+ cachedQueries: /* @__PURE__ */ new Map(),
110
+ worldIndex: createWorldIndex(),
111
+ reset: () => {
112
+ universe.worlds = new Array(WORLD_ID_BITS ** 2);
113
+ universe.cachedQueries = /* @__PURE__ */ new Map();
114
+ universe.worldIndex = createWorldIndex();
115
+ }
116
+ };
117
+
118
+ // ../core/src/query/modifier.ts
119
+ var ModifierData = class {
120
+ constructor(type, id, traits) {
121
+ this.type = type;
122
+ this.id = id;
123
+ this.traits = traits;
124
+ __publicField(this, "traitIds");
125
+ this.traitIds = traits.map((trait2) => trait2[$internal].id);
126
+ }
127
+ };
128
+
129
+ // ../core/src/query/utils/tracking-cursor.ts
130
+ var cursor = 3;
131
+ function createTrackingId() {
132
+ return cursor++;
133
+ }
134
+ function getTrackingCursor() {
135
+ return cursor;
136
+ }
137
+ function setTrackingMasks(world, id) {
138
+ const ctx = world[$internal];
139
+ const snapshot = structuredClone(ctx.entityMasks);
140
+ ctx.trackingSnapshots.set(id, snapshot);
141
+ ctx.dirtyMasks.set(
142
+ id,
143
+ snapshot.map((mask) => mask.map(() => 0))
144
+ );
145
+ ctx.changedMasks.set(
146
+ id,
147
+ snapshot.map((mask) => mask.map(() => 0))
148
+ );
149
+ }
150
+
151
+ // ../core/src/query/modifiers/changed.ts
152
+ function createChanged() {
153
+ const id = createTrackingId();
154
+ for (const world of universe.worlds) {
155
+ if (!world) continue;
156
+ setTrackingMasks(world, id);
157
+ }
158
+ return (...traits) => new ModifierData(`changed-${id}`, id, traits);
159
+ }
160
+ function setChanged(world, entity, trait2) {
161
+ const ctx = world[$internal];
162
+ if (!hasTrait(world, entity, trait2)) return;
163
+ if (!ctx.traitData.has(trait2)) registerTrait(world, trait2);
164
+ const data = ctx.traitData.get(trait2);
165
+ for (const changedMask of ctx.changedMasks.values()) {
166
+ const eid = getEntityId(entity);
167
+ if (!changedMask[eid]) changedMask[eid] = new Array();
168
+ const traitId2 = trait2[$internal].id;
169
+ changedMask[eid][traitId2] = 1;
170
+ }
171
+ for (const query of data.queries) {
172
+ if (!query.hasChangedModifiers) continue;
173
+ let match = query.check(world, entity, { type: "change", traitData: data });
174
+ if (match) query.add(entity);
175
+ else query.remove(world, entity);
176
+ }
177
+ for (const sub of data.changedSubscriptions) {
178
+ sub(entity);
179
+ }
180
+ }
181
+
78
182
  // ../core/src/relation/relation.ts
79
183
  function defineRelation(definition) {
80
184
  const pairsMap = /* @__PURE__ */ new Map();
@@ -322,7 +426,7 @@ function addTrait(world, entity, ...traits) {
322
426
  } else {
323
427
  trait2 = traits[i];
324
428
  }
325
- if (entity.has(trait2)) return;
429
+ if (hasTrait(world, entity, trait2)) return;
326
430
  const traitCtx = trait2[$internal];
327
431
  if (!ctx.traitData.has(trait2)) registerTrait(world, trait2);
328
432
  const data = ctx.traitData.get(trait2);
@@ -344,8 +448,8 @@ function addTrait(world, entity, ...traits) {
344
448
  const target = traitCtx.pairTarget;
345
449
  if (traitCtx.isPairTrait && relation2 !== null && target !== null) {
346
450
  ctx.relationTargetEntities.add(target);
347
- entity.add(Pair(Wildcard, target));
348
- entity.add(Pair(relation2, Wildcard));
451
+ addTrait(world, entity, Pair(Wildcard, target));
452
+ addTrait(world, entity, Pair(relation2, Wildcard));
349
453
  if (relation2[$internal].exclusive === true && target !== Wildcard) {
350
454
  const oldTarget = getRelationTargets(world, relation2, entity)[0];
351
455
  if (oldTarget !== null && oldTarget !== void 0 && oldTarget !== target) {
@@ -362,10 +466,10 @@ function addTrait(world, entity, ...traits) {
362
466
  defaults[key] = data.schema[key];
363
467
  }
364
468
  }
365
- entity.set(trait2, { ...defaults, ...params }, false);
469
+ setTrait(world, entity, trait2, { ...defaults, ...params }, false);
366
470
  } else {
367
471
  const state = params ?? data.schema();
368
- entity.set(trait2, state, false);
472
+ setTrait(world, entity, trait2, state, false);
369
473
  }
370
474
  }
371
475
  }
@@ -374,7 +478,7 @@ function removeTrait(world, entity, ...traits) {
374
478
  for (let i = 0; i < traits.length; i++) {
375
479
  const trait2 = traits[i];
376
480
  const traitCtx = trait2[$internal];
377
- if (!entity.has(trait2)) return;
481
+ if (!hasTrait(world, entity, trait2)) return;
378
482
  const data = ctx.traitData.get(trait2);
379
483
  const { generationId, bitflag, queries } = data;
380
484
  const eid = getEntityId(entity);
@@ -417,6 +521,25 @@ function getStore(world, trait2) {
417
521
  const store = data.store;
418
522
  return store;
419
523
  }
524
+ function setTrait(world, entity, trait2, value, triggerChanged = true) {
525
+ const ctx = trait2[$internal];
526
+ const index = entity & ENTITY_ID_MASK;
527
+ const store = getStore(world, trait2);
528
+ value instanceof Function && (value = value(ctx.get(index, store)));
529
+ ctx.set(index, store, value);
530
+ triggerChanged && setChanged(world, entity, trait2);
531
+ }
532
+ function getTrait(world, entity, trait2) {
533
+ const worldCtx = world[$internal];
534
+ const data = worldCtx.traitData.get(trait2);
535
+ if (!data) return void 0;
536
+ const index = getEntityId(entity);
537
+ const mask = worldCtx.entityMasks[data.generationId][index];
538
+ if ((mask & data.bitflag) !== data.bitflag) return void 0;
539
+ const traitCtx = trait2[$internal];
540
+ const store = getStore(world, trait2);
541
+ return traitCtx.get(index, store);
542
+ }
420
543
 
421
544
  // ../core/src/entity/utils/entity-index.ts
422
545
  var createEntityIndex = (worldId) => ({
@@ -464,110 +587,6 @@ var getAliveEntities = (index) => {
464
587
  return index.dense.slice(0, index.aliveCount);
465
588
  };
466
589
 
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
590
  // ../core/src/entity/entity-methods-patch.ts
572
591
  Number.prototype.add = function(...traits) {
573
592
  const worldId = this >>> WORLD_ID_SHIFT;
@@ -597,24 +616,12 @@ Number.prototype.changed = function(trait2) {
597
616
  Number.prototype.get = function(trait2) {
598
617
  const worldId = this >>> WORLD_ID_SHIFT;
599
618
  const world = universe.worlds[worldId];
600
- const worldCtx = world[$internal];
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);
619
+ return getTrait(world, this, trait2);
609
620
  };
610
621
  Number.prototype.set = function(trait2, value, triggerChanged = true) {
611
- const ctx = trait2[$internal];
612
- const index = this & ENTITY_ID_MASK;
613
622
  const worldId = this >>> WORLD_ID_SHIFT;
614
- const store = ctx.stores[worldId];
615
- value instanceof Function && (value = value(ctx.get(index, store)));
616
- ctx.set(index, store, value);
617
- triggerChanged && setChanged(universe.worlds[worldId], this, trait2);
623
+ const world = universe.worlds[worldId];
624
+ setTrait(world, this, trait2, value, triggerChanged);
618
625
  };
619
626
  Number.prototype.targetsFor = function(relation2) {
620
627
  const worldId = this >>> WORLD_ID_SHIFT;
@@ -630,6 +637,11 @@ Number.prototype.id = function() {
630
637
  const id = this & ENTITY_ID_MASK;
631
638
  return id;
632
639
  };
640
+ Number.prototype.isAlive = function() {
641
+ const worldId = this >>> WORLD_ID_SHIFT;
642
+ const world = universe.worlds[worldId];
643
+ return isEntityAlive(world[$internal].entityIndex, this);
644
+ };
633
645
 
634
646
  // ../core/src/entity/entity.ts
635
647
  function createEntity(world, ...traits) {
@@ -638,10 +650,10 @@ function createEntity(world, ...traits) {
638
650
  for (const query of ctx.notQueries) {
639
651
  const match = query.check(world, entity);
640
652
  if (match) query.add(entity);
641
- query.resetTrackingBitmasks(entity.id());
653
+ query.resetTrackingBitmasks(getEntityId(entity));
642
654
  }
643
655
  ctx.entityTraits.set(entity, /* @__PURE__ */ new Set());
644
- entity.add(...traits);
656
+ addTrait(world, entity, ...traits);
645
657
  return entity;
646
658
  }
647
659
  var cachedSet = /* @__PURE__ */ new Set();
@@ -682,6 +694,8 @@ function destroyEntity(world, entity) {
682
694
  }
683
695
  }
684
696
  releaseEntity(ctx.entityIndex, currentEntity);
697
+ const allQuery = ctx.queriesHashMap.get("");
698
+ if (allQuery) allQuery.remove(world, currentEntity);
685
699
  ctx.entityTraits.delete(entity);
686
700
  const eid = getEntityId(currentEntity);
687
701
  for (let i = 0; i < ctx.entityMasks.length; i++) {
@@ -968,6 +982,7 @@ var Query = class {
968
982
  for (const sub of this.removeSubscriptions) {
969
983
  sub(entity);
970
984
  }
985
+ this.version++;
971
986
  }
972
987
  check(world, entity, event) {
973
988
  const { bitmasks, generations } = this;
@@ -1129,7 +1144,7 @@ function createQueryResult(query, world, params) {
1129
1144
  }
1130
1145
  for (let i = 0; i < changedPairs.length; i++) {
1131
1146
  const [entity, trait2] = changedPairs[i];
1132
- entity.changed(trait2);
1147
+ setChanged(world, entity, trait2);
1133
1148
  }
1134
1149
  } else if (options.changeDetection === "always") {
1135
1150
  const changedPairs = [];
@@ -1164,7 +1179,7 @@ function createQueryResult(query, world, params) {
1164
1179
  }
1165
1180
  for (let i = 0; i < changedPairs.length; i++) {
1166
1181
  const [entity, trait2] = changedPairs[i];
1167
- entity.changed(trait2);
1182
+ setChanged(world, entity, trait2);
1168
1183
  }
1169
1184
  } else if (options.changeDetection === "never") {
1170
1185
  for (let i = 0; i < entities.length; i++) {
@@ -1273,19 +1288,19 @@ var World = class {
1273
1288
  return createEntity(this, ...traits);
1274
1289
  }
1275
1290
  has(target) {
1276
- return typeof target === "number" ? isEntityAlive(this[$internal].entityIndex, target) : this[$internal].worldEntity.has(target);
1291
+ return typeof target === "number" ? isEntityAlive(this[$internal].entityIndex, target) : hasTrait(this, this[$internal].worldEntity, target);
1277
1292
  }
1278
1293
  add(...traits) {
1279
- this[$internal].worldEntity.add(...traits);
1294
+ addTrait(this, this[$internal].worldEntity, ...traits);
1280
1295
  }
1281
1296
  remove(...traits) {
1282
- this[$internal].worldEntity.remove(...traits);
1297
+ removeTrait(this, this[$internal].worldEntity, ...traits);
1283
1298
  }
1284
1299
  get(trait2) {
1285
- return this[$internal].worldEntity.get(trait2);
1300
+ return getTrait(this, this[$internal].worldEntity, trait2);
1286
1301
  }
1287
1302
  set(trait2, value) {
1288
- this[$internal].worldEntity.set(trait2, value);
1303
+ setTrait(this, this[$internal].worldEntity, trait2, value);
1289
1304
  }
1290
1305
  destroy() {
1291
1306
  destroyEntity(this, this[$internal].worldEntity);
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Schema, T as Trait, N as Norm, M as ModifierData, W as World, Q as QueryParameter, R as Relation, a as RelationTarget, b as WildcardRelation } from './world-DQXl4lI8.cjs';
2
- export { $ as $internal, A as AoSFactory, C as ConfigurableTrait, k as Entity, j as ExtractIsTag, E as ExtractSchema, i as ExtractStore, q as InstancesFromParameters, r as IsNotModifier, I as IsTag, l as QueryModifier, o as QueryResult, n as QueryResultOptions, m as QuerySubscriber, h as Store, p as StoresFromParameters, g as TraitInstance, f as TraitTuple, d as TraitType, e as TraitValue, c as createWorld } from './world-DQXl4lI8.cjs';
1
+ import { S as Schema, T as Trait, N as Norm, M as ModifierData, W as World, Q as QueryParameter, R as Relation, a as RelationTarget, b as WildcardRelation } from './world-CHO2npCL.cjs';
2
+ export { $ as $internal, A as AoSFactory, C as ConfigurableTrait, k as Entity, j as ExtractIsTag, E as ExtractSchema, i as ExtractStore, q as InstancesFromParameters, r as IsNotModifier, I as IsTag, l as QueryModifier, o as QueryResult, n as QueryResultOptions, m as QuerySubscriber, h as Store, p as StoresFromParameters, g as TraitInstance, f as TraitTuple, d as TraitType, e as TraitValue, c as createWorld } from './world-CHO2npCL.cjs';
3
3
 
4
4
  declare function defineTrait<S extends Schema = {}>(schema?: S): Trait<Norm<S>>;
5
5
  declare const trait: typeof defineTrait;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Schema, T as Trait, N as Norm, M as ModifierData, W as World, Q as QueryParameter, R as Relation, a as RelationTarget, b as WildcardRelation } from './world-DQXl4lI8.js';
2
- export { $ as $internal, A as AoSFactory, C as ConfigurableTrait, k as Entity, j as ExtractIsTag, E as ExtractSchema, i as ExtractStore, q as InstancesFromParameters, r as IsNotModifier, I as IsTag, l as QueryModifier, o as QueryResult, n as QueryResultOptions, m as QuerySubscriber, h as Store, p as StoresFromParameters, g as TraitInstance, f as TraitTuple, d as TraitType, e as TraitValue, c as createWorld } from './world-DQXl4lI8.js';
1
+ import { S as Schema, T as Trait, N as Norm, M as ModifierData, W as World, Q as QueryParameter, R as Relation, a as RelationTarget, b as WildcardRelation } from './world-CHO2npCL.js';
2
+ export { $ as $internal, A as AoSFactory, C as ConfigurableTrait, k as Entity, j as ExtractIsTag, E as ExtractSchema, i as ExtractStore, q as InstancesFromParameters, r as IsNotModifier, I as IsTag, l as QueryModifier, o as QueryResult, n as QueryResultOptions, m as QuerySubscriber, h as Store, p as StoresFromParameters, g as TraitInstance, f as TraitTuple, d as TraitType, e as TraitValue, c as createWorld } from './world-CHO2npCL.js';
3
3
 
4
4
  declare function defineTrait<S extends Schema = {}>(schema?: S): Trait<Norm<S>>;
5
5
  declare const trait: typeof defineTrait;
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  relation,
14
14
  trait,
15
15
  universe
16
- } from "./chunk-4QEK6BHY.js";
16
+ } from "./chunk-ZHBGFPP2.js";
17
17
  export {
18
18
  $internal,
19
19
  Not,