/** * GameLib.EntityManager * @param graphics GameLib.D3.Graphics * @param apiEntityManager GameLib.API.EntityManager * @constructor */ GameLib.EntityManager = function( graphics, apiEntityManager ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); if (GameLib.Utils.UndefinedOrNull(apiEntityManager)) { apiEntityManager = {}; } if (apiEntityManager instanceof GameLib.EntityManager) { return apiEntityManager; } GameLib.API.EntityManager.call( this, apiEntityManager.id, apiEntityManager.name, apiEntityManager.entities, // apiEntityManager.systems, apiEntityManager.parentEntity ); this.entities = this.entities.map( function(apiEntity) { if (apiEntity instanceof GameLib.API.Entity) { return new GameLib.Entity( this.graphics, apiEntity ) } else { console.warn('Entity not of type API.Entity'); throw new Error('Entity not of type API.Entity'); } }.bind(this) ); // this.systems = this.systems.map( // function(apiSystem) { // // if (apiSystem instanceof GameLib.API.System) { // return new GameLib.System( // this.graphics, // apiSystem // ) // } else { // console.warn('System not of type API.System'); // throw new Error('System not of type API.System'); // } // // }.bind(this) // ); this.buildIdToObject(); this.instance = this.createInstance(); this.registerCallbacks(); }; GameLib.EntityManager.prototype = Object.create(GameLib.API.EntityManager.prototype); GameLib.EntityManager.prototype.constructor = GameLib.EntityManager; /** * Creates an Entity Manager instance * @returns {*} */ GameLib.EntityManager.prototype.createInstance = function() { /** * Fuck the current ECS bullshit on the internet - both tiny-ecs and ecsjs SUCKS ASS */ return null; }; /** * Creates an GameLib.Entity and adds it to entities array * @returns {*} */ GameLib.EntityManager.prototype.createEntity = function(name) { var apiEntity = new GameLib.API.Entity( null, name, null, null, this ); var entity = new GameLib.Entity( this.graphics, apiEntity ); this.entities.push(entity); return entity; }; /** * Returns an entity by ID or null * @param id * @returns {*} */ GameLib.EntityManager.prototype.findEntityById = function(id) { return this.entities.reduce( function(result, entity){ if (entity.id === id) { result = entity; } return result; }, null ); }; GameLib.EntityManager.prototype.findHelperByObject = function(object) { return this.entities.reduce( function(result, entity) { var helpers = entity.getComponents(GameLib.D3.Helper); var helper = helpers.reduce( function(helperResult, tmpHelper) { if (tmpHelper.object === object) { helperResult = tmpHelper; } return helperResult; }, null ); if (helper) { result = helper; } return result; }, null ); }; /** * Adds an entity to this manager * @param entity GameLib.Entity */ GameLib.EntityManager.prototype.addEntity = function(entity) { entity.parentEntityManager = this; this.entities.push(entity); }; // /** // * Adds a system to this manager // * @param system GameLib.System // */ // GameLib.EntityManager.prototype.addSystem = function(system) { // this.systems.push(system); // }; /** * Returns entity by name * @param name * @returns {*} */ GameLib.EntityManager.prototype.queryByName = function(name) { return this.entities.reduce( function(result, entity){ if (entity.name === name) { result = entity; } return result; }, null ) }; /** * Removes an entity - do we remove all its components as well? * @param entity GameLib.D3.Entity * @returns boolean true if successful */ GameLib.EntityManager.prototype.removeEntity = function(entity) { var index = this.entities.indexOf(entity); if (index === -1) { console.log('failed to remove entity : ', entity); return false; } entity.parentEntityManager = null; this.entities.splice(index, 1); return true; }; /** * Returns all the entities with the following components * @param components GameLib.Component[] */ GameLib.EntityManager.prototype.query = function(components) { var entities = this.entities.reduce( function(result, entity) { var hasAllComponents = components.reduce( function(componentResult, component) { if (!entity.hasComponent(component)) { componentResult = false; } return componentResult; }, true ); if (hasAllComponents) { result.push(entity); } return result; }, [] ); return entities; }; /** * Returns all actual components of all entities that contain this component * @param constructor */ GameLib.EntityManager.prototype.queryComponents = function(constructor) { var entities = this.query([constructor]); var components = entities.reduce( function(result, entity){ var ecs = entity.getComponents(constructor); ecs.map(function(ec){ result.push(ec); }); return result; }, [] ); return components; }; /** * Converts a GameLib.Entity to GameLib.API.Entity * @returns {GameLib.API.EntityManager} */ GameLib.EntityManager.prototype.toApiObject = function() { var apiEntities = this.entities.map( function (entity) { return entity.toApiObject(); } ); // var apiSystems = this.systems.map( // function (system) { // return system.toApiObject(); // } // ); var apiEntityManager = new GameLib.API.EntityManager( this.id, this.name, apiEntities, // apiSystems, this.parentEntity ); return apiEntityManager; }; /** * Returns an EntityManager from an Object entity manager * @param graphics * @param objectEntityManager Object * @constructor */ GameLib.EntityManager.FromObjectEntityManager = function(graphics, objectEntityManager) { var apiEntityManager = GameLib.API.EntityManager.FromObjectEntityManager(objectEntityManager); var entityManager = new GameLib.EntityManager( graphics, apiEntityManager ); return entityManager; }; GameLib.EntityManager.prototype.onParentSceneChange = function(data) { if (data.object instanceof GameLib.D3.Mesh) { /** * We remove the helper (if any) from the old scene and add it to the new scene */ var helper = this.findHelperByObject(data.object); if (helper) { data.originalScene.instance.remove(helper.instance); data.newScene.instance.add(helper.instance); } /** * We remove the mesh from the old scene and add it to the new scene */ data.originalScene.removeMesh(data.object); data.newScene.addMesh(data.object); /** * We inherit the parent entity of this new scene */ var originalEntity = null; var newEntity = null; if (data.object.hasOwnProperty('parentEntity')) { originalEntity = data.object.parentEntity } if (data.newScene.hasOwnProperty('parentEntity')) { newEntity = data.newScene.parentEntity; } if (originalEntity && newEntity) { /** * We also transfer the helper (as a component) to the new entity */ if (helper) { originalEntity.removeComponent(helper); newEntity.addComponent(helper); } originalEntity.removeComponent(data.object); newEntity.addComponent(data.object); /** * Now also remove the object from the GUI */ var gui = originalEntity.getFirstComponent(GameLib.GUI); if (gui) { gui.removeObject(data.object); gui.build(this); gui = newEntity.getFirstComponent(GameLib.GUI); if (gui) { gui.addObject(data.object); gui.build(this); } } } } if (data.object instanceof GameLib.D3.Light) { console.log('implement remove light here'); } }; /** * */ GameLib.EntityManager.prototype.registerCallbacks = function() { this.subscribe( GameLib.Event.PARENT_SCENE_CHANGE, this.onParentSceneChange ) }; /** * Links object Ids to actual objects * @param idToObject */ // GameLib.EntityManager.prototype.linkObjects = function(idToObject) { // // this.entities.map( // function(entity) { // entity.components.map( // function (componentId, index, array) { // if (componentId instanceof GameLib.Component) { // array[index] = componentId; // } else { // array[index] = idToObject[componentId]; // } // // Object.keys(array[index].linkedObjects).map( // function (propertyName) { // array[index][propertyName] = idToObject[array[index][propertyName]]; // } // ); // // array[index].loaded = true; // } // ) // } // ); // // };