UNPKG

ecsjs

Version:

An entity component system library for JavaScript

64 lines (55 loc) 1.98 kB
import type { ComponentMap } from './component-map.js'; import type { EntityMap } from './entity-map.js'; import type { ComponentClass, ComponentInstances, IteratorResult } from './types.js'; /** * @category Iterators * @example * // construct an instance * const iterator = new ComponentIterator(entityMap, Player, Position) * * // iterate each component value that is related to the Player * for(const [entityId, player, position] of iterator) { } * * // you can also reset the iterator back to the start * // without having to create a new ComponentIterator instance * iterator.reset() * for(const [entityId, player, position] of iterator) { } */ export class ComponentIterator< TComponentKey extends ComponentClass<any>, TComponentClasses extends ComponentClass<any>[] > { private keyMap: ComponentMap<any> private components: ComponentMap<any>[] // iteration state private entries: MapIterator<[number, TComponentKey]> /** * {@link ComponentNotRegistered} when any of specified component(s) are not registered */ constructor(public ecs: EntityMap, public key: TComponentKey, ...components: TComponentClasses) { this.keyMap = this.ecs.getMap(key)!; this.entries = this.keyMap.entries(); this.components = components.map(x => this.ecs.getMap(x)!); } /** * gets the next iterator value */ next(): IteratorResult<ComponentInstances<[ComponentClass<number>, TComponentKey, ...TComponentClasses]>> { const entry = this.entries.next(); const { value, done } = entry; if (done) return { value: value as any, done }; const [entityId, entityValue] = value; const results = [entityId, entityValue] for (const x of this.components) { results.push(x.get(entityId)); } return { value: results as any, done: false }; } /** * resets the iterator back to the first entry */ reset() { this.entries = this.keyMap.entries(); } [Symbol.iterator]() { return this; } }