import Query from './query.js'; export default class System { destroying = []; ecs; queries = {}; constructor(ecs) { this.ecs = ecs; const queries = this.constructor.queries(); for (const i in queries) { this.queries[i] = new Query(queries[i], ecs.Types); } } deindex(entityIds) { for (const i in this.queries) { this.queries[i].deindex(entityIds); } } destroyEntity(entityId) { this.destroyManyEntities([entityId]); } destroyManyEntities(entityIds) { for (let i = 0; i < entityIds.length; i++) { this.destroying.push(entityIds[i]); } } finalize() {} static normalize(SystemLike) { if (SystemLike.prototype instanceof System) { return SystemLike; } if ('function' === typeof SystemLike) { class TickingSystem extends System {} TickingSystem.prototype.tick = SystemLike; return TickingSystem; } /* v8 ignore next */ throw new TypeError(`Couldn't normalize '${SystemLike}' as a system`); } static queries() { return {}; } reindex(entityIds) { for (const i in this.queries) { this.queries[i].reindex(entityIds); } } select(query) { return this.queries[query].select(); } tickDestruction() { this.deindex(this.destroying); this.destroying = []; } tick() {} static wrap(source, ecs) { class WrappedSystem extends System.normalize(source) { constructor() { super(ecs); this.reindex(ecs.entities); } createEntity(components) { return this.ecs.create(components); } createManyEntities(componentsList) { return this.ecs.createMany(componentsList); } get source() { return source; } insertComponents(entityId, components) { this.ecs.insert(entityId, components); } insertManyComponents(components) { this.ecs.insertMany(components); } removeComponents(entityId, components) { this.ecs.remove(entityId, components); } removeManyComponents(entityIds) { this.ecs.removeMany(entityIds); } } return new WrappedSystem(); } }