/** * Runtime Entity * @param apiEntity GameLib.D3.API.Entity * @constructor */ GameLib.Entity = function ( apiEntity ) { 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) */ 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) { GameLib.Utils.PushUnique(this.components, 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 { /** * 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 ) { GameLib.Utils.PushUnique(this.components, 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; } 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.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) ); }; /** * Entity from Object * @param objectEntity Object * @param parentEntityManager GameLib.D3.EntityManager * @returns {GameLib.Entity} * @constructor */ GameLib.Entity.FromObject = function(objectEntity, parentEntityManager) { var apiEntity = GameLib.API.Entity.FromObject(objectEntity); var entity = new GameLib.Entity( apiEntity ); if (GameLib.Utils.UndefinedOrNull(parentEntityManager)) { return entity; } parentEntityManager.addEntity(entity); return entity; };