ecsy
Version:
Entity Component System in JS
151 lines (116 loc) • 3.65 kB
JavaScript
import Query from "./Query.js";
export class Entity {
constructor(entityManager) {
this._entityManager = entityManager || null;
// Unique ID for this entity
this.id = entityManager._nextEntityId++;
// List of components types the entity has
this._ComponentTypes = [];
// Instance of the components
this._components = {};
this._componentsToRemove = {};
// Queries where the entity is added
this.queries = [];
// Used for deferred removal
this._ComponentTypesToRemove = [];
this.alive = false;
//if there are state components on a entity, it can't be removed completely
this.numStateComponents = 0;
}
// COMPONENTS
getComponent(Component, includeRemoved) {
var component = this._components[Component._typeId];
if (!component && includeRemoved === true) {
component = this._componentsToRemove[Component._typeId];
}
return component;
}
getRemovedComponent(Component) {
const component = this._componentsToRemove[Component._typeId];
return component;
}
getComponents() {
return this._components;
}
getComponentsToRemove() {
return this._componentsToRemove;
}
getComponentTypes() {
return this._ComponentTypes;
}
getMutableComponent(Component) {
var component = this._components[Component._typeId];
if (!component) {
return;
}
for (var i = 0; i < this.queries.length; i++) {
var query = this.queries[i];
// @todo accelerate this check. Maybe having query._Components as an object
// @todo add Not components
if (query.reactive && query.Components.indexOf(Component) !== -1) {
query.eventDispatcher.dispatchEvent(
Query.prototype.COMPONENT_CHANGED,
this,
component
);
}
}
return component;
}
addComponent(Component, values) {
this._entityManager.entityAddComponent(this, Component, values);
return this;
}
removeComponent(Component, forceImmediate) {
this._entityManager.entityRemoveComponent(this, Component, forceImmediate);
return this;
}
hasComponent(Component, includeRemoved) {
return (
!!~this._ComponentTypes.indexOf(Component) ||
(includeRemoved === true && this.hasRemovedComponent(Component))
);
}
hasRemovedComponent(Component) {
return !!~this._ComponentTypesToRemove.indexOf(Component);
}
hasAllComponents(Components) {
for (var i = 0; i < Components.length; i++) {
if (!this.hasComponent(Components[i])) return false;
}
return true;
}
hasAnyComponents(Components) {
for (var i = 0; i < Components.length; i++) {
if (this.hasComponent(Components[i])) return true;
}
return false;
}
removeAllComponents(forceImmediate) {
return this._entityManager.entityRemoveAllComponents(this, forceImmediate);
}
copy(src) {
// TODO: This can definitely be optimized
for (var ecsyComponentId in src._components) {
var srcComponent = src._components[ecsyComponentId];
this.addComponent(srcComponent.constructor);
var component = this.getComponent(srcComponent.constructor);
component.copy(srcComponent);
}
return this;
}
clone() {
return new Entity(this._entityManager).copy(this);
}
reset() {
this.id = this._entityManager._nextEntityId++;
this._ComponentTypes.length = 0;
this.queries.length = 0;
for (var ecsyComponentId in this._components) {
delete this._components[ecsyComponentId];
}
}
remove(forceImmediate) {
return this._entityManager.removeEntity(this, forceImmediate);
}
}