import { IEntity , TTag } from "./entity.spec" ; import { TObjectProto , TTypeProto } from "./_.spec" ; import { registerEntity } from "./ecs" ; export * from './entity.spec' ; export class Entity implements IEntity { static uuidFn ? : ( ) => string ; protected components : Map < TObjectProto , Object > = new Map ( ) ; protected tags : Set < TTag > = new Set ( ) ; constructor ( protected uuid ? ) { if ( uuid ) { registerEntity ( this ) ; } } get id ( ) { if ( ! this . uuid && Entity . uuidFn ) { this . uuid = Entity . uuidFn ( ) ; registerEntity ( this ) ; } return this . uuid ; } addComponent ( component ) { const obj = this . asObject ( component ) ; if ( this . hasComponent ( obj . constructor as typeof Object ) ) { throw new Error ( `Component "${ obj . constructor . name }" already exists on entity!` ) ; } this . components . set ( obj . constructor as TObjectProto , obj ) ; return this ; } addTag ( tag ) { this . tags . add ( tag ) ; return this ; } protected asObject ( component , ... args ) { return typeof component === 'object' ? component : new ( component . prototype . constructor . bind ( component , ... Array . from ( arguments ) . slice ( 1 ) ) ) ( ) ; } getComponent < T extends Object > ( component ) { return this . components . get ( component ) as T ; } getComponents ( ) { return this . components . values ( ) ; } protected getConstructor ( component ) { return typeof component === 'object' ? component . constructor as TObjectProto : component ; } getTags ( ) { return this . tags . values ( ) ; } hasComponent ( component ) { return this . components . has ( component ) ; } hasTag ( tag ) { return this . tags . has ( tag ) ; } removeComponent ( component ) { this . components . delete ( this . getConstructor ( component ) ) ; return this ; } removeTag ( tag ) { this . tags . delete ( tag ) ; return this ; } }