@lagless/core 0.0.35 → 0.0.38

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.
Files changed (57) hide show
  1. package/dist/lib/ecs-runner.d.ts +1 -1
  2. package/dist/lib/ecs-runner.d.ts.map +1 -1
  3. package/dist/lib/ecs-runner.js +8 -2
  4. package/dist/lib/ecs-runner.js.map +1 -1
  5. package/dist/lib/ecs-simulation.d.ts +24 -4
  6. package/dist/lib/ecs-simulation.d.ts.map +1 -1
  7. package/dist/lib/ecs-simulation.js +57 -1
  8. package/dist/lib/ecs-simulation.js.map +1 -1
  9. package/dist/lib/hash-verification/abstract-hash-verification.system.d.ts.map +1 -1
  10. package/dist/lib/hash-verification/abstract-hash-verification.system.js +5 -0
  11. package/dist/lib/hash-verification/abstract-hash-verification.system.js.map +1 -1
  12. package/dist/lib/hash-verification/create-hash-reporter.d.ts.map +1 -1
  13. package/dist/lib/hash-verification/create-hash-reporter.js +11 -8
  14. package/dist/lib/hash-verification/create-hash-reporter.js.map +1 -1
  15. package/dist/lib/input/abstract-input-provider.d.ts +1 -0
  16. package/dist/lib/input/abstract-input-provider.d.ts.map +1 -1
  17. package/dist/lib/input/abstract-input-provider.js +8 -1
  18. package/dist/lib/input/abstract-input-provider.js.map +1 -1
  19. package/dist/lib/input/input-provider-di-token.d.ts +1 -0
  20. package/dist/lib/input/input-provider-di-token.d.ts.map +1 -1
  21. package/dist/lib/input/input-provider-di-token.js +3 -0
  22. package/dist/lib/input/input-provider-di-token.js.map +1 -1
  23. package/dist/lib/input/local-input-provider.d.ts +1 -0
  24. package/dist/lib/input/local-input-provider.d.ts.map +1 -1
  25. package/dist/lib/input/local-input-provider.js +5 -0
  26. package/dist/lib/input/local-input-provider.js.map +1 -1
  27. package/dist/lib/input/replay-input-provider.d.ts +1 -0
  28. package/dist/lib/input/replay-input-provider.d.ts.map +1 -1
  29. package/dist/lib/input/replay-input-provider.js +5 -0
  30. package/dist/lib/input/replay-input-provider.js.map +1 -1
  31. package/dist/lib/mem/managers/entities-manager.d.ts +3 -2
  32. package/dist/lib/mem/managers/entities-manager.d.ts.map +1 -1
  33. package/dist/lib/mem/managers/entities-manager.js +65 -23
  34. package/dist/lib/mem/managers/entities-manager.js.map +1 -1
  35. package/dist/lib/mem/managers/filters-manager.d.ts +2 -2
  36. package/dist/lib/mem/managers/filters-manager.d.ts.map +1 -1
  37. package/dist/lib/mem/managers/filters-manager.js +19 -4
  38. package/dist/lib/mem/managers/filters-manager.js.map +1 -1
  39. package/dist/lib/mem/mem.d.ts.map +1 -1
  40. package/dist/lib/mem/mem.js +4 -2
  41. package/dist/lib/mem/mem.js.map +1 -1
  42. package/dist/lib/signals/signal.d.ts +4 -3
  43. package/dist/lib/signals/signal.d.ts.map +1 -1
  44. package/dist/lib/signals/signal.js +34 -34
  45. package/dist/lib/signals/signal.js.map +1 -1
  46. package/dist/lib/signals/signals.registry.d.ts +1 -1
  47. package/dist/lib/signals/signals.registry.d.ts.map +1 -1
  48. package/dist/lib/signals/signals.registry.js +2 -2
  49. package/dist/lib/signals/signals.registry.js.map +1 -1
  50. package/dist/lib/types/abstract-filter.d.ts +3 -2
  51. package/dist/lib/types/abstract-filter.d.ts.map +1 -1
  52. package/dist/lib/types/abstract-filter.js +22 -21
  53. package/dist/lib/types/abstract-filter.js.map +1 -1
  54. package/dist/lib/types/ecs-types.d.ts +5 -3
  55. package/dist/lib/types/ecs-types.d.ts.map +1 -1
  56. package/dist/lib/types/ecs-types.js.map +1 -1
  57. package/package.json +4 -5
@@ -1,5 +1,10 @@
1
1
  import { AbstractInputProvider } from './abstract-input-provider.js';
2
2
  export class LocalInputProvider extends AbstractInputProvider {
3
+ get verifiedTick() {
4
+ var _this__simulation;
5
+ var _this__simulation_tick;
6
+ return (_this__simulation_tick = (_this__simulation = this._simulation) == null ? void 0 : _this__simulation.tick) != null ? _this__simulation_tick : -1;
7
+ }
3
8
  getInvalidateRollbackTick() {
4
9
  return undefined;
5
10
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/input/local-input-provider.ts"],"sourcesContent":["import { AbstractInputProvider } from './abstract-input-provider.js';\n\nexport class LocalInputProvider extends AbstractInputProvider {\n public override playerSlot = 0;\n\n public override getInvalidateRollbackTick(): void | number {\n return undefined;\n }\n}\n"],"names":["AbstractInputProvider","LocalInputProvider","getInvalidateRollbackTick","undefined","playerSlot"],"rangeMappings":";;;;;;;;;","mappings":"AAAA,SAASA,qBAAqB,QAAQ,+BAA+B;AAErE,OAAO,MAAMC,2BAA2BD;IAGtBE,4BAA2C;QACzD,OAAOC;IACT;;;aAJgBC,aAAa;;AAK/B"}
1
+ {"version":3,"sources":["../../../src/lib/input/local-input-provider.ts"],"sourcesContent":["import { AbstractInputProvider } from './abstract-input-provider.js';\n\nexport class LocalInputProvider extends AbstractInputProvider {\n public override playerSlot = 0;\n\n public override get verifiedTick(): number {\n return this._simulation?.tick ?? -1;\n }\n\n public override getInvalidateRollbackTick(): void | number {\n return undefined;\n }\n}\n"],"names":["AbstractInputProvider","LocalInputProvider","verifiedTick","_simulation","tick","getInvalidateRollbackTick","undefined","playerSlot"],"rangeMappings":";;;;;;;;;;;;;;","mappings":"AAAA,SAASA,qBAAqB,QAAQ,+BAA+B;AAErE,OAAO,MAAMC,2BAA2BD;IAGtC,IAAoBE,eAAuB;YAClC;YAAA;QAAP,OAAO,CAAA,0BAAA,oBAAA,IAAI,CAACC,WAAW,qBAAhB,kBAAkBC,IAAI,YAAtB,yBAA0B,CAAC;IACpC;IAEgBC,4BAA2C;QACzD,OAAOC;IACT;;;aARgBC,aAAa;;AAS/B"}
@@ -3,6 +3,7 @@ import { ECSConfig } from '../ecs-config.js';
3
3
  import { InputRegistry } from './input-registry.js';
4
4
  export declare class ReplayInputProvider extends AbstractInputProvider {
5
5
  playerSlot: number;
6
+ get verifiedTick(): number;
6
7
  getInvalidateRollbackTick(): undefined;
7
8
  constructor(replayData: ArrayBuffer, ecsConfig: ECSConfig, inputRegistry: InputRegistry);
8
9
  update(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"replay-input-provider.d.ts","sourceRoot":"","sources":["../../../src/lib/input/replay-input-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQpD,qBAAa,mBAAoB,SAAQ,qBAAqB;IAC5C,UAAU,SAAK;IAEf,yBAAyB;gBAKvC,UAAU,EAAE,WAAW,EACvB,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,aAAa;IAMd,MAAM,IAAI,IAAI;WAIhB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,WAAW;WAWrG,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,GAAG,mBAAmB;CAUvG"}
1
+ {"version":3,"file":"replay-input-provider.d.ts","sourceRoot":"","sources":["../../../src/lib/input/replay-input-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQpD,qBAAa,mBAAoB,SAAQ,qBAAqB;IAC5C,UAAU,SAAK;IAE/B,IAAoB,YAAY,IAAI,MAAM,CAEzC;IAEe,yBAAyB;gBAKvC,UAAU,EAAE,WAAW,EACvB,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,aAAa;IAMd,MAAM,IAAI,IAAI;WAIhB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,WAAW;WAWrG,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,GAAG,mBAAmB;CAUvG"}
@@ -6,6 +6,11 @@ const MAX_PLAYERS_OFFSET = SEED_OFFSET + SEED_LENGTH;
6
6
  const FPS_OFFSET = MAX_PLAYERS_OFFSET + 1;
7
7
  const REPLAY_DATA_OFFSET = FPS_OFFSET + 1;
8
8
  export class ReplayInputProvider extends AbstractInputProvider {
9
+ get verifiedTick() {
10
+ var _this__simulation;
11
+ var _this__simulation_tick;
12
+ return (_this__simulation_tick = (_this__simulation = this._simulation) == null ? void 0 : _this__simulation.tick) != null ? _this__simulation_tick : -1;
13
+ }
9
14
  getInvalidateRollbackTick() {
10
15
  return undefined;
11
16
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/input/replay-input-provider.ts"],"sourcesContent":["import { AbstractInputProvider } from './abstract-input-provider.js';\nimport { ECSConfig } from '../ecs-config.js';\nimport { InputRegistry } from './input-registry.js';\n\nconst SEED_OFFSET = 0;\nconst SEED_LENGTH = 16;\nconst MAX_PLAYERS_OFFSET = SEED_OFFSET + SEED_LENGTH;\nconst FPS_OFFSET = MAX_PLAYERS_OFFSET + 1;\nconst REPLAY_DATA_OFFSET = FPS_OFFSET + 1;\n\nexport class ReplayInputProvider extends AbstractInputProvider {\n public override playerSlot = 0;\n\n public override getInvalidateRollbackTick() {\n return undefined;\n }\n\n constructor(\n replayData: ArrayBuffer,\n ecsConfig: ECSConfig,\n inputRegistry: InputRegistry,\n ) {\n super(ecsConfig, inputRegistry);\n this._rpcHistory.import(inputRegistry, replayData);\n }\n\n public override update(): void {\n // do nothing, all inputs are pre-recorded\n }\n\n public static exportReplay(seed: Uint8Array, maxPlayers: number, fps: number, replayData: ArrayBuffer): ArrayBuffer {\n const replay = new ArrayBuffer(REPLAY_DATA_OFFSET + replayData.byteLength);\n const replayUint8 = new Uint8Array(replay);\n replayUint8.set(seed, SEED_OFFSET);\n const replayView = new DataView(replay);\n replayView.setUint8(MAX_PLAYERS_OFFSET, maxPlayers);\n replayView.setUint8(FPS_OFFSET, fps);\n replayUint8.set(new Uint8Array(replayData), REPLAY_DATA_OFFSET);\n return replay;\n }\n\n public static createFromReplay(replay: ArrayBuffer, inputRegistry: InputRegistry): ReplayInputProvider {\n const replayUint8 = new Uint8Array(replay);\n const seed = replayUint8.slice(SEED_OFFSET, SEED_OFFSET + SEED_LENGTH);\n const replayView = new DataView(replay);\n const maxPlayers = replayView.getUint8(MAX_PLAYERS_OFFSET);\n const fps = replayView.getUint8(FPS_OFFSET);\n const rpcData = replay.slice(REPLAY_DATA_OFFSET);\n const ecsConfig = new ECSConfig({ maxPlayers, seed, fps });\n return new ReplayInputProvider(rpcData, ecsConfig, inputRegistry);\n }\n}\n"],"names":["AbstractInputProvider","ECSConfig","SEED_OFFSET","SEED_LENGTH","MAX_PLAYERS_OFFSET","FPS_OFFSET","REPLAY_DATA_OFFSET","ReplayInputProvider","getInvalidateRollbackTick","undefined","update","exportReplay","seed","maxPlayers","fps","replayData","replay","ArrayBuffer","byteLength","replayUint8","Uint8Array","set","replayView","DataView","setUint8","createFromReplay","inputRegistry","slice","getUint8","rpcData","ecsConfig","constructor","playerSlot","_rpcHistory","import"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,qBAAqB,QAAQ,+BAA+B;AACrE,SAASC,SAAS,QAAQ,mBAAmB;AAG7C,MAAMC,cAAc;AACpB,MAAMC,cAAc;AACpB,MAAMC,qBAAqBF,cAAcC;AACzC,MAAME,aAAaD,qBAAqB;AACxC,MAAME,qBAAqBD,aAAa;AAExC,OAAO,MAAME,4BAA4BP;IAGvBQ,4BAA4B;QAC1C,OAAOC;IACT;IAWgBC,SAAe;IAC7B,0CAA0C;IAC5C;IAEA,OAAcC,aAAaC,IAAgB,EAAEC,UAAkB,EAAEC,GAAW,EAAEC,UAAuB,EAAe;QAClH,MAAMC,SAAS,IAAIC,YAAYX,qBAAqBS,WAAWG,UAAU;QACzE,MAAMC,cAAc,IAAIC,WAAWJ;QACnCG,YAAYE,GAAG,CAACT,MAAMV;QACtB,MAAMoB,aAAa,IAAIC,SAASP;QAChCM,WAAWE,QAAQ,CAACpB,oBAAoBS;QACxCS,WAAWE,QAAQ,CAACnB,YAAYS;QAChCK,YAAYE,GAAG,CAAC,IAAID,WAAWL,aAAaT;QAC5C,OAAOU;IACT;IAEA,OAAcS,iBAAiBT,MAAmB,EAAEU,aAA4B,EAAuB;QACrG,MAAMP,cAAc,IAAIC,WAAWJ;QACnC,MAAMJ,OAAOO,YAAYQ,KAAK,CAACzB,aAAaA,cAAcC;QAC1D,MAAMmB,aAAa,IAAIC,SAASP;QAChC,MAAMH,aAAaS,WAAWM,QAAQ,CAACxB;QACvC,MAAMU,MAAMQ,WAAWM,QAAQ,CAACvB;QAChC,MAAMwB,UAAUb,OAAOW,KAAK,CAACrB;QAC7B,MAAMwB,YAAY,IAAI7B,UAAU;YAAEY;YAAYD;YAAME;QAAI;QACxD,OAAO,IAAIP,oBAAoBsB,SAASC,WAAWJ;IACrD;IAjCAK,YACEhB,UAAuB,EACvBe,SAAoB,EACpBJ,aAA4B,CAC5B;QACA,KAAK,CAACI,WAAWJ;aAXHM,aAAa;QAY3B,IAAI,CAACC,WAAW,CAACC,MAAM,CAACR,eAAeX;IACzC;AA2BF"}
1
+ {"version":3,"sources":["../../../src/lib/input/replay-input-provider.ts"],"sourcesContent":["import { AbstractInputProvider } from './abstract-input-provider.js';\nimport { ECSConfig } from '../ecs-config.js';\nimport { InputRegistry } from './input-registry.js';\n\nconst SEED_OFFSET = 0;\nconst SEED_LENGTH = 16;\nconst MAX_PLAYERS_OFFSET = SEED_OFFSET + SEED_LENGTH;\nconst FPS_OFFSET = MAX_PLAYERS_OFFSET + 1;\nconst REPLAY_DATA_OFFSET = FPS_OFFSET + 1;\n\nexport class ReplayInputProvider extends AbstractInputProvider {\n public override playerSlot = 0;\n\n public override get verifiedTick(): number {\n return this._simulation?.tick ?? -1;\n }\n\n public override getInvalidateRollbackTick() {\n return undefined;\n }\n\n constructor(\n replayData: ArrayBuffer,\n ecsConfig: ECSConfig,\n inputRegistry: InputRegistry,\n ) {\n super(ecsConfig, inputRegistry);\n this._rpcHistory.import(inputRegistry, replayData);\n }\n\n public override update(): void {\n // do nothing, all inputs are pre-recorded\n }\n\n public static exportReplay(seed: Uint8Array, maxPlayers: number, fps: number, replayData: ArrayBuffer): ArrayBuffer {\n const replay = new ArrayBuffer(REPLAY_DATA_OFFSET + replayData.byteLength);\n const replayUint8 = new Uint8Array(replay);\n replayUint8.set(seed, SEED_OFFSET);\n const replayView = new DataView(replay);\n replayView.setUint8(MAX_PLAYERS_OFFSET, maxPlayers);\n replayView.setUint8(FPS_OFFSET, fps);\n replayUint8.set(new Uint8Array(replayData), REPLAY_DATA_OFFSET);\n return replay;\n }\n\n public static createFromReplay(replay: ArrayBuffer, inputRegistry: InputRegistry): ReplayInputProvider {\n const replayUint8 = new Uint8Array(replay);\n const seed = replayUint8.slice(SEED_OFFSET, SEED_OFFSET + SEED_LENGTH);\n const replayView = new DataView(replay);\n const maxPlayers = replayView.getUint8(MAX_PLAYERS_OFFSET);\n const fps = replayView.getUint8(FPS_OFFSET);\n const rpcData = replay.slice(REPLAY_DATA_OFFSET);\n const ecsConfig = new ECSConfig({ maxPlayers, seed, fps });\n return new ReplayInputProvider(rpcData, ecsConfig, inputRegistry);\n }\n}\n"],"names":["AbstractInputProvider","ECSConfig","SEED_OFFSET","SEED_LENGTH","MAX_PLAYERS_OFFSET","FPS_OFFSET","REPLAY_DATA_OFFSET","ReplayInputProvider","verifiedTick","_simulation","tick","getInvalidateRollbackTick","undefined","update","exportReplay","seed","maxPlayers","fps","replayData","replay","ArrayBuffer","byteLength","replayUint8","Uint8Array","set","replayView","DataView","setUint8","createFromReplay","inputRegistry","slice","getUint8","rpcData","ecsConfig","constructor","playerSlot","_rpcHistory","import"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,qBAAqB,QAAQ,+BAA+B;AACrE,SAASC,SAAS,QAAQ,mBAAmB;AAG7C,MAAMC,cAAc;AACpB,MAAMC,cAAc;AACpB,MAAMC,qBAAqBF,cAAcC;AACzC,MAAME,aAAaD,qBAAqB;AACxC,MAAME,qBAAqBD,aAAa;AAExC,OAAO,MAAME,4BAA4BP;IAGvC,IAAoBQ,eAAuB;YAClC;YAAA;QAAP,OAAO,CAAA,0BAAA,oBAAA,IAAI,CAACC,WAAW,qBAAhB,kBAAkBC,IAAI,YAAtB,yBAA0B,CAAC;IACpC;IAEgBC,4BAA4B;QAC1C,OAAOC;IACT;IAWgBC,SAAe;IAC7B,0CAA0C;IAC5C;IAEA,OAAcC,aAAaC,IAAgB,EAAEC,UAAkB,EAAEC,GAAW,EAAEC,UAAuB,EAAe;QAClH,MAAMC,SAAS,IAAIC,YAAYd,qBAAqBY,WAAWG,UAAU;QACzE,MAAMC,cAAc,IAAIC,WAAWJ;QACnCG,YAAYE,GAAG,CAACT,MAAMb;QACtB,MAAMuB,aAAa,IAAIC,SAASP;QAChCM,WAAWE,QAAQ,CAACvB,oBAAoBY;QACxCS,WAAWE,QAAQ,CAACtB,YAAYY;QAChCK,YAAYE,GAAG,CAAC,IAAID,WAAWL,aAAaZ;QAC5C,OAAOa;IACT;IAEA,OAAcS,iBAAiBT,MAAmB,EAAEU,aAA4B,EAAuB;QACrG,MAAMP,cAAc,IAAIC,WAAWJ;QACnC,MAAMJ,OAAOO,YAAYQ,KAAK,CAAC5B,aAAaA,cAAcC;QAC1D,MAAMsB,aAAa,IAAIC,SAASP;QAChC,MAAMH,aAAaS,WAAWM,QAAQ,CAAC3B;QACvC,MAAMa,MAAMQ,WAAWM,QAAQ,CAAC1B;QAChC,MAAM2B,UAAUb,OAAOW,KAAK,CAACxB;QAC7B,MAAM2B,YAAY,IAAIhC,UAAU;YAAEe;YAAYD;YAAME;QAAI;QACxD,OAAO,IAAIV,oBAAoByB,SAASC,WAAWJ;IACrD;IAjCAK,YACEhB,UAAuB,EACvBe,SAAoB,EACpBJ,aAA4B,CAC5B;QACA,KAAK,CAACI,WAAWJ;aAfHM,aAAa;QAgB3B,IAAI,CAACC,WAAW,CAACC,MAAM,CAACR,eAAeX;IACzC;AA2BF"}
@@ -5,17 +5,18 @@ import { ECSConfig } from '../../ecs-config.js';
5
5
  import { Prefab } from '../../prefab.js';
6
6
  import { IComponentConstructor } from '../../types/index.js';
7
7
  import { MemoryTracker } from '@lagless/binary';
8
- /** Sentinel value indicating an entity slot is unused / removed. */
8
+ /** Sentinel value indicating an entity slot is unused / removed. All mask words are set to 0xFFFFFFFF. */
9
9
  export declare const ENTITY_REMOVED_MASK = 4294967295;
10
10
  export declare class EntitiesManager implements IAbstractMemory {
11
11
  private readonly _ECSConfig;
12
12
  private readonly _ComponentsMemory;
13
13
  private readonly _FiltersMemory;
14
+ private readonly _maskWords;
14
15
  private _nextEntityId;
15
16
  private _removedEntitiesLength;
16
17
  private _removedEntities;
17
18
  private _entitiesComponentsMasks;
18
- constructor(_ECSConfig: ECSConfig, _ComponentsMemory: ComponentsManager, _FiltersMemory: FiltersManager);
19
+ constructor(_ECSConfig: ECSConfig, _ComponentsMemory: ComponentsManager, _FiltersMemory: FiltersManager, _maskWords?: 1 | 2);
19
20
  createEntity(prefab?: Prefab): number;
20
21
  removeEntity(entity: number): void;
21
22
  isEntityAlive(entity: number): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"entities-manager.d.ts","sourceRoot":"","sources":["../../../../src/lib/mem/managers/entities-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAE9C,qBAAa,eAAgB,YAAW,eAAe;IAOnD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc;IARjC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,sBAAsB,CAAe;IAC7C,OAAO,CAAC,gBAAgB,CAAe;IACvC,OAAO,CAAC,wBAAwB,CAAe;gBAG5B,UAAU,EAAE,SAAS,EACrB,iBAAiB,EAAE,iBAAiB,EACpC,cAAc,EAAE,cAAc;IAG1C,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IA6BrC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAmBlC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAKtC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,GAAG,IAAI;IAK/E,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,GAAG,IAAI;IAKlF,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,GAAG,OAAO;IAOlF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAUzD,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,kBAAkB;IAWnB,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAe5D,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;CAMnD"}
1
+ {"version":3,"file":"entities-manager.d.ts","sourceRoot":"","sources":["../../../../src/lib/mem/managers/entities-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,0GAA0G;AAC1G,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAE9C,qBAAa,eAAgB,YAAW,eAAe;IAOnD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAT7B,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,sBAAsB,CAAe;IAC7C,OAAO,CAAC,gBAAgB,CAAe;IACvC,OAAO,CAAC,wBAAwB,CAAe;gBAG5B,UAAU,EAAE,SAAS,EACrB,iBAAiB,EAAE,iBAAiB,EACpC,cAAc,EAAE,cAAc,EAC9B,UAAU,GAAE,CAAC,GAAG,CAAK;IAGjC,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAoCrC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IA6BlC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAStC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,GAAG,IAAI;IAQ/E,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,GAAG,IAAI;IAQlF,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,GAAG,OAAO;IAUlF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAazD,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,kBAAkB;IAWnB,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAe5D,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;CAMnD"}
@@ -1,4 +1,4 @@
1
- /** Sentinel value indicating an entity slot is unused / removed. */ export const ENTITY_REMOVED_MASK = 0xFFFFFFFF;
1
+ /** Sentinel value indicating an entity slot is unused / removed. All mask words are set to 0xFFFFFFFF. */ export const ENTITY_REMOVED_MASK = 0xFFFFFFFF;
2
2
  export class EntitiesManager {
3
3
  createEntity(prefab) {
4
4
  let entity = this.popRemovedEntities();
@@ -9,66 +9,107 @@ export class EntitiesManager {
9
9
  if (entity >= this._ECSConfig.maxEntities) {
10
10
  throw new Error(`Maximum number of entities (${this._ECSConfig.maxEntities}) exceeded`);
11
11
  }
12
- this._entitiesComponentsMasks[entity] = 0;
12
+ // Clear all mask words for the entity
13
+ const base = entity * this._maskWords;
14
+ for(let w = 0; w < this._maskWords; w++){
15
+ this._entitiesComponentsMasks[base + w] = 0;
16
+ }
13
17
  if (prefab) {
14
18
  for (const [ComponentConstructor, Values] of prefab){
15
- const componentInstance = this._ComponentsMemory.get(ComponentConstructor);
16
- this._entitiesComponentsMasks[entity] |= ComponentConstructor.ID;
19
+ const bitIndex = ComponentConstructor.ID;
20
+ const wordOffset = bitIndex >>> 5;
21
+ const bit = 1 << (bitIndex & 31);
22
+ this._entitiesComponentsMasks[base + wordOffset] |= bit;
17
23
  if (!Values) continue;
24
+ const componentInstance = this._ComponentsMemory.get(ComponentConstructor);
18
25
  for (const [fieldName, value] of Object.entries(Values)){
19
26
  if (value === undefined) continue;
20
27
  componentInstance.unsafe[fieldName][entity] = value;
21
28
  }
22
29
  }
23
30
  }
24
- this.updateFilters(entity, this._entitiesComponentsMasks[entity]);
31
+ this.updateFilters(entity);
25
32
  return entity;
26
33
  }
27
34
  removeEntity(entity) {
28
35
  if (entity < 0 || entity >= this._ECSConfig.maxEntities) {
29
36
  throw new Error(`Entity ID ${entity} is out of bounds`);
30
37
  }
31
- // Guard against double removal
32
- if (this._entitiesComponentsMasks[entity] === ENTITY_REMOVED_MASK) {
33
- return;
38
+ const base = entity * this._maskWords;
39
+ // Guard against double removal (all mask words must be sentinel)
40
+ let isRemoved = true;
41
+ for(let w = 0; w < this._maskWords; w++){
42
+ if (this._entitiesComponentsMasks[base + w] !== ENTITY_REMOVED_MASK) {
43
+ isRemoved = false;
44
+ break;
45
+ }
46
+ }
47
+ if (isRemoved) return;
48
+ // Set all mask words to sentinel
49
+ for(let w = 0; w < this._maskWords; w++){
50
+ this._entitiesComponentsMasks[base + w] = ENTITY_REMOVED_MASK;
34
51
  }
35
- this._entitiesComponentsMasks[entity] = ENTITY_REMOVED_MASK;
36
52
  // Add the entity to the removed entities stack
37
53
  this._removedEntities[this._removedEntitiesLength[0]] = entity;
38
54
  this._removedEntitiesLength[0]++;
39
- this.updateFilters(entity, ENTITY_REMOVED_MASK);
55
+ this._FiltersMemory.removeEntityFromAllFilters(entity);
40
56
  }
41
57
  isEntityAlive(entity) {
42
58
  if (entity < 0 || entity >= this._ECSConfig.maxEntities) return false;
43
- return this._entitiesComponentsMasks[entity] !== ENTITY_REMOVED_MASK;
59
+ const base = entity * this._maskWords;
60
+ for(let w = 0; w < this._maskWords; w++){
61
+ if (this._entitiesComponentsMasks[base + w] !== ENTITY_REMOVED_MASK) return true;
62
+ }
63
+ return false;
44
64
  }
45
65
  addComponent(entity, ComponentConstructor) {
46
- this._entitiesComponentsMasks[entity] |= ComponentConstructor.ID;
47
- this.updateFilters(entity, this._entitiesComponentsMasks[entity]);
66
+ const bitIndex = ComponentConstructor.ID;
67
+ const base = entity * this._maskWords;
68
+ const wordOffset = bitIndex >>> 5;
69
+ this._entitiesComponentsMasks[base + wordOffset] |= 1 << (bitIndex & 31);
70
+ this.updateFilters(entity);
48
71
  }
49
72
  removeComponent(entity, ComponentConstructor) {
50
- this._entitiesComponentsMasks[entity] &= ~ComponentConstructor.ID;
51
- this.updateFilters(entity, this._entitiesComponentsMasks[entity]);
73
+ const bitIndex = ComponentConstructor.ID;
74
+ const base = entity * this._maskWords;
75
+ const wordOffset = bitIndex >>> 5;
76
+ this._entitiesComponentsMasks[base + wordOffset] &= ~(1 << (bitIndex & 31));
77
+ this.updateFilters(entity);
52
78
  }
53
79
  hasComponent(entity, ComponentConstructor) {
54
80
  if (entity < 0 || entity >= this._ECSConfig.maxEntities) {
55
81
  throw new Error(`Entity ID ${entity} is out of bounds`);
56
82
  }
57
- return (this._entitiesComponentsMasks[entity] & ComponentConstructor.ID) !== 0;
83
+ const bitIndex = ComponentConstructor.ID;
84
+ const base = entity * this._maskWords;
85
+ const wordOffset = bitIndex >>> 5;
86
+ return (this._entitiesComponentsMasks[base + wordOffset] & 1 << (bitIndex & 31)) !== 0;
58
87
  }
59
88
  hasPrefab(entity, prefab) {
89
+ const base = entity * this._maskWords;
60
90
  for (const [ComponentConstructor] of prefab){
61
- if ((this._entitiesComponentsMasks[entity] & ComponentConstructor.ID) === 0) {
91
+ const bitIndex = ComponentConstructor.ID;
92
+ const wordOffset = bitIndex >>> 5;
93
+ if ((this._entitiesComponentsMasks[base + wordOffset] & 1 << (bitIndex & 31)) === 0) {
62
94
  return false;
63
95
  }
64
96
  }
65
97
  return true;
66
98
  }
67
- updateFilters(entity, componentMask) {
68
- if (componentMask === ENTITY_REMOVED_MASK || componentMask === 0) {
99
+ updateFilters(entity) {
100
+ const base = entity * this._maskWords;
101
+ // Check if entity has any components set (all words zero means empty)
102
+ let isEmpty = true;
103
+ for(let w = 0; w < this._maskWords; w++){
104
+ if (this._entitiesComponentsMasks[base + w] !== 0) {
105
+ isEmpty = false;
106
+ break;
107
+ }
108
+ }
109
+ if (isEmpty) {
69
110
  this._FiltersMemory.removeEntityFromAllFilters(entity);
70
111
  } else {
71
- this._FiltersMemory.updateEntityInAllFilters(entity, componentMask);
112
+ this._FiltersMemory.updateEntityInAllFilters(entity, this._entitiesComponentsMasks, base, this._maskWords);
72
113
  }
73
114
  }
74
115
  popRemovedEntities() {
@@ -86,7 +127,7 @@ export class EntitiesManager {
86
127
  tracker.add(this._removedEntitiesLength.byteLength);
87
128
  this._removedEntities = new Uint32Array(arrayBuffer, tracker.ptr, this._ECSConfig.maxEntities);
88
129
  tracker.add(this._removedEntities.byteLength);
89
- this._entitiesComponentsMasks = new Uint32Array(arrayBuffer, tracker.ptr, this._ECSConfig.maxEntities);
130
+ this._entitiesComponentsMasks = new Uint32Array(arrayBuffer, tracker.ptr, this._ECSConfig.maxEntities * this._maskWords);
90
131
  this._entitiesComponentsMasks.fill(ENTITY_REMOVED_MASK);
91
132
  tracker.add(this._entitiesComponentsMasks.byteLength);
92
133
  }
@@ -94,12 +135,13 @@ export class EntitiesManager {
94
135
  tracker.add(Uint32Array.BYTES_PER_ELEMENT); // nextEntityId
95
136
  tracker.add(Uint32Array.BYTES_PER_ELEMENT); // removedEntitiesLength
96
137
  tracker.add(this._ECSConfig.maxEntities * Uint32Array.BYTES_PER_ELEMENT); // removedEntities
97
- tracker.add(this._ECSConfig.maxEntities * Uint32Array.BYTES_PER_ELEMENT); // entitiesComponentsMasks
138
+ tracker.add(this._ECSConfig.maxEntities * this._maskWords * Uint32Array.BYTES_PER_ELEMENT); // entitiesComponentsMasks
98
139
  }
99
- constructor(_ECSConfig, _ComponentsMemory, _FiltersMemory){
140
+ constructor(_ECSConfig, _ComponentsMemory, _FiltersMemory, _maskWords = 1){
100
141
  this._ECSConfig = _ECSConfig;
101
142
  this._ComponentsMemory = _ComponentsMemory;
102
143
  this._FiltersMemory = _FiltersMemory;
144
+ this._maskWords = _maskWords;
103
145
  }
104
146
  }
105
147
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/mem/managers/entities-manager.ts"],"sourcesContent":["import { FiltersManager } from './filters-manager.js';\nimport { ComponentsManager } from './components-manager.js';\nimport { IAbstractMemory } from '../abstract-memory.interface.js';\nimport { ECSConfig } from '../../ecs-config.js';\nimport { Prefab } from '../../prefab.js';\nimport { IComponentConstructor } from '../../types/index.js';\nimport { MemoryTracker } from '@lagless/binary';\n\n/** Sentinel value indicating an entity slot is unused / removed. */\nexport const ENTITY_REMOVED_MASK = 0xFFFFFFFF;\n\nexport class EntitiesManager implements IAbstractMemory {\n private _nextEntityId!: Uint32Array;\n private _removedEntitiesLength!: Uint32Array;\n private _removedEntities!: Uint32Array;\n private _entitiesComponentsMasks!: Uint32Array;\n\n constructor(\n private readonly _ECSConfig: ECSConfig,\n private readonly _ComponentsMemory: ComponentsManager,\n private readonly _FiltersMemory: FiltersManager,\n ) {}\n\n public createEntity(prefab?: Prefab): number {\n let entity = this.popRemovedEntities();\n if (entity === undefined) {\n entity = this._nextEntityId[0];\n this._nextEntityId[0]++;\n }\n if (entity >= this._ECSConfig.maxEntities) {\n throw new Error(`Maximum number of entities (${this._ECSConfig.maxEntities}) exceeded`);\n }\n\n this._entitiesComponentsMasks[entity] = 0;\n\n if (prefab) {\n for (const [ ComponentConstructor, Values ] of prefab) {\n const componentInstance = this._ComponentsMemory.get(ComponentConstructor);\n this._entitiesComponentsMasks[entity] |= ComponentConstructor.ID;\n if (!Values) continue;\n for (const [ fieldName, value ] of Object.entries(Values)) {\n if (value === undefined) continue;\n componentInstance.unsafe[fieldName as keyof typeof componentInstance.unsafe][entity] = value;\n }\n }\n }\n\n this.updateFilters(entity, this._entitiesComponentsMasks[entity]);\n\n return entity;\n }\n\n public removeEntity(entity: number): void {\n if (entity < 0 || entity >= this._ECSConfig.maxEntities) {\n throw new Error(`Entity ID ${entity} is out of bounds`);\n }\n\n // Guard against double removal\n if (this._entitiesComponentsMasks[entity] === ENTITY_REMOVED_MASK) {\n return;\n }\n\n this._entitiesComponentsMasks[entity] = ENTITY_REMOVED_MASK;\n\n // Add the entity to the removed entities stack\n this._removedEntities[this._removedEntitiesLength[0]] = entity;\n this._removedEntitiesLength[0]++;\n\n this.updateFilters(entity, ENTITY_REMOVED_MASK);\n }\n\n public isEntityAlive(entity: number): boolean {\n if (entity < 0 || entity >= this._ECSConfig.maxEntities) return false;\n return this._entitiesComponentsMasks[entity] !== ENTITY_REMOVED_MASK;\n }\n\n public addComponent(entity: number, ComponentConstructor: IComponentConstructor): void {\n this._entitiesComponentsMasks[entity] |= ComponentConstructor.ID;\n this.updateFilters(entity, this._entitiesComponentsMasks[entity]);\n }\n\n public removeComponent(entity: number, ComponentConstructor: IComponentConstructor): void {\n this._entitiesComponentsMasks[entity] &= ~ComponentConstructor.ID;\n this.updateFilters(entity, this._entitiesComponentsMasks[entity]);\n }\n\n public hasComponent(entity: number, ComponentConstructor: IComponentConstructor): boolean {\n if (entity < 0 || entity >= this._ECSConfig.maxEntities) {\n throw new Error(`Entity ID ${entity} is out of bounds`);\n }\n return (this._entitiesComponentsMasks[entity] & ComponentConstructor.ID) !== 0;\n }\n\n public hasPrefab(entity: number, prefab: Prefab): boolean {\n for (const [ ComponentConstructor ] of prefab) {\n if ((this._entitiesComponentsMasks[entity] & ComponentConstructor.ID) === 0) {\n return false;\n }\n }\n\n return true;\n }\n\n private updateFilters(entity: number, componentMask: number): void {\n if (componentMask === ENTITY_REMOVED_MASK || componentMask === 0) {\n this._FiltersMemory.removeEntityFromAllFilters(entity);\n } else {\n this._FiltersMemory.updateEntityInAllFilters(entity, componentMask);\n }\n }\n\n private popRemovedEntities(): number | undefined {\n if (this._removedEntitiesLength[0] === 0) {\n return undefined;\n }\n\n const entity = this._removedEntities[this._removedEntitiesLength[0] - 1];\n this._removedEntitiesLength[0]--;\n\n return entity;\n }\n\n public init(arrayBuffer: ArrayBuffer, tracker: MemoryTracker): void {\n this._nextEntityId = new Uint32Array(arrayBuffer, tracker.ptr, 1);\n tracker.add(this._nextEntityId.byteLength);\n\n this._removedEntitiesLength = new Uint32Array(arrayBuffer, tracker.ptr, 1);\n tracker.add(this._removedEntitiesLength.byteLength);\n\n this._removedEntities = new Uint32Array(arrayBuffer, tracker.ptr, this._ECSConfig.maxEntities);\n tracker.add(this._removedEntities.byteLength);\n\n this._entitiesComponentsMasks = new Uint32Array(arrayBuffer, tracker.ptr, this._ECSConfig.maxEntities);\n this._entitiesComponentsMasks.fill(ENTITY_REMOVED_MASK);\n tracker.add(this._entitiesComponentsMasks.byteLength);\n }\n\n public calculateSize(tracker: MemoryTracker): void {\n tracker.add(Uint32Array.BYTES_PER_ELEMENT); // nextEntityId\n tracker.add(Uint32Array.BYTES_PER_ELEMENT); // removedEntitiesLength\n tracker.add(this._ECSConfig.maxEntities * Uint32Array.BYTES_PER_ELEMENT); // removedEntities\n tracker.add(this._ECSConfig.maxEntities * Uint32Array.BYTES_PER_ELEMENT); // entitiesComponentsMasks\n }\n}\n"],"names":["ENTITY_REMOVED_MASK","EntitiesManager","createEntity","prefab","entity","popRemovedEntities","undefined","_nextEntityId","_ECSConfig","maxEntities","Error","_entitiesComponentsMasks","ComponentConstructor","Values","componentInstance","_ComponentsMemory","get","ID","fieldName","value","Object","entries","unsafe","updateFilters","removeEntity","_removedEntities","_removedEntitiesLength","isEntityAlive","addComponent","removeComponent","hasComponent","hasPrefab","componentMask","_FiltersMemory","removeEntityFromAllFilters","updateEntityInAllFilters","init","arrayBuffer","tracker","Uint32Array","ptr","add","byteLength","fill","calculateSize","BYTES_PER_ELEMENT","constructor"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/lib/mem/managers/entities-manager.ts"],"sourcesContent":["import { FiltersManager } from './filters-manager.js';\nimport { ComponentsManager } from './components-manager.js';\nimport { IAbstractMemory } from '../abstract-memory.interface.js';\nimport { ECSConfig } from '../../ecs-config.js';\nimport { Prefab } from '../../prefab.js';\nimport { IComponentConstructor } from '../../types/index.js';\nimport { MemoryTracker } from '@lagless/binary';\n\n/** Sentinel value indicating an entity slot is unused / removed. All mask words are set to 0xFFFFFFFF. */\nexport const ENTITY_REMOVED_MASK = 0xFFFFFFFF;\n\nexport class EntitiesManager implements IAbstractMemory {\n private _nextEntityId!: Uint32Array;\n private _removedEntitiesLength!: Uint32Array;\n private _removedEntities!: Uint32Array;\n private _entitiesComponentsMasks!: Uint32Array;\n\n constructor(\n private readonly _ECSConfig: ECSConfig,\n private readonly _ComponentsMemory: ComponentsManager,\n private readonly _FiltersMemory: FiltersManager,\n private readonly _maskWords: 1 | 2 = 1,\n ) {}\n\n public createEntity(prefab?: Prefab): number {\n let entity = this.popRemovedEntities();\n if (entity === undefined) {\n entity = this._nextEntityId[0];\n this._nextEntityId[0]++;\n }\n if (entity >= this._ECSConfig.maxEntities) {\n throw new Error(`Maximum number of entities (${this._ECSConfig.maxEntities}) exceeded`);\n }\n\n // Clear all mask words for the entity\n const base = entity * this._maskWords;\n for (let w = 0; w < this._maskWords; w++) {\n this._entitiesComponentsMasks[base + w] = 0;\n }\n\n if (prefab) {\n for (const [ ComponentConstructor, Values ] of prefab) {\n const bitIndex = ComponentConstructor.ID;\n const wordOffset = bitIndex >>> 5;\n const bit = 1 << (bitIndex & 31);\n this._entitiesComponentsMasks[base + wordOffset] |= bit;\n if (!Values) continue;\n const componentInstance = this._ComponentsMemory.get(ComponentConstructor);\n for (const [ fieldName, value ] of Object.entries(Values)) {\n if (value === undefined) continue;\n componentInstance.unsafe[fieldName as keyof typeof componentInstance.unsafe][entity] = value;\n }\n }\n }\n\n this.updateFilters(entity);\n\n return entity;\n }\n\n public removeEntity(entity: number): void {\n if (entity < 0 || entity >= this._ECSConfig.maxEntities) {\n throw new Error(`Entity ID ${entity} is out of bounds`);\n }\n\n const base = entity * this._maskWords;\n\n // Guard against double removal (all mask words must be sentinel)\n let isRemoved = true;\n for (let w = 0; w < this._maskWords; w++) {\n if (this._entitiesComponentsMasks[base + w] !== ENTITY_REMOVED_MASK) {\n isRemoved = false;\n break;\n }\n }\n if (isRemoved) return;\n\n // Set all mask words to sentinel\n for (let w = 0; w < this._maskWords; w++) {\n this._entitiesComponentsMasks[base + w] = ENTITY_REMOVED_MASK;\n }\n\n // Add the entity to the removed entities stack\n this._removedEntities[this._removedEntitiesLength[0]] = entity;\n this._removedEntitiesLength[0]++;\n\n this._FiltersMemory.removeEntityFromAllFilters(entity);\n }\n\n public isEntityAlive(entity: number): boolean {\n if (entity < 0 || entity >= this._ECSConfig.maxEntities) return false;\n const base = entity * this._maskWords;\n for (let w = 0; w < this._maskWords; w++) {\n if (this._entitiesComponentsMasks[base + w] !== ENTITY_REMOVED_MASK) return true;\n }\n return false;\n }\n\n public addComponent(entity: number, ComponentConstructor: IComponentConstructor): void {\n const bitIndex = ComponentConstructor.ID;\n const base = entity * this._maskWords;\n const wordOffset = bitIndex >>> 5;\n this._entitiesComponentsMasks[base + wordOffset] |= 1 << (bitIndex & 31);\n this.updateFilters(entity);\n }\n\n public removeComponent(entity: number, ComponentConstructor: IComponentConstructor): void {\n const bitIndex = ComponentConstructor.ID;\n const base = entity * this._maskWords;\n const wordOffset = bitIndex >>> 5;\n this._entitiesComponentsMasks[base + wordOffset] &= ~(1 << (bitIndex & 31));\n this.updateFilters(entity);\n }\n\n public hasComponent(entity: number, ComponentConstructor: IComponentConstructor): boolean {\n if (entity < 0 || entity >= this._ECSConfig.maxEntities) {\n throw new Error(`Entity ID ${entity} is out of bounds`);\n }\n const bitIndex = ComponentConstructor.ID;\n const base = entity * this._maskWords;\n const wordOffset = bitIndex >>> 5;\n return (this._entitiesComponentsMasks[base + wordOffset] & (1 << (bitIndex & 31))) !== 0;\n }\n\n public hasPrefab(entity: number, prefab: Prefab): boolean {\n const base = entity * this._maskWords;\n for (const [ ComponentConstructor ] of prefab) {\n const bitIndex = ComponentConstructor.ID;\n const wordOffset = bitIndex >>> 5;\n if ((this._entitiesComponentsMasks[base + wordOffset] & (1 << (bitIndex & 31))) === 0) {\n return false;\n }\n }\n\n return true;\n }\n\n private updateFilters(entity: number): void {\n const base = entity * this._maskWords;\n\n // Check if entity has any components set (all words zero means empty)\n let isEmpty = true;\n for (let w = 0; w < this._maskWords; w++) {\n if (this._entitiesComponentsMasks[base + w] !== 0) {\n isEmpty = false;\n break;\n }\n }\n\n if (isEmpty) {\n this._FiltersMemory.removeEntityFromAllFilters(entity);\n } else {\n this._FiltersMemory.updateEntityInAllFilters(entity, this._entitiesComponentsMasks, base, this._maskWords);\n }\n }\n\n private popRemovedEntities(): number | undefined {\n if (this._removedEntitiesLength[0] === 0) {\n return undefined;\n }\n\n const entity = this._removedEntities[this._removedEntitiesLength[0] - 1];\n this._removedEntitiesLength[0]--;\n\n return entity;\n }\n\n public init(arrayBuffer: ArrayBuffer, tracker: MemoryTracker): void {\n this._nextEntityId = new Uint32Array(arrayBuffer, tracker.ptr, 1);\n tracker.add(this._nextEntityId.byteLength);\n\n this._removedEntitiesLength = new Uint32Array(arrayBuffer, tracker.ptr, 1);\n tracker.add(this._removedEntitiesLength.byteLength);\n\n this._removedEntities = new Uint32Array(arrayBuffer, tracker.ptr, this._ECSConfig.maxEntities);\n tracker.add(this._removedEntities.byteLength);\n\n this._entitiesComponentsMasks = new Uint32Array(arrayBuffer, tracker.ptr, this._ECSConfig.maxEntities * this._maskWords);\n this._entitiesComponentsMasks.fill(ENTITY_REMOVED_MASK);\n tracker.add(this._entitiesComponentsMasks.byteLength);\n }\n\n public calculateSize(tracker: MemoryTracker): void {\n tracker.add(Uint32Array.BYTES_PER_ELEMENT); // nextEntityId\n tracker.add(Uint32Array.BYTES_PER_ELEMENT); // removedEntitiesLength\n tracker.add(this._ECSConfig.maxEntities * Uint32Array.BYTES_PER_ELEMENT); // removedEntities\n tracker.add(this._ECSConfig.maxEntities * this._maskWords * Uint32Array.BYTES_PER_ELEMENT); // entitiesComponentsMasks\n }\n}\n"],"names":["ENTITY_REMOVED_MASK","EntitiesManager","createEntity","prefab","entity","popRemovedEntities","undefined","_nextEntityId","_ECSConfig","maxEntities","Error","base","_maskWords","w","_entitiesComponentsMasks","ComponentConstructor","Values","bitIndex","ID","wordOffset","bit","componentInstance","_ComponentsMemory","get","fieldName","value","Object","entries","unsafe","updateFilters","removeEntity","isRemoved","_removedEntities","_removedEntitiesLength","_FiltersMemory","removeEntityFromAllFilters","isEntityAlive","addComponent","removeComponent","hasComponent","hasPrefab","isEmpty","updateEntityInAllFilters","init","arrayBuffer","tracker","Uint32Array","ptr","add","byteLength","fill","calculateSize","BYTES_PER_ELEMENT","constructor"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -6,12 +6,12 @@ export declare class FiltersManager implements IAbstractMemory {
6
6
  private readonly _ECSConfig;
7
7
  private readonly _ECSDeps;
8
8
  private readonly _filtersInstances;
9
- constructor(_ECSConfig: ECSConfig, _ECSDeps: ECSDeps);
9
+ constructor(_ECSConfig: ECSConfig, _ECSDeps: ECSDeps, _maskWords?: 1 | 2);
10
10
  init(arrayBuffer: ArrayBuffer, tracker: MemoryTracker): void;
11
11
  calculateSize(tracker: MemoryTracker): void;
12
12
  get<FilterCtor extends IFilterConstructor>(FilterConstructor: FilterCtor): InstanceType<FilterCtor>;
13
13
  [Symbol.iterator](): MapIterator<[IFilterConstructor, IFilterInstance]>;
14
14
  removeEntityFromAllFilters(entity: number): void;
15
- updateEntityInAllFilters(entity: number, componentsMask: number): void;
15
+ updateEntityInAllFilters(entity: number, masks: Uint32Array, maskBase: number, maskWords: number): void;
16
16
  }
17
17
  //# sourceMappingURL=filters-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filters-manager.d.ts","sourceRoot":"","sources":["../../../../src/lib/mem/managers/filters-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qBAAa,cAAe,YAAW,eAAe;IAGxC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAa,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAF7E,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkD;gBAEvD,UAAU,EAAE,SAAS,EAAmB,QAAQ,EAAE,OAAO;IAE/E,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAO5D,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAM3C,GAAG,CAAC,UAAU,SAAS,kBAAkB,EAAE,iBAAiB,EAAE,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;IAQnG,CAAC,MAAM,CAAC,QAAQ,CAAC;IAIjB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMhD,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI;CAc9E"}
1
+ {"version":3,"file":"filters-manager.d.ts","sourceRoot":"","sources":["../../../../src/lib/mem/managers/filters-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qBAAa,cAAe,YAAW,eAAe;IAIlD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJ3B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkD;gBAGjE,UAAU,EAAE,SAAS,EACrB,QAAQ,EAAE,OAAO,EAClC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC;IAGb,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAO5D,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAM3C,GAAG,CAAC,UAAU,SAAS,kBAAkB,EAAE,iBAAiB,EAAE,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;IAQnG,CAAC,MAAM,CAAC,QAAQ,CAAC;IAIjB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMhD,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CA2B/G"}
@@ -25,10 +25,25 @@ export class FiltersManager {
25
25
  filterInstance.removeEntityFromFilter(entity);
26
26
  }
27
27
  }
28
- updateEntityInAllFilters(entity, componentsMask) {
28
+ updateEntityInAllFilters(entity, masks, maskBase, maskWords) {
29
29
  for (const filterInstance of this._filtersInstances.values()){
30
- const includeOk = !filterInstance.includeMask || (componentsMask & filterInstance.includeMask) === filterInstance.includeMask;
31
- const excludeOk = !filterInstance.excludeMask || (componentsMask & filterInstance.excludeMask) === 0;
30
+ let includeOk = true;
31
+ let excludeOk = true;
32
+ for(let w = 0; w < maskWords; w++){
33
+ const entityMaskWord = masks[maskBase + w];
34
+ var _filterInstance_includeMask_w;
35
+ const incWord = (_filterInstance_includeMask_w = filterInstance.includeMask[w]) != null ? _filterInstance_includeMask_w : 0;
36
+ var _filterInstance_excludeMask_w;
37
+ const excWord = (_filterInstance_excludeMask_w = filterInstance.excludeMask[w]) != null ? _filterInstance_excludeMask_w : 0;
38
+ if (incWord && (entityMaskWord & incWord) >>> 0 !== incWord >>> 0) {
39
+ includeOk = false;
40
+ break;
41
+ }
42
+ if (excWord && (entityMaskWord & excWord) !== 0) {
43
+ excludeOk = false;
44
+ break;
45
+ }
46
+ }
32
47
  if (includeOk && excludeOk) {
33
48
  filterInstance.addEntityToFilter(entity);
34
49
  } else {
@@ -36,7 +51,7 @@ export class FiltersManager {
36
51
  }
37
52
  }
38
53
  }
39
- constructor(_ECSConfig, _ECSDeps){
54
+ constructor(_ECSConfig, _ECSDeps, _maskWords){
40
55
  this._ECSConfig = _ECSConfig;
41
56
  this._ECSDeps = _ECSDeps;
42
57
  this._filtersInstances = new Map();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/mem/managers/filters-manager.ts"],"sourcesContent":["import { ECSConfig } from '../../ecs-config.js';\nimport { IAbstractMemory } from '../abstract-memory.interface.js';\nimport { ECSDeps, IFilterConstructor, IFilterInstance } from '../../types/index.js';\nimport { MemoryTracker } from '@lagless/binary';\n\nexport class FiltersManager implements IAbstractMemory {\n private readonly _filtersInstances = new Map<IFilterConstructor, IFilterInstance>();\n\n constructor(private readonly _ECSConfig: ECSConfig, private readonly _ECSDeps: ECSDeps) {}\n\n public init(arrayBuffer: ArrayBuffer, tracker: MemoryTracker): void {\n for (const FilterConstructor of this._ECSDeps.filters) {\n const filterInstance = new FilterConstructor(this._ECSConfig.maxEntities, arrayBuffer, tracker);\n this._filtersInstances.set(FilterConstructor, filterInstance);\n }\n }\n\n public calculateSize(tracker: MemoryTracker): void {\n for (const FilterDefinition of this._ECSDeps.filters) {\n FilterDefinition.calculateSize(this._ECSConfig.maxEntities, tracker);\n }\n }\n\n public get<FilterCtor extends IFilterConstructor>(FilterConstructor: FilterCtor): InstanceType<FilterCtor> {\n const filterInstance = this._filtersInstances.get(FilterConstructor);\n if (!filterInstance) {\n throw new Error(`Filter ${FilterConstructor.name} not found`);\n }\n return filterInstance as InstanceType<FilterCtor>;\n }\n\n public [Symbol.iterator]() {\n return this._filtersInstances.entries();\n }\n\n public removeEntityFromAllFilters(entity: number): void {\n for (const filterInstance of this._filtersInstances.values()) {\n filterInstance.removeEntityFromFilter(entity);\n }\n }\n\n public updateEntityInAllFilters(entity: number, componentsMask: number): void {\n for (const filterInstance of this._filtersInstances.values()) {\n const includeOk = !filterInstance.includeMask\n || (componentsMask & filterInstance.includeMask) === filterInstance.includeMask;\n const excludeOk = !filterInstance.excludeMask\n || (componentsMask & filterInstance.excludeMask) === 0;\n\n if (includeOk && excludeOk) {\n filterInstance.addEntityToFilter(entity);\n } else {\n filterInstance.removeEntityFromFilter(entity);\n }\n }\n }\n}\n"],"names":["FiltersManager","init","arrayBuffer","tracker","FilterConstructor","_ECSDeps","filters","filterInstance","_ECSConfig","maxEntities","_filtersInstances","set","calculateSize","FilterDefinition","get","Error","name","Symbol","iterator","entries","removeEntityFromAllFilters","entity","values","removeEntityFromFilter","updateEntityInAllFilters","componentsMask","includeOk","includeMask","excludeOk","excludeMask","addEntityToFilter","constructor","Map"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAKA,OAAO,MAAMA;IAKJC,KAAKC,WAAwB,EAAEC,OAAsB,EAAQ;QAClE,KAAK,MAAMC,qBAAqB,IAAI,CAACC,QAAQ,CAACC,OAAO,CAAE;YACrD,MAAMC,iBAAiB,IAAIH,kBAAkB,IAAI,CAACI,UAAU,CAACC,WAAW,EAAEP,aAAaC;YACvF,IAAI,CAACO,iBAAiB,CAACC,GAAG,CAACP,mBAAmBG;QAChD;IACF;IAEOK,cAAcT,OAAsB,EAAQ;QACjD,KAAK,MAAMU,oBAAoB,IAAI,CAACR,QAAQ,CAACC,OAAO,CAAE;YACpDO,iBAAiBD,aAAa,CAAC,IAAI,CAACJ,UAAU,CAACC,WAAW,EAAEN;QAC9D;IACF;IAEOW,IAA2CV,iBAA6B,EAA4B;QACzG,MAAMG,iBAAiB,IAAI,CAACG,iBAAiB,CAACI,GAAG,CAACV;QAClD,IAAI,CAACG,gBAAgB;YACnB,MAAM,IAAIQ,MAAM,CAAC,OAAO,EAAEX,kBAAkBY,IAAI,CAAC,UAAU,CAAC;QAC9D;QACA,OAAOT;IACT;IAEO,CAACU,OAAOC,QAAQ,CAAC,GAAG;QACzB,OAAO,IAAI,CAACR,iBAAiB,CAACS,OAAO;IACvC;IAEOC,2BAA2BC,MAAc,EAAQ;QACtD,KAAK,MAAMd,kBAAkB,IAAI,CAACG,iBAAiB,CAACY,MAAM,GAAI;YAC5Df,eAAegB,sBAAsB,CAACF;QACxC;IACF;IAEOG,yBAAyBH,MAAc,EAAEI,cAAsB,EAAQ;QAC5E,KAAK,MAAMlB,kBAAkB,IAAI,CAACG,iBAAiB,CAACY,MAAM,GAAI;YAC5D,MAAMI,YAAY,CAACnB,eAAeoB,WAAW,IACxC,AAACF,CAAAA,iBAAiBlB,eAAeoB,WAAW,AAAD,MAAOpB,eAAeoB,WAAW;YACjF,MAAMC,YAAY,CAACrB,eAAesB,WAAW,IACxC,AAACJ,CAAAA,iBAAiBlB,eAAesB,WAAW,AAAD,MAAO;YAEvD,IAAIH,aAAaE,WAAW;gBAC1BrB,eAAeuB,iBAAiB,CAACT;YACnC,OAAO;gBACLd,eAAegB,sBAAsB,CAACF;YACxC;QACF;IACF;IA9CAU,YAAY,AAAiBvB,UAAqB,EAAE,AAAiBH,QAAiB,CAAE;aAA3DG,aAAAA;aAAwCH,WAAAA;aAFpDK,oBAAoB,IAAIsB;IAEgD;AA+C3F"}
1
+ {"version":3,"sources":["../../../../src/lib/mem/managers/filters-manager.ts"],"sourcesContent":["import { ECSConfig } from '../../ecs-config.js';\nimport { IAbstractMemory } from '../abstract-memory.interface.js';\nimport { ECSDeps, IFilterConstructor, IFilterInstance } from '../../types/index.js';\nimport { MemoryTracker } from '@lagless/binary';\n\nexport class FiltersManager implements IAbstractMemory {\n private readonly _filtersInstances = new Map<IFilterConstructor, IFilterInstance>();\n\n constructor(\n private readonly _ECSConfig: ECSConfig,\n private readonly _ECSDeps: ECSDeps,\n _maskWords?: 1 | 2,\n ) {}\n\n public init(arrayBuffer: ArrayBuffer, tracker: MemoryTracker): void {\n for (const FilterConstructor of this._ECSDeps.filters) {\n const filterInstance = new FilterConstructor(this._ECSConfig.maxEntities, arrayBuffer, tracker);\n this._filtersInstances.set(FilterConstructor, filterInstance);\n }\n }\n\n public calculateSize(tracker: MemoryTracker): void {\n for (const FilterDefinition of this._ECSDeps.filters) {\n FilterDefinition.calculateSize(this._ECSConfig.maxEntities, tracker);\n }\n }\n\n public get<FilterCtor extends IFilterConstructor>(FilterConstructor: FilterCtor): InstanceType<FilterCtor> {\n const filterInstance = this._filtersInstances.get(FilterConstructor);\n if (!filterInstance) {\n throw new Error(`Filter ${FilterConstructor.name} not found`);\n }\n return filterInstance as InstanceType<FilterCtor>;\n }\n\n public [Symbol.iterator]() {\n return this._filtersInstances.entries();\n }\n\n public removeEntityFromAllFilters(entity: number): void {\n for (const filterInstance of this._filtersInstances.values()) {\n filterInstance.removeEntityFromFilter(entity);\n }\n }\n\n public updateEntityInAllFilters(entity: number, masks: Uint32Array, maskBase: number, maskWords: number): void {\n for (const filterInstance of this._filtersInstances.values()) {\n let includeOk = true;\n let excludeOk = true;\n\n for (let w = 0; w < maskWords; w++) {\n const entityMaskWord = masks[maskBase + w];\n const incWord = filterInstance.includeMask[w] ?? 0;\n const excWord = filterInstance.excludeMask[w] ?? 0;\n\n if (incWord && ((entityMaskWord & incWord) >>> 0) !== (incWord >>> 0)) {\n includeOk = false;\n break;\n }\n if (excWord && (entityMaskWord & excWord) !== 0) {\n excludeOk = false;\n break;\n }\n }\n\n if (includeOk && excludeOk) {\n filterInstance.addEntityToFilter(entity);\n } else {\n filterInstance.removeEntityFromFilter(entity);\n }\n }\n }\n}\n"],"names":["FiltersManager","init","arrayBuffer","tracker","FilterConstructor","_ECSDeps","filters","filterInstance","_ECSConfig","maxEntities","_filtersInstances","set","calculateSize","FilterDefinition","get","Error","name","Symbol","iterator","entries","removeEntityFromAllFilters","entity","values","removeEntityFromFilter","updateEntityInAllFilters","masks","maskBase","maskWords","includeOk","excludeOk","w","entityMaskWord","incWord","includeMask","excWord","excludeMask","addEntityToFilter","constructor","_maskWords","Map"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAKA,OAAO,MAAMA;IASJC,KAAKC,WAAwB,EAAEC,OAAsB,EAAQ;QAClE,KAAK,MAAMC,qBAAqB,IAAI,CAACC,QAAQ,CAACC,OAAO,CAAE;YACrD,MAAMC,iBAAiB,IAAIH,kBAAkB,IAAI,CAACI,UAAU,CAACC,WAAW,EAAEP,aAAaC;YACvF,IAAI,CAACO,iBAAiB,CAACC,GAAG,CAACP,mBAAmBG;QAChD;IACF;IAEOK,cAAcT,OAAsB,EAAQ;QACjD,KAAK,MAAMU,oBAAoB,IAAI,CAACR,QAAQ,CAACC,OAAO,CAAE;YACpDO,iBAAiBD,aAAa,CAAC,IAAI,CAACJ,UAAU,CAACC,WAAW,EAAEN;QAC9D;IACF;IAEOW,IAA2CV,iBAA6B,EAA4B;QACzG,MAAMG,iBAAiB,IAAI,CAACG,iBAAiB,CAACI,GAAG,CAACV;QAClD,IAAI,CAACG,gBAAgB;YACnB,MAAM,IAAIQ,MAAM,CAAC,OAAO,EAAEX,kBAAkBY,IAAI,CAAC,UAAU,CAAC;QAC9D;QACA,OAAOT;IACT;IAEO,CAACU,OAAOC,QAAQ,CAAC,GAAG;QACzB,OAAO,IAAI,CAACR,iBAAiB,CAACS,OAAO;IACvC;IAEOC,2BAA2BC,MAAc,EAAQ;QACtD,KAAK,MAAMd,kBAAkB,IAAI,CAACG,iBAAiB,CAACY,MAAM,GAAI;YAC5Df,eAAegB,sBAAsB,CAACF;QACxC;IACF;IAEOG,yBAAyBH,MAAc,EAAEI,KAAkB,EAAEC,QAAgB,EAAEC,SAAiB,EAAQ;QAC7G,KAAK,MAAMpB,kBAAkB,IAAI,CAACG,iBAAiB,CAACY,MAAM,GAAI;YAC5D,IAAIM,YAAY;YAChB,IAAIC,YAAY;YAEhB,IAAK,IAAIC,IAAI,GAAGA,IAAIH,WAAWG,IAAK;gBAClC,MAAMC,iBAAiBN,KAAK,CAACC,WAAWI,EAAE;oBAC1BvB;gBAAhB,MAAMyB,UAAUzB,CAAAA,gCAAAA,eAAe0B,WAAW,CAACH,EAAE,YAA7BvB,gCAAiC;oBACjCA;gBAAhB,MAAM2B,UAAU3B,CAAAA,gCAAAA,eAAe4B,WAAW,CAACL,EAAE,YAA7BvB,gCAAiC;gBAEjD,IAAIyB,WAAW,AAAED,CAAAA,iBAAiBC,OAAM,MAAO,MAAQA,YAAY,GAAI;oBACrEJ,YAAY;oBACZ;gBACF;gBACA,IAAIM,WAAW,AAACH,CAAAA,iBAAiBG,OAAM,MAAO,GAAG;oBAC/CL,YAAY;oBACZ;gBACF;YACF;YAEA,IAAID,aAAaC,WAAW;gBAC1BtB,eAAe6B,iBAAiB,CAACf;YACnC,OAAO;gBACLd,eAAegB,sBAAsB,CAACF;YACxC;QACF;IACF;IA/DAgB,YACE,AAAiB7B,UAAqB,EACtC,AAAiBH,QAAiB,EAClCiC,UAAkB,CAClB;aAHiB9B,aAAAA;aACAH,WAAAA;aAJFK,oBAAoB,IAAI6B;IAMtC;AA4DL"}
@@ -1 +1 @@
1
- {"version":3,"file":"mem.d.ts","sourceRoot":"","sources":["../../../src/lib/mem/mem.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGzD,qBAAa,GAAG;IAYF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAa,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX7E,SAAgB,WAAW,EAAE,WAAW,CAAC;IACzC,SAAgB,WAAW,EAAE,WAAW,CAAC;IACzC,SAAgB,iBAAiB,EAAE,iBAAiB,CAAC;IACrD,SAAgB,iBAAiB,EAAE,iBAAiB,CAAC;IACrD,SAAgB,cAAc,EAAE,cAAc,CAAC;IAC/C,SAAgB,eAAe,EAAE,eAAe,CAAC;IACjD,SAAgB,sBAAsB,EAAE,sBAAsB,CAAC;IAE/D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;gBAE5B,UAAU,EAAE,SAAS,EAAmB,QAAQ,EAAE,OAAO;IA8B/E,cAAc,IAAI,WAAW;IAI7B,aAAa,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAQpD,OAAO,CAAC,aAAa;IAUd,OAAO,IAAI,MAAM;CAQzB"}
1
+ {"version":3,"file":"mem.d.ts","sourceRoot":"","sources":["../../../src/lib/mem/mem.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGzD,qBAAa,GAAG;IAYF,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAa,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX7E,SAAgB,WAAW,EAAE,WAAW,CAAC;IACzC,SAAgB,WAAW,EAAE,WAAW,CAAC;IACzC,SAAgB,iBAAiB,EAAE,iBAAiB,CAAC;IACrD,SAAgB,iBAAiB,EAAE,iBAAiB,CAAC;IACrD,SAAgB,cAAc,EAAE,cAAc,CAAC;IAC/C,SAAgB,eAAe,EAAE,eAAe,CAAC;IACjD,SAAgB,sBAAsB,EAAE,sBAAsB,CAAC;IAE/D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;gBAE5B,UAAU,EAAE,SAAS,EAAmB,QAAQ,EAAE,OAAO;IAiC/E,cAAc,IAAI,WAAW;IAI7B,aAAa,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAQpD,OAAO,CAAC,aAAa;IAUd,OAAO,IAAI,MAAM;CAQzB"}
@@ -35,12 +35,14 @@ export class Mem {
35
35
  constructor(_ECSConfig, _ECSDeps){
36
36
  this._ECSConfig = _ECSConfig;
37
37
  this._ECSDeps = _ECSDeps;
38
+ // Derive mask word count from component count (1 word for ≤32, 2 for 33-64)
39
+ const maskWords = Math.max(1, Math.ceil(this._ECSDeps.components.length / 32));
38
40
  this.tickManager = new TickManager();
39
41
  this.prngManager = new PRNGManager(this._ECSConfig);
40
42
  this.componentsManager = new ComponentsManager(this._ECSConfig, this._ECSDeps);
41
43
  this.singletonsManager = new SingletonsManager(this._ECSDeps);
42
- this.filtersManager = new FiltersManager(this._ECSConfig, this._ECSDeps);
43
- this.entitiesManager = new EntitiesManager(this._ECSConfig, this.componentsManager, this.filtersManager);
44
+ this.filtersManager = new FiltersManager(this._ECSConfig, this._ECSDeps, maskWords);
45
+ this.entitiesManager = new EntitiesManager(this._ECSConfig, this.componentsManager, this.filtersManager, maskWords);
44
46
  this.playerResourcesManager = new PlayerResourcesManager(this._ECSConfig, this._ECSDeps);
45
47
  this._memoryManagers = [
46
48
  this.tickManager,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/mem/mem.ts"],"sourcesContent":["// libs/core/src/lib/mem/mem.ts\nimport { ECSDeps } from '../types/index.js';\nimport { ECSConfig } from '../ecs-config.js';\nimport { IAbstractMemory } from './abstract-memory.interface.js';\nimport { ComponentsManager } from './managers/components-manager.js';\nimport { EntitiesManager } from './managers/entities-manager.js';\nimport { SingletonsManager } from './managers/singletons-manager.js';\nimport { FiltersManager } from './managers/filters-manager.js';\nimport { PlayerResourcesManager } from './managers/player-resources-manager.js';\nimport { TickManager } from './managers/tick-manager.js';\nimport { PRNGManager } from './managers/prng-manager.js';\nimport { MemoryTracker } from '@lagless/binary';\n\nexport class Mem {\n public readonly tickManager: TickManager;\n public readonly prngManager: PRNGManager;\n public readonly componentsManager: ComponentsManager;\n public readonly singletonsManager: SingletonsManager;\n public readonly filtersManager: FiltersManager;\n public readonly entitiesManager: EntitiesManager;\n public readonly playerResourcesManager: PlayerResourcesManager;\n\n private readonly _arrayBuffer: ArrayBuffer;\n private readonly _memoryManagers: Array<IAbstractMemory>;\n\n constructor(private readonly _ECSConfig: ECSConfig, private readonly _ECSDeps: ECSDeps) {\n this.tickManager = new TickManager();\n this.prngManager = new PRNGManager(this._ECSConfig);\n this.componentsManager = new ComponentsManager(this._ECSConfig, this._ECSDeps);\n this.singletonsManager = new SingletonsManager(this._ECSDeps);\n this.filtersManager = new FiltersManager(this._ECSConfig, this._ECSDeps);\n this.entitiesManager = new EntitiesManager(this._ECSConfig, this.componentsManager, this.filtersManager);\n this.playerResourcesManager = new PlayerResourcesManager(this._ECSConfig, this._ECSDeps);\n\n this._memoryManagers = [\n this.tickManager,\n this.prngManager,\n this.componentsManager,\n this.singletonsManager,\n this.filtersManager,\n this.entitiesManager,\n this.playerResourcesManager,\n ];\n\n const arrayBufferSize = this.calculateSize();\n\n this._arrayBuffer = new ArrayBuffer(arrayBufferSize);\n\n const tracker = new MemoryTracker();\n\n for (const memoryManager of this._memoryManagers) {\n memoryManager.init(this._arrayBuffer, tracker);\n }\n }\n\n public exportSnapshot(): ArrayBuffer {\n return this._arrayBuffer.slice(0);\n }\n\n public applySnapshot(arrayBuffer: ArrayBuffer): void {\n if (arrayBuffer.byteLength !== this._arrayBuffer.byteLength) {\n throw new Error('Snapshot size mismatch');\n }\n\n new Uint8Array(this._arrayBuffer).set(new Uint8Array(arrayBuffer));\n }\n\n private calculateSize(): number {\n const tracker = new MemoryTracker();\n\n for (const memoryManager of this._memoryManagers) {\n memoryManager.calculateSize(tracker);\n }\n\n return tracker.ptr;\n }\n\n public getHash(): number {\n let hash = 0;\n const dataView = new DataView(this._arrayBuffer);\n for (let i = 0; i < this._arrayBuffer.byteLength; i++) {\n hash = (hash * 31 + dataView.getUint8(i)) >>> 0;\n }\n return hash;\n }\n}\n"],"names":["ComponentsManager","EntitiesManager","SingletonsManager","FiltersManager","PlayerResourcesManager","TickManager","PRNGManager","MemoryTracker","Mem","exportSnapshot","_arrayBuffer","slice","applySnapshot","arrayBuffer","byteLength","Error","Uint8Array","set","calculateSize","tracker","memoryManager","_memoryManagers","ptr","getHash","hash","dataView","DataView","i","getUint8","constructor","_ECSConfig","_ECSDeps","tickManager","prngManager","componentsManager","singletonsManager","filtersManager","entitiesManager","playerResourcesManager","arrayBufferSize","ArrayBuffer","init"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,+BAA+B;AAI/B,SAASA,iBAAiB,QAAQ,mCAAmC;AACrE,SAASC,eAAe,QAAQ,iCAAiC;AACjE,SAASC,iBAAiB,QAAQ,mCAAmC;AACrE,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,sBAAsB,QAAQ,yCAAyC;AAChF,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,aAAa,QAAQ,kBAAkB;AAEhD,OAAO,MAAMC;IA0CJC,iBAA8B;QACnC,OAAO,IAAI,CAACC,YAAY,CAACC,KAAK,CAAC;IACjC;IAEOC,cAAcC,WAAwB,EAAQ;QACnD,IAAIA,YAAYC,UAAU,KAAK,IAAI,CAACJ,YAAY,CAACI,UAAU,EAAE;YAC3D,MAAM,IAAIC,MAAM;QAClB;QAEA,IAAIC,WAAW,IAAI,CAACN,YAAY,EAAEO,GAAG,CAAC,IAAID,WAAWH;IACvD;IAEQK,gBAAwB;QAC9B,MAAMC,UAAU,IAAIZ;QAEpB,KAAK,MAAMa,iBAAiB,IAAI,CAACC,eAAe,CAAE;YAChDD,cAAcF,aAAa,CAACC;QAC9B;QAEA,OAAOA,QAAQG,GAAG;IACpB;IAEOC,UAAkB;QACvB,IAAIC,OAAO;QACX,MAAMC,WAAW,IAAIC,SAAS,IAAI,CAAChB,YAAY;QAC/C,IAAK,IAAIiB,IAAI,GAAGA,IAAI,IAAI,CAACjB,YAAY,CAACI,UAAU,EAAEa,IAAK;YACrDH,OAAO,AAACA,OAAO,KAAKC,SAASG,QAAQ,CAACD,OAAQ;QAChD;QACA,OAAOH;IACT;IA3DAK,YAAY,AAAiBC,UAAqB,EAAE,AAAiBC,QAAiB,CAAE;aAA3DD,aAAAA;aAAwCC,WAAAA;QACnE,IAAI,CAACC,WAAW,GAAG,IAAI3B;QACvB,IAAI,CAAC4B,WAAW,GAAG,IAAI3B,YAAY,IAAI,CAACwB,UAAU;QAClD,IAAI,CAACI,iBAAiB,GAAG,IAAIlC,kBAAkB,IAAI,CAAC8B,UAAU,EAAE,IAAI,CAACC,QAAQ;QAC7E,IAAI,CAACI,iBAAiB,GAAG,IAAIjC,kBAAkB,IAAI,CAAC6B,QAAQ;QAC5D,IAAI,CAACK,cAAc,GAAG,IAAIjC,eAAe,IAAI,CAAC2B,UAAU,EAAE,IAAI,CAACC,QAAQ;QACvE,IAAI,CAACM,eAAe,GAAG,IAAIpC,gBAAgB,IAAI,CAAC6B,UAAU,EAAE,IAAI,CAACI,iBAAiB,EAAE,IAAI,CAACE,cAAc;QACvG,IAAI,CAACE,sBAAsB,GAAG,IAAIlC,uBAAuB,IAAI,CAAC0B,UAAU,EAAE,IAAI,CAACC,QAAQ;QAEvF,IAAI,CAACV,eAAe,GAAG;YACrB,IAAI,CAACW,WAAW;YAChB,IAAI,CAACC,WAAW;YAChB,IAAI,CAACC,iBAAiB;YACtB,IAAI,CAACC,iBAAiB;YACtB,IAAI,CAACC,cAAc;YACnB,IAAI,CAACC,eAAe;YACpB,IAAI,CAACC,sBAAsB;SAC5B;QAED,MAAMC,kBAAkB,IAAI,CAACrB,aAAa;QAE1C,IAAI,CAACR,YAAY,GAAG,IAAI8B,YAAYD;QAEpC,MAAMpB,UAAU,IAAIZ;QAEpB,KAAK,MAAMa,iBAAiB,IAAI,CAACC,eAAe,CAAE;YAChDD,cAAcqB,IAAI,CAAC,IAAI,CAAC/B,YAAY,EAAES;QACxC;IACF;AAgCF"}
1
+ {"version":3,"sources":["../../../src/lib/mem/mem.ts"],"sourcesContent":["// libs/core/src/lib/mem/mem.ts\nimport { ECSDeps } from '../types/index.js';\nimport { ECSConfig } from '../ecs-config.js';\nimport { IAbstractMemory } from './abstract-memory.interface.js';\nimport { ComponentsManager } from './managers/components-manager.js';\nimport { EntitiesManager } from './managers/entities-manager.js';\nimport { SingletonsManager } from './managers/singletons-manager.js';\nimport { FiltersManager } from './managers/filters-manager.js';\nimport { PlayerResourcesManager } from './managers/player-resources-manager.js';\nimport { TickManager } from './managers/tick-manager.js';\nimport { PRNGManager } from './managers/prng-manager.js';\nimport { MemoryTracker } from '@lagless/binary';\n\nexport class Mem {\n public readonly tickManager: TickManager;\n public readonly prngManager: PRNGManager;\n public readonly componentsManager: ComponentsManager;\n public readonly singletonsManager: SingletonsManager;\n public readonly filtersManager: FiltersManager;\n public readonly entitiesManager: EntitiesManager;\n public readonly playerResourcesManager: PlayerResourcesManager;\n\n private readonly _arrayBuffer: ArrayBuffer;\n private readonly _memoryManagers: Array<IAbstractMemory>;\n\n constructor(private readonly _ECSConfig: ECSConfig, private readonly _ECSDeps: ECSDeps) {\n // Derive mask word count from component count (1 word for ≤32, 2 for 33-64)\n const maskWords = (Math.max(1, Math.ceil(this._ECSDeps.components.length / 32))) as 1 | 2;\n\n this.tickManager = new TickManager();\n this.prngManager = new PRNGManager(this._ECSConfig);\n this.componentsManager = new ComponentsManager(this._ECSConfig, this._ECSDeps);\n this.singletonsManager = new SingletonsManager(this._ECSDeps);\n this.filtersManager = new FiltersManager(this._ECSConfig, this._ECSDeps, maskWords);\n this.entitiesManager = new EntitiesManager(this._ECSConfig, this.componentsManager, this.filtersManager, maskWords);\n this.playerResourcesManager = new PlayerResourcesManager(this._ECSConfig, this._ECSDeps);\n\n this._memoryManagers = [\n this.tickManager,\n this.prngManager,\n this.componentsManager,\n this.singletonsManager,\n this.filtersManager,\n this.entitiesManager,\n this.playerResourcesManager,\n ];\n\n const arrayBufferSize = this.calculateSize();\n\n this._arrayBuffer = new ArrayBuffer(arrayBufferSize);\n\n const tracker = new MemoryTracker();\n\n for (const memoryManager of this._memoryManagers) {\n memoryManager.init(this._arrayBuffer, tracker);\n }\n }\n\n public exportSnapshot(): ArrayBuffer {\n return this._arrayBuffer.slice(0);\n }\n\n public applySnapshot(arrayBuffer: ArrayBuffer): void {\n if (arrayBuffer.byteLength !== this._arrayBuffer.byteLength) {\n throw new Error('Snapshot size mismatch');\n }\n\n new Uint8Array(this._arrayBuffer).set(new Uint8Array(arrayBuffer));\n }\n\n private calculateSize(): number {\n const tracker = new MemoryTracker();\n\n for (const memoryManager of this._memoryManagers) {\n memoryManager.calculateSize(tracker);\n }\n\n return tracker.ptr;\n }\n\n public getHash(): number {\n let hash = 0;\n const dataView = new DataView(this._arrayBuffer);\n for (let i = 0; i < this._arrayBuffer.byteLength; i++) {\n hash = (hash * 31 + dataView.getUint8(i)) >>> 0;\n }\n return hash;\n }\n}\n"],"names":["ComponentsManager","EntitiesManager","SingletonsManager","FiltersManager","PlayerResourcesManager","TickManager","PRNGManager","MemoryTracker","Mem","exportSnapshot","_arrayBuffer","slice","applySnapshot","arrayBuffer","byteLength","Error","Uint8Array","set","calculateSize","tracker","memoryManager","_memoryManagers","ptr","getHash","hash","dataView","DataView","i","getUint8","constructor","_ECSConfig","_ECSDeps","maskWords","Math","max","ceil","components","length","tickManager","prngManager","componentsManager","singletonsManager","filtersManager","entitiesManager","playerResourcesManager","arrayBufferSize","ArrayBuffer","init"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,+BAA+B;AAI/B,SAASA,iBAAiB,QAAQ,mCAAmC;AACrE,SAASC,eAAe,QAAQ,iCAAiC;AACjE,SAASC,iBAAiB,QAAQ,mCAAmC;AACrE,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,sBAAsB,QAAQ,yCAAyC;AAChF,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,aAAa,QAAQ,kBAAkB;AAEhD,OAAO,MAAMC;IA6CJC,iBAA8B;QACnC,OAAO,IAAI,CAACC,YAAY,CAACC,KAAK,CAAC;IACjC;IAEOC,cAAcC,WAAwB,EAAQ;QACnD,IAAIA,YAAYC,UAAU,KAAK,IAAI,CAACJ,YAAY,CAACI,UAAU,EAAE;YAC3D,MAAM,IAAIC,MAAM;QAClB;QAEA,IAAIC,WAAW,IAAI,CAACN,YAAY,EAAEO,GAAG,CAAC,IAAID,WAAWH;IACvD;IAEQK,gBAAwB;QAC9B,MAAMC,UAAU,IAAIZ;QAEpB,KAAK,MAAMa,iBAAiB,IAAI,CAACC,eAAe,CAAE;YAChDD,cAAcF,aAAa,CAACC;QAC9B;QAEA,OAAOA,QAAQG,GAAG;IACpB;IAEOC,UAAkB;QACvB,IAAIC,OAAO;QACX,MAAMC,WAAW,IAAIC,SAAS,IAAI,CAAChB,YAAY;QAC/C,IAAK,IAAIiB,IAAI,GAAGA,IAAI,IAAI,CAACjB,YAAY,CAACI,UAAU,EAAEa,IAAK;YACrDH,OAAO,AAACA,OAAO,KAAKC,SAASG,QAAQ,CAACD,OAAQ;QAChD;QACA,OAAOH;IACT;IA9DAK,YAAY,AAAiBC,UAAqB,EAAE,AAAiBC,QAAiB,CAAE;aAA3DD,aAAAA;aAAwCC,WAAAA;QACnE,4EAA4E;QAC5E,MAAMC,YAAaC,KAAKC,GAAG,CAAC,GAAGD,KAAKE,IAAI,CAAC,IAAI,CAACJ,QAAQ,CAACK,UAAU,CAACC,MAAM,GAAG;QAE3E,IAAI,CAACC,WAAW,GAAG,IAAIjC;QACvB,IAAI,CAACkC,WAAW,GAAG,IAAIjC,YAAY,IAAI,CAACwB,UAAU;QAClD,IAAI,CAACU,iBAAiB,GAAG,IAAIxC,kBAAkB,IAAI,CAAC8B,UAAU,EAAE,IAAI,CAACC,QAAQ;QAC7E,IAAI,CAACU,iBAAiB,GAAG,IAAIvC,kBAAkB,IAAI,CAAC6B,QAAQ;QAC5D,IAAI,CAACW,cAAc,GAAG,IAAIvC,eAAe,IAAI,CAAC2B,UAAU,EAAE,IAAI,CAACC,QAAQ,EAAEC;QACzE,IAAI,CAACW,eAAe,GAAG,IAAI1C,gBAAgB,IAAI,CAAC6B,UAAU,EAAE,IAAI,CAACU,iBAAiB,EAAE,IAAI,CAACE,cAAc,EAAEV;QACzG,IAAI,CAACY,sBAAsB,GAAG,IAAIxC,uBAAuB,IAAI,CAAC0B,UAAU,EAAE,IAAI,CAACC,QAAQ;QAEvF,IAAI,CAACV,eAAe,GAAG;YACrB,IAAI,CAACiB,WAAW;YAChB,IAAI,CAACC,WAAW;YAChB,IAAI,CAACC,iBAAiB;YACtB,IAAI,CAACC,iBAAiB;YACtB,IAAI,CAACC,cAAc;YACnB,IAAI,CAACC,eAAe;YACpB,IAAI,CAACC,sBAAsB;SAC5B;QAED,MAAMC,kBAAkB,IAAI,CAAC3B,aAAa;QAE1C,IAAI,CAACR,YAAY,GAAG,IAAIoC,YAAYD;QAEpC,MAAM1B,UAAU,IAAIZ;QAEpB,KAAK,MAAMa,iBAAiB,IAAI,CAACC,eAAe,CAAE;YAChDD,cAAc2B,IAAI,CAAC,IAAI,CAACrC,YAAY,EAAES;QACxC;IACF;AAgCF"}
@@ -14,14 +14,15 @@ export declare abstract class Signal<TData = unknown> {
14
14
  readonly Cancelled: EventEmitter<SignalEvent<TData>>;
15
15
  private readonly _pending;
16
16
  private readonly _awaitingVerification;
17
- private readonly _maxInputDelayTick;
17
+ private _lastVerifiedTick;
18
18
  constructor(_ECSConfig: ECSConfig);
19
19
  emit(tick: number, data: TData): void;
20
20
  /**
21
- * Проверка Verified/Cancelled (вызывается каждый тик из SignalsRegistry)
21
+ * Verify/cancel signals for ticks up to verifiedTick.
22
+ * Called each simulation tick from SignalsRegistry.
22
23
  * @internal
23
24
  */
24
- _onTick(currentTick: number): void;
25
+ _onTick(verifiedTick: number): void;
25
26
  /**
26
27
  * Перед rollback — очищаем pending для тиков которые будут пересимулированы
27
28
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../../../src/lib/signals/signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,MAAM,WAAW,WAAW,CAAC,KAAK;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,KAAK,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IAEjC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;CACnC;AAED,8BACsB,MAAM,CAAC,KAAK,GAAG,OAAO;IAS9B,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS;IARpD,SAAgB,SAAS,mCAA0C;IACnE,SAAgB,QAAQ,mCAA0C;IAClE,SAAgB,SAAS,mCAA0C;IAEnE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA8B;IACpE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;gBAEb,UAAU,EAAE,SAAS;IAI7C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI;IA4B5C;;;OAGG;IACI,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAmCzC;;;OAGG;IACI,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAS9C;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO;IAoB3C,OAAO,IAAI,IAAI;CAOvB"}
1
+ {"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../../../src/lib/signals/signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,MAAM,WAAW,WAAW,CAAC,KAAK;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,KAAK,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IAEjC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;CACnC;AAED,8BACsB,MAAM,CAAC,KAAK,GAAG,OAAO;IAS9B,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS;IARpD,SAAgB,SAAS,mCAA0C;IACnE,SAAgB,QAAQ,mCAA0C;IAClE,SAAgB,SAAS,mCAA0C;IAEnE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA8B;IACpE,OAAO,CAAC,iBAAiB,CAAM;gBAEA,UAAU,EAAE,SAAS;IAE7C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI;IA4B5C;;;;OAIG;IACI,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAgC1C;;;OAGG;IACI,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAS9C;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO;IAoB3C,OAAO,IAAI,IAAI;CAQvB"}
@@ -32,43 +32,42 @@ export class Signal {
32
32
  }
33
33
  }
34
34
  /**
35
- * Проверка Verified/Cancelled (вызывается каждый тик из SignalsRegistry)
35
+ * Verify/cancel signals for ticks up to verifiedTick.
36
+ * Called each simulation tick from SignalsRegistry.
36
37
  * @internal
37
- */ _onTick(currentTick) {
38
- const verifyTick = currentTick - this._maxInputDelayTick;
39
- if (verifyTick < 0) return;
40
- const awaiting = this._awaitingVerification.get(verifyTick);
41
- if (!awaiting || awaiting.length === 0) {
42
- this._cleanupTick(verifyTick);
43
- return;
44
- }
45
- var _this__pending_get;
46
- const pending = (_this__pending_get = this._pending.get(verifyTick)) != null ? _this__pending_get : [];
47
- const pendingMatched = new Array(pending.length).fill(false);
48
- for (const awaitingData of awaiting){
49
- // Ищем matching событие в pending
50
- let matchIdx = -1;
51
- for(let i = 0; i < pending.length; i++){
52
- if (!pendingMatched[i] && this._dataEquals(pending[i], awaitingData)) {
53
- matchIdx = i;
54
- break;
38
+ */ _onTick(verifiedTick) {
39
+ while(this._lastVerifiedTick < verifiedTick){
40
+ const nextTick = this._lastVerifiedTick + 1;
41
+ const awaiting = this._awaitingVerification.get(nextTick);
42
+ if (awaiting && awaiting.length > 0) {
43
+ var _this__pending_get;
44
+ const pending = (_this__pending_get = this._pending.get(nextTick)) != null ? _this__pending_get : [];
45
+ const pendingMatched = new Array(pending.length).fill(false);
46
+ for (const awaitingData of awaiting){
47
+ let matchIdx = -1;
48
+ for(let i = 0; i < pending.length; i++){
49
+ if (!pendingMatched[i] && this._dataEquals(pending[i], awaitingData)) {
50
+ matchIdx = i;
51
+ break;
52
+ }
53
+ }
54
+ if (matchIdx >= 0) {
55
+ pendingMatched[matchIdx] = true;
56
+ this.Verified.emit({
57
+ tick: nextTick,
58
+ data: awaitingData
59
+ });
60
+ } else {
61
+ this.Cancelled.emit({
62
+ tick: nextTick,
63
+ data: awaitingData
64
+ });
65
+ }
55
66
  }
56
67
  }
57
- if (matchIdx >= 0) {
58
- pendingMatched[matchIdx] = true;
59
- this.Verified.emit({
60
- tick: verifyTick,
61
- data: awaitingData
62
- });
63
- } else {
64
- // Событие было Predicted, но нет в pending после rollback
65
- this.Cancelled.emit({
66
- tick: verifyTick,
67
- data: awaitingData
68
- });
69
- }
68
+ this._cleanupTick(nextTick);
69
+ this._lastVerifiedTick = nextTick;
70
70
  }
71
- this._cleanupTick(verifyTick);
72
71
  }
73
72
  /**
74
73
  * Перед rollback — очищаем pending для тиков которые будут пересимулированы
@@ -108,6 +107,7 @@ export class Signal {
108
107
  dispose() {
109
108
  this._pending.clear();
110
109
  this._awaitingVerification.clear();
110
+ this._lastVerifiedTick = -1;
111
111
  this.Predicted.clear();
112
112
  this.Verified.clear();
113
113
  this.Cancelled.clear();
@@ -119,7 +119,7 @@ export class Signal {
119
119
  this.Cancelled = new EventEmitter();
120
120
  this._pending = new Map();
121
121
  this._awaitingVerification = new Map();
122
- this._maxInputDelayTick = _ECSConfig.maxInputDelayTick;
122
+ this._lastVerifiedTick = -1;
123
123
  }
124
124
  }
125
125
  Signal = _ts_decorate([