/** * Runtime Entity * @param apiEntity GameLib.D3.API.Entity * @constructor */ GameLib.Entity = function ( apiEntity ) { if (GameLib.Utils.UndefinedOrNull(apiEntity)) { apiEntity = {}; } GameLib.API.Entity.call( this, apiEntity.id, apiEntity.name, apiEntity.components, apiEntity.parentEntity ); GameLib.Component.call( this, { 'components' : [GameLib.Component] } ); }; GameLib.Entity.prototype = Object.create(GameLib.Component.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) */ this.instance = true; GameLib.Component.prototype.createInstance.call(this); }; /** * Adds a component to this entity through the instance (should notify the entity manager instance) * @param component */ GameLib.Entity.prototype.addComponent = function(component) { // if (component instanceof GameLib.D3.Mesh) { // // /** // * For meshes, simply get the children components // * @type {Array} // */ // component.getChildrenComponents().map(function(childComponent){ // GameLib.Utils.PushUnique(this.components, childComponent); // childComponent.parentEntity = this; // }.bind(this)) // // } else { if (component instanceof GameLib.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 */ Object.keys(component.idToObject).map( function(componentId) { GameLib.Utils.PushUnique(this.components, component.idToObject[componentId]); component.idToObject[componentId].parentEntity = this; }.bind(this) ); GameLib.Utils.PushUnique(this.components, component); } // } /** * 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; } var childIndex = this.components.indexOf(component); if (childIndex !== -1) { this.components.splice(childIndex, 1); } else { console.error('component not found'); } /** * Break the dependency to the parent */ component.parentEntity = null; return true; }; /** * Updates an entity instance */ GameLib.Entity.prototype.updateInstance = function() { console.log('entity update instance called'); }; /** * Converts a GameLib.Entity to GameLib.API.Entity * @returns {GameLib.API.Entity} */ GameLib.Entity.prototype.toApiObject = function() { var apiComponents = this.components.map( function(component) { return GameLib.Utils.IdOrNull(component); } ); return new GameLib.API.Entity( this.id, this.name, apiComponents, GameLib.Utils.IdOrNull(this.parentEntity) ); }; /** * Entity from Object * @param objectEntity Object * @returns {GameLib.Entity} * @constructor */ GameLib.Entity.FromObject = function(objectEntity) { var apiEntity = GameLib.API.Entity.FromObject(objectEntity); var entity = new GameLib.Entity( apiEntity ); GameLib.EntityManager.Instance.addEntity(entity); return entity; };