/** * Runtime Entity * @param graphics GameLib.D3.Graphics * @param apiEntity GameLib.D3.API.Entity * @constructor */ GameLib.Entity = function ( graphics, apiEntity ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); if (GameLib.Utils.UndefinedOrNull(apiEntity)) { apiEntity = {}; } if (apiEntity instanceof GameLib.Entity) { return apiEntity; } GameLib.API.Entity.call( this, apiEntity.id, apiEntity.name, apiEntity.components, apiEntity.parentEntity, apiEntity.parentEntityManager ); this.componentToCreate = 0; GameLib.Component.call( this, GameLib.Component.COMPONENT_ENTITY, { 'components' : [GameLib.Component], 'activeComponent' : GameLib.Component } ); }; GameLib.Entity.prototype = Object.create(GameLib.API.Entity.prototype); GameLib.Entity.prototype.constructor = GameLib.Entity; /** * Creates an entity instance */ GameLib.Entity.prototype.createInstance = function() { /** * FUCK ecsjs and tiny-ecs - no client-side support and shitty code (only takes constructors as args) */ return null; }; /** * Adds a component to this entity through the instance (should notify the entity manager instance) * @param component */ GameLib.Entity.prototype.addComponent = function(component) { this.components.push(component); /** * Here we will dig into this component - find all its 'parentEntity' members - and update them accordingly */ component.buildIdToObject(); /** * Also add the child components of this component as components of this entity */ for (var property in component.idToObject) { if (component.idToObject.hasOwnProperty(property) && component.idToObject[property] !== component && component.idToObject[property] instanceof GameLib.Component && this.components.indexOf(component.idToObject[property] === -1) ) { this.components.push(component.idToObject[property]); component.idToObject[property].parentEntity = this; } } /** * Finally, we are the boss component - update my parent entity * @type {GameLib.Entity} */ component.parentEntity = this; }; /** * Returns all components of type 'constructor' * @param constructor */ GameLib.Entity.prototype.getComponents = function(constructor) { var components = this.components.reduce( function(result, component) { if (component instanceof constructor) { result.push(component); } return result; }, [] ); return components; }; /** * Returns the first component or null * @param constructor */ GameLib.Entity.prototype.getFirstComponent = function(constructor) { var components = this.getComponents(constructor); if (components.length > 0) { return components[0]; } return null; }; /** * Returns true when this entity has a certain component, false otherwise * @param constructor */ GameLib.Entity.prototype.hasComponent = function(constructor) { var has = this.components.reduce( function(result, component) { if (component instanceof constructor) { result = true; } return result; }, false ); return has; }; /** * * @param component */ GameLib.Entity.prototype.removeComponent = function(component) { if (GameLib.Utils.UndefinedOrNull(component)) { component = this.activeComponent; } /** * We also had added all the child components of this component, so we remove them first */ for (var property in component.idToObject) { if (component.idToObject.hasOwnProperty(property)) { if (component.idToObject[property] instanceof GameLib.Component) { if (component.idToObject[property].parentEntity === this) { var childIndex = this.components.indexOf(component.idToObject[property]); if (childIndex !== -1) { this.components.splice(childIndex, 1); component.idToObject[property].parentEntity = null; } } } } } /** * Now we remove the boss entity * @type {null} */ component.parentEntity = null; var index = this.components.indexOf(component); if (index === -1) { console.log('failed to remove component : ', component); return false; } this.components.splice(index, 1); return true; }; /** * Updates an entity instance */ GameLib.Entity.prototype.updateInstance = function() { this.instance = this.createInstance(true); }; /** * Converts a GameLib.Entity to GameLib.API.Entity * @returns {GameLib.API.Entity} */ GameLib.Entity.prototype.toApiObject = function() { var apiComponents = this.components.reduce( function(result, component) { if (typeof component.toApiObject === 'function') { result.push(component.toApiObject()); } else { console.log('ignored runtime component : ' + component.name); } return result; }, [] ); return new GameLib.API.Entity( this.id, this.name, apiComponents, GameLib.Utils.IdOrNull(this.parentEntity), GameLib.Utils.IdOrNull(this.parentEntityManager) ); }; /** * * @param graphics GameLib.D3.Graphics * @param objectEntity Object * @constructor */ GameLib.Entity.FromObject = function(graphics, objectEntity) { var apiEntity = GameLib.API.Entity.FromObject(objectEntity); return new GameLib.Entity( graphics, apiEntity ); };