@draug/engine 1.0.19 → 1.0.21

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
@@ -51,9 +51,9 @@ __export(index_exports, {
51
51
  PluginBase: () => PluginBase,
52
52
  PluginError: () => PluginError,
53
53
  PluginsManager: () => PluginsManager,
54
+ Resource: () => Resource,
54
55
  ResourcesManager: () => ResourcesManager,
55
56
  Runtime: () => Runtime,
56
- SingletonStorage: () => SingletonStorage,
57
57
  System: () => System,
58
58
  SystemBase: () => SystemBase,
59
59
  SystemError: () => SystemError,
@@ -65,6 +65,7 @@ __export(index_exports, {
65
65
  createEventKey: () => createEventKey,
66
66
  entry: () => entry,
67
67
  getPluginMetadata: () => getPluginMetadata,
68
+ getResourceMetadata: () => getResourceMetadata,
68
69
  getSystemMetadata: () => getSystemMetadata,
69
70
  isPlugin: () => isPlugin,
70
71
  isSystem: () => isSystem,
@@ -149,7 +150,8 @@ function System(props) {
149
150
  const requiredComponents = new Set(props.requiredComponents);
150
151
  const computeAfter = new Set(props.computeAfter);
151
152
  const phase = props.phase ?? 1 /* MAIN */;
152
- const metadata = { query, requiredComponents, computeAfter, phase };
153
+ const name = props.name ?? target.name;
154
+ const metadata = { query, requiredComponents, computeAfter, phase, name };
153
155
  systemTarget[SystemMetadataSymbol] = metadata;
154
156
  };
155
157
  }
@@ -195,7 +197,8 @@ var SystemsManager = class {
195
197
  this.requiredComponents_.add(c);
196
198
  for (const c of requiredComponents)
197
199
  this.requiredComponents_.add(c);
198
- this.logger.debug(() => `[Systems]: "${ctor.name}" was registered`);
200
+ const meta = getSystemMetadata(ctor);
201
+ this.logger.debug(() => `[Systems]: system "${meta.name}" was registered`);
199
202
  }
200
203
  build() {
201
204
  this.buildSystemsArray();
@@ -487,55 +490,41 @@ var ComponentStorage = class {
487
490
  }
488
491
  };
489
492
 
490
- // src/ecs/components/singleton-storage.ts
491
- var SingletonStorage = class {
492
- constructor(factory) {
493
- this.factory = factory;
494
- }
495
- factory;
496
- value = null;
497
- entityId = null;
498
- bitmap() {
499
- throw new Error("Singletone component cannot has a bitmap!");
500
- }
501
- add(id2, initFn) {
502
- if (this.value !== null)
503
- throw new Error("Singleton already initiated");
504
- this.entityId = id2;
505
- this.value = this.factory();
506
- initFn?.(this.value);
507
- return this.value;
508
- }
509
- remove(id2) {
510
- if (!this.validateId(id2))
511
- return;
512
- this.value = null;
513
- this.entityId = null;
514
- }
515
- get(id2) {
516
- if (!this.validateId(id2))
517
- return null;
518
- return this.value;
519
- }
520
- tryGet(id2) {
521
- if (!this.validateId(id2))
522
- throw new Error("[SingletoneStorage]: ID missmatch.");
523
- return this.value;
524
- }
525
- has(id2) {
526
- return this.validateId(id2);
527
- }
528
- size() {
529
- return this.value !== null ? 1 : 0;
530
- }
531
- forEach(cb) {
532
- if (this.entityId !== null)
533
- cb(this.entityId);
493
+ // src/ecs/components/utils.ts
494
+ var registry = /* @__PURE__ */ new Map();
495
+ var id = 0;
496
+ var ComponentMetadataSymbol = /* @__PURE__ */ Symbol("component");
497
+ function Component(options) {
498
+ return (target) => {
499
+ const metadata = {
500
+ name: options.name,
501
+ id: ++id
502
+ };
503
+ registry.set(target, metadata.id);
504
+ target[ComponentMetadataSymbol] = metadata;
505
+ };
506
+ }
507
+ function getComponentId(ctor) {
508
+ const id2 = registry.get(ctor);
509
+ if (id2 === void 0) {
510
+ throw new Error(`Component not registered: ${ctor.name}`);
534
511
  }
535
- validateId(id2) {
536
- return this.entityId !== null && id2 === this.entityId;
512
+ return id2;
513
+ }
514
+ var ErrNotComponent = class extends Error {
515
+ constructor(ctor) {
516
+ super(`Class ${ctor.name} is not a Component. Use @Component decorator to define components.`);
537
517
  }
538
518
  };
519
+ function getComponentMetadata(component) {
520
+ if (isComponent(component)) {
521
+ return component[ComponentMetadataSymbol];
522
+ }
523
+ throw new ErrNotComponent(component);
524
+ }
525
+ function isComponent(ctor) {
526
+ return ComponentMetadataSymbol in ctor;
527
+ }
539
528
 
540
529
  // src/ecs/components/manager.ts
541
530
  var ComponentAlreadyRegisteredError = class extends Error {
@@ -544,9 +533,11 @@ var ComponentAlreadyRegisteredError = class extends Error {
544
533
  }
545
534
  };
546
535
  var ComponentsManager = class {
547
- constructor(maxEntityCount = ECS_DEFAULTS.MAX_ENTITY_COUNT) {
536
+ constructor(logger, maxEntityCount = ECS_DEFAULTS.MAX_ENTITY_COUNT) {
537
+ this.logger = logger;
548
538
  this.maxEntityCount = maxEntityCount;
549
539
  }
540
+ logger;
550
541
  maxEntityCount;
551
542
  storages_ = /* @__PURE__ */ new Map();
552
543
  currId_ = 0;
@@ -556,19 +547,10 @@ var ComponentsManager = class {
556
547
  register(component, opts) {
557
548
  if (this.storages_.has(component))
558
549
  return this.storages_.get(component);
559
- let store;
560
- switch (opts?.storageType) {
561
- case 2 /* SINGLETON_STORAGE */:
562
- store = this.createSingletonStore(opts);
563
- break;
564
- case 1 /* COMPONENT_STORAGE */:
565
- store = this.createComponentStore(component, opts);
566
- break;
567
- default:
568
- store = this.createComponentStore(component, opts);
569
- break;
570
- }
550
+ const store = this.createComponentStore(component, opts);
571
551
  this.storages_.set(component, store);
552
+ const meta = getComponentMetadata(component);
553
+ this.logger.debug(() => `[Components]: Registered component "${meta.name}"`);
572
554
  return store;
573
555
  }
574
556
  createComponentStore(component, opts) {
@@ -577,12 +559,6 @@ var ComponentsManager = class {
577
559
  store._internalSetId(this.nextId());
578
560
  return store;
579
561
  }
580
- createSingletonStore(opts) {
581
- if (!opts?.factory) {
582
- throw new Error("For singletone storage provide factory is required!");
583
- }
584
- return new SingletonStorage(opts.factory);
585
- }
586
562
  getStorage(component) {
587
563
  const store = this.storages_.get(component);
588
564
  if (store === void 0)
@@ -594,24 +570,30 @@ var ComponentsManager = class {
594
570
  }
595
571
  };
596
572
 
597
- // src/ecs/components/utils.ts
598
- var registry = /* @__PURE__ */ new Map();
599
- var id = 0;
600
- function Component() {
573
+ // src/ecs/resources/resources.ts
574
+ var ResourceMetadataSymbol = /* @__PURE__ */ Symbol("resource");
575
+ function Resource(params) {
601
576
  return (target) => {
602
- if (registry.has(target)) return;
603
- registry.set(target, ++id);
577
+ const metadata = {
578
+ name: params.name
579
+ };
580
+ target[ResourceMetadataSymbol] = metadata;
604
581
  };
605
582
  }
606
- function getComponentId(ctor) {
607
- const id2 = registry.get(ctor);
608
- if (id2 === void 0) {
609
- throw new Error(`Component not registered: ${ctor.name}`);
583
+ var ErrNotResource = class extends Error {
584
+ constructor(ctor) {
585
+ super(`Class ${ctor.name} is not a Resource. Use @Resource decorator to define resources.`);
610
586
  }
611
- return id2;
587
+ };
588
+ function getResourceMetadata(resource) {
589
+ if (isResource(resource)) {
590
+ return resource[ResourceMetadataSymbol];
591
+ }
592
+ throw new ErrNotResource(resource);
593
+ }
594
+ function isResource(ctor) {
595
+ return ResourceMetadataSymbol in ctor;
612
596
  }
613
-
614
- // src/ecs/resources/resources.ts
615
597
  var ResourcesManager = class {
616
598
  constructor(logger) {
617
599
  this.logger = logger;
@@ -620,13 +602,15 @@ var ResourcesManager = class {
620
602
  items_ = /* @__PURE__ */ new Map();
621
603
  insert(type, value) {
622
604
  this.items_.set(type, value);
623
- this.logger.debug(() => `[Resources]: Inserted new Resource "${type.name}"`);
605
+ const metadata = getResourceMetadata(type);
606
+ this.logger.debug(() => `[Resources]: Inserted new Resource "${metadata.name}"`);
624
607
  return value;
625
608
  }
626
609
  get(type) {
627
610
  const value = this.items_.get(type);
611
+ const meta = getResourceMetadata(type);
628
612
  if (!value)
629
- throw new Error(`Resource of class ${type.name} does not exist!`);
613
+ throw new Error(`Resource of class ${meta.name} does not exist!`);
630
614
  return value;
631
615
  }
632
616
  getOrInsert(type, factory) {
@@ -638,7 +622,8 @@ var ResourcesManager = class {
638
622
  return value;
639
623
  }
640
624
  remove(type) {
641
- this.logger.debug(() => `[Resources]: Removed resource "${type.name}"`);
625
+ const meta = getResourceMetadata(type);
626
+ this.logger.debug(() => `[Resources]: Removed resource "${meta.name}"`);
642
627
  this.items_.delete(type);
643
628
  }
644
629
  };
@@ -672,7 +657,10 @@ var Commands = class {
672
657
  }
673
658
  };
674
659
  this.add(cmd);
675
- this.logger.debug(() => `[Commands.createEntity]: Created new entity with ID ${id2}. Linked components: [${entries.map((x) => x[0].name).join(", ")}]`);
660
+ this.logger.debug(() => {
661
+ const components = entries.map((x) => getComponentMetadata(x[0]).name).join(", ");
662
+ return `[Commands.createEntity]: Created new entity with ID ${id2}. Linked components: [${components}]`;
663
+ });
676
664
  return id2;
677
665
  }
678
666
  };
@@ -872,14 +860,14 @@ var PluginsManager = class {
872
860
  if (!isPlugin(plugin))
873
861
  throw new ErrMissingPluginMetadata(plugin);
874
862
  const metadata = getPluginMetadata(plugin);
875
- if (this.plugins_.has(metadata.id))
863
+ if (this.plugins_.has(plugin))
876
864
  return;
877
865
  const entry2 = {
878
866
  ctor: plugin,
879
867
  ctorParams: constructorProps,
880
868
  metadata
881
869
  };
882
- this.plugins_.set(metadata.id, entry2);
870
+ this.plugins_.set(plugin, entry2);
883
871
  this.logger.debug(() => `[Plugins]: Installed plugin ${metadata.name} (${metadata.version})`);
884
872
  }
885
873
  build() {
@@ -890,15 +878,15 @@ var PluginsManager = class {
890
878
  for (const id2 of this.plugins_.keys()) {
891
879
  nodes.set(id2, new DAGNode(id2));
892
880
  }
893
- for (const [id2, entry2] of this.plugins_) {
894
- const node = nodes.get(id2);
881
+ for (const [plugin, entry2] of this.plugins_) {
882
+ const node = nodes.get(plugin);
895
883
  const depPlugins = entry2.metadata.dependencies?.plugins ?? [];
896
884
  for (const dep of depPlugins) {
897
- const depNode = nodes.get(dep.id);
885
+ const depNode = nodes.get(dep.plugin);
898
886
  if (!depNode) {
899
- throw new ErrMissingPluginDependency(id2, dep.id);
887
+ throw new ErrMissingPluginDependency(plugin, dep.plugin);
900
888
  }
901
- node.vertices.push(depNode);
889
+ depNode.vertices.push(node);
902
890
  }
903
891
  }
904
892
  let sortedNodes;
@@ -928,31 +916,20 @@ var PluginsManager = class {
928
916
  p.instance?.onAfterWorldInit?.(world);
929
917
  }
930
918
  }
931
- getPluginMetadata(pluginOrId) {
932
- const id2 = this.resolveId(pluginOrId);
933
- const entry2 = this.plugins_.get(id2);
934
- if (!entry2) throw new ErrUnknownPlugin(id2);
919
+ getPluginMetadata(plugin) {
920
+ const entry2 = this.plugins_.get(plugin);
921
+ if (!entry2) throw new ErrUnknownPlugin(plugin);
935
922
  return entry2.metadata;
936
923
  }
937
- getPluginInstance(pluginOrId) {
924
+ getPluginInstance(plugin) {
925
+ const entry2 = this.plugins_.get(plugin);
926
+ if (!entry2) throw new ErrUnknownPlugin(plugin);
927
+ if (!entry2.instance) throw new ErrPluginNotInit(plugin);
938
928
  if (!this.isInitiated_) {
939
- throw new Error("Plugin instance is not initiated yet. Use PluginManager.build() before use plugins.");
929
+ throw new ErrPluginNotInit(plugin);
940
930
  }
941
- const id2 = this.resolveId(pluginOrId);
942
- const entry2 = this.plugins_.get(id2);
943
- if (!entry2) throw new ErrUnknownPlugin(id2);
944
- if (!entry2.instance) throw new ErrPluginNotInit(id2);
945
931
  return entry2.instance;
946
932
  }
947
- resolveId(pluginOrId) {
948
- if (typeof pluginOrId === "string") {
949
- return pluginOrId;
950
- }
951
- if (!isPlugin(pluginOrId)) {
952
- throw new ErrMissingPluginMetadata(pluginOrId);
953
- }
954
- return getPluginMetadata(pluginOrId).id;
955
- }
956
933
  };
957
934
 
958
935
  // src/ecs/world.ts
@@ -967,9 +944,13 @@ var World3 = class {
967
944
  plugins;
968
945
  logger;
969
946
  entityRefs_ = /* @__PURE__ */ new Map();
947
+ updatesCount_ = 0;
948
+ get updatesCount() {
949
+ return this.updatesCount_;
950
+ }
970
951
  constructor(params) {
971
952
  this.entities = new EntitiesManager(params.logger);
972
- this.components = new ComponentsManager(params.maxEntityCount ?? ECS_DEFAULTS.MAX_ENTITY_COUNT);
953
+ this.components = new ComponentsManager(params.logger, params.maxEntityCount ?? ECS_DEFAULTS.MAX_ENTITY_COUNT);
973
954
  this.systems = new SystemsManager(this, params.logger);
974
955
  this.events = new EventBus();
975
956
  this.resources = new ResourcesManager(params.logger);
@@ -1015,6 +996,7 @@ var World3 = class {
1015
996
  update(clock) {
1016
997
  this.systems.update(clock.getTime());
1017
998
  this.commands.flush(this);
999
+ this.updatesCount_++;
1018
1000
  }
1019
1001
  build() {
1020
1002
  this.plugins.build();
@@ -1310,9 +1292,9 @@ var Engine = class {
1310
1292
  PluginBase,
1311
1293
  PluginError,
1312
1294
  PluginsManager,
1295
+ Resource,
1313
1296
  ResourcesManager,
1314
1297
  Runtime,
1315
- SingletonStorage,
1316
1298
  System,
1317
1299
  SystemBase,
1318
1300
  SystemError,
@@ -1324,6 +1306,7 @@ var Engine = class {
1324
1306
  createEventKey,
1325
1307
  entry,
1326
1308
  getPluginMetadata,
1309
+ getResourceMetadata,
1327
1310
  getSystemMetadata,
1328
1311
  isPlugin,
1329
1312
  isSystem,