export interface Entity extends HTMLElement {
components: any;
addComponent: (component)=>{};
}
export class EntityMgr {
static entityTag = 'ash-entity';
static getDefaultComponent;
static hasNewMember: boolean = false;
static create(name: string = null, pure = false) {
this.hasNewMember = true;
let gameObject = document.createElement(this.entityTag) as Entity;
if(name) {
gameObject.dataset.name = name;
gameObject.textContent = name;
}
gameObject.components = {};
if(this.getDefaultComponent && !pure)
this.addComponent(gameObject, this.getDefaultComponent());
// Alias
gameObject['addComponent'] = (comp) => this.addComponent(gameObject, comp);
// Debug envent
gameObject.addEventListener('pointerdown', e => {
console.log('\t|-' + gameObject.dataset.name);
console.log(gameObject.components);
let trans = gameObject.components.Transform;
// toggle visible
if(trans != null) {
trans.isVisible = !trans.isVisible;
}
e.stopPropagation();
})
return gameObject;
}
static cloneMethods = {};
static clone(entity: Entity) {
let temp = this.create(entity.dataset.name, true);
this.addComponent(temp, this.cloneMethods['_Transform'](entity.components.Transform));
for(let comp in entity.components) {
if(this.cloneMethods[comp]) {
this.addComponent(temp, this.cloneMethods[comp](entity.components[comp]));
}
}
for(let i = 0; i < entity.childElementCount; i++) {
temp.appendChild(this.clone(entity.children[i] as Entity));
}
return temp;
}
static find(selector:string, root:any = document) {
let nodes = Array.from(root.querySelectorAll(selector)); // convert NodeList to Array
return nodes as Entity[];
}
static getComponents(componentName: string, root: any = document) {
return this.find(`${this.entityTag}[${componentName.toLowerCase()}]`, root).map(({components}) => components[componentName]) as T[];
}
static getEntites(deps: string[], root:any = document) {
return this.find(`${this.entityTag}[${deps.join('][')}]`, root);
}
static addComponent(entity: Entity, component: any) {
this.hasNewMember = true;
let componentName = component.constructor.name;
entity.components[componentName] = component;
entity.setAttribute(componentName, '');
component.entity = entity;
return component;
}
}