@draug/engine 1.0.16 → 1.0.18

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.d.ts CHANGED
@@ -3,6 +3,20 @@ import { Bitmap } from 'bitmap-index';
3
3
  type ClassType<T> = new (...args: any[]) => T;
4
4
  type ComponentType<T extends object = object> = ClassType<T>;
5
5
 
6
+ declare enum LogLevel {
7
+ Debug = 0,
8
+ Info = 1,
9
+ Warn = 2,
10
+ Error = 3
11
+ }
12
+ type LogMessage = () => string;
13
+ interface Logger {
14
+ debug(message: LogMessage): void;
15
+ info(message: LogMessage): void;
16
+ warn(message: LogMessage): void;
17
+ error(message: LogMessage): void;
18
+ }
19
+
6
20
  interface IStorage<T extends object> {
7
21
  add(id: number, initFn?: (obj: T) => T): T;
8
22
  remove(id: number): void;
@@ -90,7 +104,9 @@ declare class EntityMaskNotFoundError extends Error {
90
104
  constructor(id: EntityID);
91
105
  }
92
106
  declare class EntitiesManager {
107
+ private readonly logger;
93
108
  private id_;
109
+ constructor(logger: Logger);
94
110
  private nextId;
95
111
  create(): EntityID;
96
112
  }
@@ -141,7 +157,9 @@ declare class EventBus {
141
157
  }
142
158
 
143
159
  declare class ResourcesManager {
160
+ private readonly logger;
144
161
  private readonly items_;
162
+ constructor(logger: Logger);
145
163
  insert<T extends object>(type: ClassType<T>, value: T): T;
146
164
  get<T extends object>(type: ClassType<T>): T;
147
165
  getOrInsert<T extends object>(type: ClassType<T>, factory: () => T): T;
@@ -154,8 +172,9 @@ type CreateEntityComponentEntry<T extends ComponentType = ComponentType> = T ext
154
172
  declare function entry<T extends ComponentType>(component: T, init?: ComponentInitFn<T>): CreateEntityComponentEntry;
155
173
  declare class Commands {
156
174
  private readonly world;
175
+ private readonly logger;
157
176
  private readonly commandsQueue_;
158
- constructor(world: World);
177
+ constructor(world: World, logger: Logger);
159
178
  add(cmd: WorldCommand): void;
160
179
  flush(world: World): void;
161
180
  createEntity(...entries: CreateEntityComponentEntry[]): number;
@@ -223,16 +242,25 @@ declare class ErrPluginNotInit extends PluginError {
223
242
  constructor(pluginId: string);
224
243
  }
225
244
  declare class PluginsManager {
245
+ private readonly logger;
226
246
  private plugins_;
227
247
  private isInitiated_;
248
+ constructor(logger: Logger);
228
249
  install<T extends ClassType<PluginBase>>(plugin: T, ...constructorProps: ConstructorParameters<T>): void;
229
250
  build(): void;
251
+ /**
252
+ * @internal
253
+ */
230
254
  __internal__onAfterWorldInit(world: World): void;
231
255
  getPluginMetadata(pluginOrId: ClassType<PluginBase> | PluginID): PluginMetadata;
232
256
  getPluginInstance<T extends PluginBase>(pluginOrId: ClassType<T> | PluginID): T;
233
257
  private resolveId;
234
258
  }
235
259
 
260
+ type WorldConstructor = {
261
+ maxEntityCount?: number;
262
+ logger: Logger;
263
+ };
236
264
  declare class World {
237
265
  readonly entities: EntitiesManager;
238
266
  readonly components: ComponentsManager;
@@ -242,8 +270,9 @@ declare class World {
242
270
  readonly commands: Commands;
243
271
  readonly queries: QueryManager;
244
272
  readonly plugins: PluginsManager;
273
+ private readonly logger;
245
274
  private entityRefs_;
246
- constructor(maxEntityCount?: number);
275
+ constructor(params: WorldConstructor);
247
276
  getEntityRef(id: number): EntityRef;
248
277
  query(params: QueryParameters): number[];
249
278
  removeComponent<T extends object>(ref: EntityRef, component: ComponentType<T>): void;
@@ -311,11 +340,17 @@ type SystemCtor<T extends SystemBase = SystemBase> = ClassType<T>;
311
340
  */
312
341
  type SystemComputeContext = {
313
342
  /** Entity IDs from the query for this {@link SystemBase.compute} invocation. */
314
- entities: number[];
343
+ readonly entities: number[];
315
344
  /** ECS world instance. */
316
- world: World;
345
+ readonly world: World;
317
346
  /** Delta time (seconds or your engine's convention) since the previous update. */
318
- dt: number;
347
+ readonly dt: number;
348
+ /** Logger instance for debugging and diagnostics. */
349
+ readonly logger: Logger;
350
+ };
351
+ type SystemInitContext = {
352
+ world: World;
353
+ logger: Logger;
319
354
  };
320
355
  /**
321
356
  * Base class for ECS systems executed by {@link SystemsManager}.
@@ -329,15 +364,16 @@ declare abstract class SystemBase {
329
364
  * Logic for one systems pass: run for all entities in {@link SystemComputeContext.entities}.
330
365
  */
331
366
  abstract compute(ctx: SystemComputeContext): void;
332
- onInit?(world: World): void;
367
+ onInit?(ctx: SystemInitContext): void;
333
368
  }
334
369
  declare class SystemsManager {
335
370
  private readonly world;
371
+ private readonly logger;
336
372
  private systems_;
337
373
  private executionOrder_;
338
374
  private requiredComponents_;
339
375
  private dirty_;
340
- constructor(world: World);
376
+ constructor(world: World, logger: Logger);
341
377
  getRequiredComponents(): ComponentType[];
342
378
  register<T extends SystemBase>(sys: T): void;
343
379
  build(): void;
@@ -364,20 +400,19 @@ declare class Clock {
364
400
  type StepFunction = (dt: number, world: World) => void;
365
401
  type PlatformLoop = (callback: () => void) => void;
366
402
  declare class Loop {
367
- private readonly world;
368
403
  private readonly clock;
369
404
  private readonly stepFn;
370
405
  private readonly platformLoop;
371
406
  private running;
372
- constructor(world: World, clock: Clock, stepFn: StepFunction, platformLoop: PlatformLoop);
373
- start(): void;
407
+ constructor(clock: Clock, stepFn: StepFunction, platformLoop: PlatformLoop);
408
+ start(world: World): void;
374
409
  stop(): void;
375
410
  }
376
411
 
377
412
  declare class Runtime {
378
413
  private readonly loop;
379
414
  constructor(loop: Loop);
380
- run(): void;
415
+ run(world: World): void;
381
416
  }
382
417
 
383
418
  declare enum VisitedState {
@@ -457,14 +492,16 @@ declare class AssetsManager {
457
492
 
458
493
  type EngineConstructor = {
459
494
  loop: Loop;
495
+ logger?: Logger;
460
496
  };
461
497
  declare class Engine {
462
498
  readonly runtime: Runtime;
463
- readonly world: World;
464
499
  readonly assets: AssetsManager;
500
+ readonly world: World;
501
+ readonly logger: Logger;
465
502
  constructor(params: EngineConstructor);
466
503
  init(): void;
467
504
  start(): void;
468
505
  }
469
506
 
470
- export { Asset, type AssetDisposer, type AssetID, type AssetIDGenerator, type AssetLoader, AssetState, AssetStorage, AssetsManager, type ClassType, Clock, Commands, Component, ComponentAlreadyRegisteredError, type ComponentInitFn, ComponentStorage, type ComponentType, ComponentsManager, type CreateEntityComponentEntry, DAGNode, Engine, type EngineConstructor, EntitiesManager, type EntityID, EntityMaskNotFoundError, EntityRef, ErrDAGCycleDetected, ErrMissingPluginMetadata, ErrMissingSystemMetadata, ErrNotAPlugin, ErrNotASystem, ErrPluginNotInit, ErrUnknownPlugin, EventBuffer, EventBus, type IStorage, Loop, ObjectPool, Plugin, PluginBase, type PluginDependencies, PluginError, type PluginID, type PluginMetadata, PluginsManager, ResourcesManager, Runtime, SingletonStorage, type StepFunction, System, SystemBase, type SystemComputeContext, SystemError, SystemPhase, SystemsManager, type TimeSource, UnregisteredComponentStorageError, VisitedState, World, type WorldCommand, createEventKey, entry, getPluginMetadata, getSystemMetadata, isPlugin, isSystem, topologicalSort };
507
+ export { Asset, type AssetDisposer, type AssetID, type AssetIDGenerator, type AssetLoader, AssetState, AssetStorage, AssetsManager, type ClassType, Clock, Commands, Component, ComponentAlreadyRegisteredError, type ComponentInitFn, ComponentStorage, type ComponentType, ComponentsManager, type CreateEntityComponentEntry, DAGNode, Engine, type EngineConstructor, EntitiesManager, type EntityID, EntityMaskNotFoundError, EntityRef, ErrDAGCycleDetected, ErrMissingPluginMetadata, ErrMissingSystemMetadata, ErrNotAPlugin, ErrNotASystem, ErrPluginNotInit, ErrUnknownPlugin, EventBuffer, EventBus, type IStorage, LogLevel, type LogMessage, type Logger, Loop, ObjectPool, type PlatformLoop, Plugin, PluginBase, type PluginDependencies, PluginError, type PluginID, type PluginMetadata, PluginsManager, ResourcesManager, Runtime, SingletonStorage, type StepFunction, System, SystemBase, type SystemComputeContext, SystemError, type SystemInitContext, SystemPhase, SystemsManager, type TimeSource, UnregisteredComponentStorageError, VisitedState, World, type WorldCommand, createEventKey, entry, getPluginMetadata, getSystemMetadata, isPlugin, isSystem, topologicalSort };
package/dist/index.js CHANGED
@@ -94,10 +94,12 @@ function isSystem(ctor) {
94
94
  var SystemBase = class {
95
95
  };
96
96
  var SystemsManager = class {
97
- constructor(world) {
97
+ constructor(world, logger) {
98
98
  this.world = world;
99
+ this.logger = logger;
99
100
  }
100
101
  world;
102
+ logger;
101
103
  systems_ = /* @__PURE__ */ new Map();
102
104
  executionOrder_ = [];
103
105
  requiredComponents_ = /* @__PURE__ */ new Set();
@@ -119,11 +121,15 @@ var SystemsManager = class {
119
121
  this.requiredComponents_.add(c);
120
122
  for (const c of requiredComponents)
121
123
  this.requiredComponents_.add(c);
124
+ this.logger.debug(() => `[Systems]: "${ctor.name}" was registered`);
122
125
  }
123
126
  build() {
124
127
  this.buildSystemsArray();
125
- for (const sys of this.systems_.values())
126
- sys.onInit?.(this.world);
128
+ for (const sys of this.systems_.values()) {
129
+ sys.onInit?.({ world: this.world, logger: this.logger });
130
+ }
131
+ this.logger.debug(() => `Built ${this.systems_.size} systems`);
132
+ this.dirty_ = false;
127
133
  }
128
134
  rebuild() {
129
135
  this.build();
@@ -141,7 +147,12 @@ var SystemsManager = class {
141
147
  for (const s of this.executionOrder_) {
142
148
  const { query } = getSystemMetadata(s.constructor);
143
149
  const entities = this.world.query(query);
144
- s.compute({ entities, world: this.world, dt });
150
+ s.compute({
151
+ world: this.world,
152
+ entities,
153
+ dt,
154
+ logger: this.logger
155
+ });
145
156
  }
146
157
  }
147
158
  buildSystemsArray() {
@@ -195,12 +206,18 @@ var EntityMaskNotFoundError = class extends Error {
195
206
  }
196
207
  };
197
208
  var EntitiesManager = class {
209
+ constructor(logger) {
210
+ this.logger = logger;
211
+ }
212
+ logger;
198
213
  id_ = 0;
199
214
  nextId() {
200
215
  return ++this.id_;
201
216
  }
202
217
  create() {
203
- return this.nextId();
218
+ const id2 = this.nextId();
219
+ this.logger.debug(() => `[Entities]: Created new entity with ID ${id2}`);
220
+ return id2;
204
221
  }
205
222
  };
206
223
  var EntityRef = class {
@@ -504,9 +521,14 @@ function getComponentId(ctor) {
504
521
 
505
522
  // src/ecs/resources/resources.ts
506
523
  var ResourcesManager = class {
524
+ constructor(logger) {
525
+ this.logger = logger;
526
+ }
527
+ logger;
507
528
  items_ = /* @__PURE__ */ new Map();
508
529
  insert(type, value) {
509
530
  this.items_.set(type, value);
531
+ this.logger.debug(() => `[Resources]: Inserted new Resource "${type.name}"`);
510
532
  return value;
511
533
  }
512
534
  get(type) {
@@ -519,11 +541,12 @@ var ResourcesManager = class {
519
541
  let value = this.items_.get(type) ?? null;
520
542
  if (value === null) {
521
543
  value = factory();
522
- this.items_.set(type, value);
544
+ this.insert(type, value);
523
545
  }
524
546
  return value;
525
547
  }
526
548
  remove(type) {
549
+ this.logger.debug(() => `[Resources]: Removed resource "${type.name}"`);
527
550
  this.items_.delete(type);
528
551
  }
529
552
  };
@@ -534,10 +557,12 @@ function entry(component, init = () => {
534
557
  return [component, init];
535
558
  }
536
559
  var Commands = class {
537
- constructor(world) {
560
+ constructor(world, logger) {
538
561
  this.world = world;
562
+ this.logger = logger;
539
563
  }
540
564
  world;
565
+ logger;
541
566
  commandsQueue_ = [];
542
567
  add(cmd) {
543
568
  this.commandsQueue_.push(cmd);
@@ -555,6 +580,7 @@ var Commands = class {
555
580
  }
556
581
  };
557
582
  this.add(cmd);
583
+ this.logger.debug(() => `[Commands.createEntity]: Created new entity with ID ${id2}. Linked components: [${entries.map((x) => x[0].name).join(", ")}]`);
558
584
  return id2;
559
585
  }
560
586
  };
@@ -744,6 +770,10 @@ var ErrDAGCycleDetectedPlugin = class extends Error {
744
770
  }
745
771
  };
746
772
  var PluginsManager = class {
773
+ constructor(logger) {
774
+ this.logger = logger;
775
+ }
776
+ logger;
747
777
  plugins_ = /* @__PURE__ */ new Map();
748
778
  isInitiated_ = false;
749
779
  install(plugin, ...constructorProps) {
@@ -758,6 +788,7 @@ var PluginsManager = class {
758
788
  metadata
759
789
  };
760
790
  this.plugins_.set(metadata.id, entry2);
791
+ this.logger.debug(() => `[Plugins]: Installed plugin ${metadata.name} (${metadata.version})`);
761
792
  }
762
793
  build() {
763
794
  const nodes = /* @__PURE__ */ new Map();
@@ -792,7 +823,11 @@ var PluginsManager = class {
792
823
  instance.onPluginLoad?.();
793
824
  }
794
825
  this.isInitiated_ = true;
826
+ this.logger.debug(() => `[Plugins]: Plugins built successfully!`);
795
827
  }
828
+ /**
829
+ * @internal
830
+ */
796
831
  __internal__onAfterWorldInit(world) {
797
832
  for (const p of this.plugins_.values()) {
798
833
  p.instance?.onAfterWorldInit?.(world);
@@ -827,17 +862,26 @@ var PluginsManager = class {
827
862
 
828
863
  // src/ecs/world.ts
829
864
  var World3 = class {
830
- entities = new EntitiesManager();
831
- components = new ComponentsManager();
832
- systems = new SystemsManager(this);
833
- events = new EventBus();
834
- resources = new ResourcesManager();
835
- commands = new Commands(this);
836
- queries = new QueryManager(this);
837
- plugins = new PluginsManager();
865
+ entities;
866
+ components;
867
+ systems;
868
+ events;
869
+ resources;
870
+ commands;
871
+ queries;
872
+ plugins;
873
+ logger;
838
874
  entityRefs_ = /* @__PURE__ */ new Map();
839
- constructor(maxEntityCount = ECS_DEFAULTS.MAX_ENTITY_COUNT) {
840
- this.components = new ComponentsManager(maxEntityCount);
875
+ constructor(params) {
876
+ this.entities = new EntitiesManager(params.logger);
877
+ this.components = new ComponentsManager(params.maxEntityCount ?? ECS_DEFAULTS.MAX_ENTITY_COUNT);
878
+ this.systems = new SystemsManager(this, params.logger);
879
+ this.events = new EventBus();
880
+ this.resources = new ResourcesManager(params.logger);
881
+ this.commands = new Commands(this, params.logger);
882
+ this.queries = new QueryManager(this);
883
+ this.plugins = new PluginsManager(params.logger);
884
+ this.logger = params.logger;
841
885
  }
842
886
  getEntityRef(id2) {
843
887
  let ref = this.entityRefs_.get(id2);
@@ -879,6 +923,18 @@ var World3 = class {
879
923
  }
880
924
  build() {
881
925
  this.plugins.build();
926
+ this.logger.debug(() => "World was built successfully");
927
+ }
928
+ };
929
+
930
+ // src/runtime/runtime.ts
931
+ var Runtime = class {
932
+ constructor(loop) {
933
+ this.loop = loop;
934
+ }
935
+ loop;
936
+ run(world) {
937
+ this.loop.start(world);
882
938
  }
883
939
  };
884
940
 
@@ -909,23 +965,21 @@ var Clock = class {
909
965
 
910
966
  // src/runtime/loop.ts
911
967
  var Loop = class {
912
- constructor(world, clock, stepFn, platformLoop) {
913
- this.world = world;
968
+ constructor(clock, stepFn, platformLoop) {
914
969
  this.clock = clock;
915
970
  this.stepFn = stepFn;
916
971
  this.platformLoop = platformLoop;
917
972
  }
918
- world;
919
973
  clock;
920
974
  stepFn;
921
975
  platformLoop;
922
976
  running = false;
923
- start() {
977
+ start(world) {
924
978
  this.running = true;
925
979
  const loop = () => {
926
980
  if (!this.running) return;
927
981
  this.clock.tick();
928
- this.stepFn(this.clock.dt, this.world);
982
+ this.stepFn(this.clock.dt, world);
929
983
  this.platformLoop(loop);
930
984
  };
931
985
  this.platformLoop(loop);
@@ -935,17 +989,6 @@ var Loop = class {
935
989
  }
936
990
  };
937
991
 
938
- // src/runtime/runtime.ts
939
- var Runtime = class {
940
- constructor(loop) {
941
- this.loop = loop;
942
- }
943
- loop;
944
- run() {
945
- this.loop.start();
946
- }
947
- };
948
-
949
992
  // src/assets/assets.ts
950
993
  var AssetState = /* @__PURE__ */ ((AssetState2) => {
951
994
  AssetState2[AssetState2["NOT_READY"] = 1] = "NOT_READY";
@@ -1092,21 +1135,43 @@ var AssetsManager = class {
1092
1135
  }
1093
1136
  };
1094
1137
 
1138
+ // src/logger/logger.ts
1139
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
1140
+ LogLevel2[LogLevel2["Debug"] = 0] = "Debug";
1141
+ LogLevel2[LogLevel2["Info"] = 1] = "Info";
1142
+ LogLevel2[LogLevel2["Warn"] = 2] = "Warn";
1143
+ LogLevel2[LogLevel2["Error"] = 3] = "Error";
1144
+ return LogLevel2;
1145
+ })(LogLevel || {});
1146
+ var NoopLogger = class {
1147
+ debug() {
1148
+ }
1149
+ info() {
1150
+ }
1151
+ warn() {
1152
+ }
1153
+ error() {
1154
+ }
1155
+ };
1156
+
1095
1157
  // src/engine.ts
1096
1158
  var Engine = class {
1097
1159
  runtime;
1160
+ assets = new AssetsManager();
1098
1161
  world;
1099
- assets;
1162
+ logger;
1100
1163
  constructor(params) {
1101
- this.world = new World3();
1102
1164
  this.runtime = new Runtime(params.loop);
1103
- this.assets = new AssetsManager();
1165
+ this.logger = params.logger ?? new NoopLogger();
1166
+ this.world = new World3({
1167
+ logger: this.logger
1168
+ });
1104
1169
  }
1105
1170
  init() {
1106
1171
  this.world.build();
1107
1172
  }
1108
1173
  start() {
1109
- this.runtime.run();
1174
+ this.runtime.run(this.world);
1110
1175
  }
1111
1176
  };
1112
1177
  export {
@@ -1134,6 +1199,7 @@ export {
1134
1199
  ErrUnknownPlugin,
1135
1200
  EventBuffer,
1136
1201
  EventBus,
1202
+ LogLevel,
1137
1203
  Loop,
1138
1204
  ObjectPool,
1139
1205
  Plugin,