export { Component } from './serpentity/component.js'; export { Entity } from './serpentity/entity.js'; export { Node } from './serpentity/node.js'; export { System } from './serpentity/system.js'; import { NodeCollection } from './serpentity/node_collection.js'; /* * Serpentity is the main engine class */ export default class Serpentity { constructor(config) { this.systems = []; this.entities = []; this._nodeCollections = []; this._nodeCollectionKeys = []; Object.assign(this, config); } /* * Adds a system to the engine, so its update method will be called * with the others. Triggers added hook. * * returns true if added succesfully, false if already added */ addSystem(system, priority) { if (this.systems.indexOf(system) >= 0) { return false; } system.priority = priority; let lastIndex = 0; const found = this.systems.some((existingSystem, i) => { lastIndex = i; if (existingSystem.priority >= system.priority) { return true; } }); if (!found) { lastIndex += 1; } this.systems.splice(lastIndex, 0, system); system.added(this); return true; } /* * Removes a system from the engine, so its update method will no * longer will be called. Triggers the removed hook. * * returns true if removed succesfully, false if already added */ removeSystem(system) { const position = this.systems.indexOf(system); if (position >= 0) { this.systems[position].removed(this); this.systems.splice(position, 1); return true; } return false; } /* * Adds an entity to the engine, adds to existing node collections * * returns true if added, false if already there */ addEntity(entity) { if (this.entities.indexOf(entity) >= 0) { return false; } this.entities.push(entity); for (const collection of this._nodeCollections) { collection.add(entity); } return true; } /* * Removes entity from system, removing from all node collections * * returns true if removed, false if not present */ removeEntity(entity) { const position = this.entities.indexOf(entity); if (position >= 0) { for (const collection of this._nodeCollections) { collection.remove(entity); } this.entities.splice(position, 1); return true; } return false; } /* * Given a Node Class, retrieves a list of all the nodes for each * applicable entity. */ getNodes(nodeType) { const position = this._nodeCollectionKeys.indexOf(nodeType); if (position >= 0) { return this._nodeCollections[position]; } const nodeCollection = new NodeCollection({ type: nodeType }); this._nodeCollectionKeys.push(nodeType); this._nodeCollections.push(nodeCollection); for (const entity of this.entities) { nodeCollection.add(entity); } return nodeCollection; } /* * Calls update for every loaded system. */ update(dt) { for (const system of this.systems) { system.update(dt); } } }