ecsjs 1.0.0-beta.7 → 1.0.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ecs.js CHANGED
@@ -1,2 +1,2 @@
1
- var a=class extends Map{constructor(e=[]){super(e)}firstEntry(){return this.size===0?void 0:this.entries().next().value}firstKey(){return this.size===0?void 0:this.keys().next().value}firstValue(){return this.size===0?void 0:this.values().next().value}toJSON(){return{__KeyMap__:1,iterable:[...this.entries()]}}toTable(e=!1){let t=[];for(let[n,o]of this.entries()){let s=o,r={};e==!1&&(r["entity.key"]=n),r["entity.type"]=s.constructor.name,t.push({...r,...s})}return t}printTable(e=!1){console.table(this.toTable(e))}entries(){return super.entries().filter(e=>e!=null)}keys(){return super.keys().filter(e=>e!=null)}values(){return super.values().filter(e=>e!=null)}static get[Symbol.species](){return Map}};var p=class i{componentMaps=new a;nextId=0;constructor(){}register(...e){for(let t of e){let n=t.name;if(n===void 0)throw new ReferenceError("The component class does not have a name defined. i.e. a constructor name");let o=new a;this.componentMaps.set(n,o)}return this}getMap(e){return this.componentMaps.get(e.name)}firstEntry(e){return this.getMap(e)?.firstEntry()}firstKey(e){return this.getMap(e)?.firstKey()}firstValue(e){return this.getMap(e)?.firstValue()}get(e,t){let n=this.componentMaps.get(t.name);if(n===void 0)throw new ReferenceError(`"${t}" component class does not exist in the componentMaps`);return n.get(e)}getValues(e,...t){return t.map(n=>this.get(e,n))}getByKey(e,t){let n=this.componentMaps.get(t);if(n===void 0)throw new ReferenceError(`"${t}" component does not exist in the componentMaps`);return n.get(e)}has(e,t){let n=this.componentMaps.get(t.name);return n===void 0?!1:n.has(e)}set(e,t){let n=this.componentMaps.get(t.constructor.name);if(n===void 0)throw new ReferenceError(`Component map does not exist using the name: ${t.constructor.name}`);return n.set(e,t),t}setValues(e,...t){return t.map(n=>this.set(e,n))}remove(e,t){return this.removeByKey(e,t.name)}removeByKey(e,t){let n=this.componentMaps.get(t);if(n===void 0)throw new ReferenceError(`A registered entity map does not exist for the given key: ${t}`);return n.get(e)===void 0?!1:n.delete(e)}destroyEntity(e){this.componentMaps.forEach(t=>{t.has(e)&&t.delete(e)})}getNextId(){return this.nextId++,this.nextId}clear(){return this.componentMaps.clear(),this}printTable(){return this.componentMaps.forEach(e=>console.table(e.toTable(!0))),this}printEntity(e){for(let t of this.componentMaps.values()){if(t.has(e)===!1)continue;let n=t.get(e),o={name:n.constructor.name,...n};console.table({[e]:o})}return this}static parse(e){let t=new i,n=JSON.parse(e,function(o,s){return s.hasOwnProperty("componentMaps")?(Reflect.setPrototypeOf(s,i.prototype),s):s.hasOwnProperty("__KeyMap__")?new a(s.iterable):this[o]});return t.componentMaps=n.componentMaps,t.nextId=n.nextId,t}static createWithTracing(e){let t={get(n,o){let s=n[o];return typeof s=="function"&&(e.length===0||e.includes(o))?function(...r){return console.groupCollapsed("ecs trace",o,r),console.trace(),console.groupEnd(),s.apply(this,r)}:s}};return new Proxy(new i,t)}};var u=new p;typeof window<"u"?window.ecs=u:typeof module<"u"&&module!==null&&(module.exports={ecs:u});export{u as ecs};
1
+ var a=class extends Map{constructor(e=[]){super(e)}firstEntry(){return this.size===0?void 0:this.entries().next().value}firstKey(){return this.size===0?void 0:this.keys().next().value}firstValue(){return this.size===0?void 0:this.values().next().value}toJSON(){return{__KeyMap__:1,iterable:[...this.entries()]}}toTable(e=!1){let t=[];for(let[n,r]of this.entries()){let s=r,o={};e==!1&&(o["entity.key"]=n),o["entity.type"]=s.constructor.name,t.push({...o,...s})}return t}printTable(e=!1){console.table(this.toTable(e))}entries(){return super.entries().filter(e=>e!=null)}keys(){return super.keys().filter(e=>e!=null)}values(){return super.values().filter(e=>e!=null)}static get[Symbol.species](){return Map}};var p=class i{componentMaps=new a;nextId=0;constructor(){}register(...e){for(let t of e){let n=t.name;if(n===void 0)throw new ReferenceError("The component class does not have a name defined. i.e. a constructor name");let r=new a;this.componentMaps.set(n,r)}return this}getMap(e){return this.componentMaps.get(e.name)}firstEntry(e){return this.getMap(e)?.firstEntry()}firstKey(e){return this.getMap(e)?.firstKey()}firstValue(e){return this.getMap(e)?.firstValue()}get(e,t){let n=this.componentMaps.get(t.name);if(n===void 0)throw new ReferenceError(`"${t}" component class does not exist in the componentMaps`);return n.get(e)}getValues(e,...t){return t.map(n=>this.get(e,n))}getByKey(e,t){let n=this.componentMaps.get(t);if(n===void 0)throw new ReferenceError(`"${t}" component does not exist in the componentMaps`);return n.get(e)}has(e,t){let n=this.componentMaps.get(t.name);return n===void 0?!1:n.has(e)}set(e,t){let n=this.componentMaps.get(t.constructor.name);if(n===void 0)throw new ReferenceError(`Component map does not exist using the name: ${t.constructor.name}`);return n.set(e,t),t}setValues(e,...t){return t.map(n=>this.set(e,n))}remove(e,...t){for(let n of t)this.removeByKey(e,n.name)}removeByKey(e,t){let n=this.componentMaps.get(t);if(n===void 0)throw new ReferenceError(`A registered entity map does not exist for the given key: ${t}`);return n.get(e)===void 0?!1:n.delete(e)}destroyEntity(e){for(let t of this.componentMaps.values())t.has(e)&&t.delete(e)}getNextId(){return this.nextId++,this.nextId}clear(){return this.componentMaps.clear(),this}printTable(){return this.componentMaps.forEach(e=>console.table(e.toTable(!0))),this}printEntity(e){for(let t of this.componentMaps.values()){if(t.has(e)===!1)continue;let n=t.get(e),r={name:n.constructor.name,...n};console.table({[e]:r})}return this}static parse(e){let t=new i,n=JSON.parse(e,function(r,s){return s.hasOwnProperty("componentMaps")?(Reflect.setPrototypeOf(s,i.prototype),s):s.hasOwnProperty("__KeyMap__")?new a(s.iterable):this[r]});return t.componentMaps=n.componentMaps,t.nextId=n.nextId,t}static createWithTracing(e){let t={get(n,r){let s=n[r];return typeof s=="function"&&(e.length===0||e.includes(r))?function(...o){return console.groupCollapsed("ecs trace",r,o),console.trace(),console.groupEnd(),s.apply(this,o)}:s}};return new Proxy(new i,t)}};var u=new p;typeof window<"u"?window.ecs=u:typeof module<"u"&&module!==null&&(module.exports={ecs:u});export{u as ecs};
2
2
  //# sourceMappingURL=ecs.js.map
package/dist/ecs.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/key-map.ts", "../src/entity-map.ts", "../src/ecs.ts"],
4
- "sourcesContent": ["/*\n ecsjs is an entity component system library for JavaScript\n Copyright (C) 2014 Peter Flannery\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as\n published by the Free Software Foundation, either version 3 of the\n License, or (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport type { KeyCollection } from './definitions.js';\n\n/**\n * Class for storing keys and values\n */\nexport class KeyMap<TKey, TValue> extends Map<TKey, TValue> {\n\n constructor(entries: any[] = []) {\n super(entries)\n }\n\n firstEntry(): [key: TKey, value: TValue] | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.entries();\n const result = iterator.next();\n return result.value;\n }\n\n firstKey(): TKey | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.keys();\n const result = iterator.next();\n return result.value;\n }\n\n firstValue(): TValue | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.values();\n const result = iterator.next();\n return result.value;\n }\n\n toJSON() {\n return { __KeyMap__: 1, iterable: [...this.entries()] }\n }\n\n toTable(excludeKeys = false): any[] {\n const table = []\n for (const [key, value] of this.entries()) {\n const entity = value as { new(): TValue }\n const meta: KeyCollection<any> = {}\n if (excludeKeys == false) meta[\"entity.key\"] = key\n meta[\"entity.type\"] = entity.constructor.name\n table.push({ ...meta, ...entity })\n }\n return table\n }\n\n /**\n * Outputs keys and values in a tabular format to the console\n */\n printTable(excludeKeys = false): void {\n console.table(this.toTable(excludeKeys))\n }\n\n entries(): MapIterator<[TKey, TValue]> {\n return super.entries().filter(x => x !== undefined && x !== null)\n }\n\n keys(): MapIterator<TKey> {\n return super.keys().filter(x => x !== undefined && x !== null)\n }\n\n values(): MapIterator<TValue> {\n return super.values().filter(x => x !== undefined && x !== null)\n }\n\n static get [Symbol.species]() { return Map; }\n\n}", "/*\n ecsjs is an entity component system library for JavaScript\n Copyright (C) 2014 Peter Flannery\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as\n published by the Free Software Foundation, either version 3 of the\n License, or (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n/**\n * @module ecsjs\n */\nimport {\n type ComponentClass,\n type ComponentDataMap,\n type ComponentMap,\n type IComponent\n} from './definitions.js';\nimport { KeyMap } from './key-map.js';\n\n/**\n * Class for storing entities and their relationships\n * \n * @class EntityMap\n */\nexport class EntityMap {\n\n // entity class maps\n private componentMaps: ComponentMap = new KeyMap()\n\n private nextId: number = 0\n\n constructor() { }\n\n /**\n * Registers a component class\n * \n * @example\n *\n * ```javascript\n * // component class\n * class MyComponent {\n * constructor(x) {\n * this.x = x;\n * }\n * }\n *\n * ecs.register(MyComponent);\n * // or\n * ecs.register(MyComponent1, MyComponent2);\n * ```\n */\n register(...component: ComponentClass<any>[]) {\n for (const definition of component) {\n const componentName = definition.name;\n if (componentName === undefined)\n throw new ReferenceError(\"The component class does not have a name defined. i.e. a constructor name\");\n\n // create the component map\n const componentDataMap: ComponentDataMap<any> = new KeyMap();\n this.componentMaps.set(componentName, componentDataMap);\n }\n\n // chain\n return this;\n }\n\n /**\n * Retrieves an entity map by it's registered type\n */\n getMap<T extends IComponent>(component: ComponentClass<T>): ComponentDataMap<T> | undefined {\n return this.componentMaps.get(component.name);\n }\n\n /**\n * Get the first entity entry for a component class\n * \n * @example\n *\n * ```javascript\n * const [entityId, player] = ecs.firstEntry(PlayerComponent) ?? [];\n * ```\n */\n firstEntry<T extends IComponent>(component: ComponentClass<T>) {\n return this.getMap(component)?.firstEntry();\n }\n\n /**\n * Get the first entity id for a component class\n * \n * @example\n *\n * ```javascript\n * const entityId = ecs.firstKey(PlayerComponent);\n * ```\n */\n firstKey<T extends IComponent>(component: ComponentClass<T>) {\n return this.getMap(component)?.firstKey();\n }\n\n /**\n * Get the first entity component value for a component class\n * \n * @example\n *\n * ```javascript\n * const player = ecs.firstValue(PlayerComponent);\n * ```\n */\n firstValue<T extends IComponent>(component: ComponentClass<T>) {\n return this.getMap(component)?.firstValue();\n }\n\n /**\n * Retrieves an entity from its registered entity map\n *\n * @example\n *\n * ```javascript\n * // get an entity\n * let positionData = ecs.get(entityId, Components.PositionComponent);\n * ```\n */\n get<T extends IComponent>(entityId: number, component: ComponentClass<T>): T {\n let cm = this.componentMaps.get(component.name);\n if (cm === undefined)\n throw new ReferenceError(`\"${component}\" component class does not exist in the componentMaps`);\n\n return cm.get(entityId);\n }\n\n /**\n * Get multiple component values related to an entity\n * \n * @param entityId\n * @param components: ComponentClass<any>[]\n * \n * @example\n *\n * ```javascript\n * // get an entity\n * const [player, position] = ecs.getValues(entityId, PlayerComponent, PositionComponent);\n * ```\n */\n getValues<\n T1 extends IComponent,\n T2 extends IComponent,\n T3 extends IComponent,\n T4 extends IComponent,\n T5 extends IComponent\n >(\n entityId: number,\n a: ComponentClass<T1>,\n b: ComponentClass<T2>,\n c?: ComponentClass<T3>,\n d?: ComponentClass<T4>,\n e?: ComponentClass<T5>\n ): [T1, T2, T3, T4, T5];\n getValues(entityId: number, ...components: ComponentClass<any>[]): IComponent[] {\n return components.map(x => this.get(entityId, x))\n }\n\n /**\n * Retrieves an entity from its registered entity map\n *\n * @example\n *\n * ```javascript\n * // get an entity\n * let positionData = ecs.getByKey(entityId, \"PositionComponent\");\n * ```\n */\n getByKey(entityId: number, componentName: string) {\n // get the component map\n let map = this.componentMaps.get(componentName);\n if (map === undefined)\n throw new ReferenceError(`\"${componentName}\" component does not exist in the componentMaps`);\n\n return map.get(entityId);\n }\n\n /**\n * Checks if the entity exists in it's registed component map\n * The entity type must be registered before calling this method\n * \n * @example\n *\n * ```javascript\n * // get an entity\n * let exists = ecs.has(entityId, PositionComponent);\n * ```\n */\n has<T extends IComponent>(entityId: number, component: ComponentClass<T>): boolean {\n // get the component map\n let map = this.componentMaps.get(component.name);\n if (map === undefined) return false\n\n return map.has(entityId);\n }\n\n /**\n * Adds or updates an entity to it's registered entity map\n *\n * @example\n *\n * ```javascript\n * // add/update an entity\n * let playerPos = ecs.set(entityId, new Components.PositionComponent(0, 0));\n * ```\n */\n set<T extends IComponent>(entityId: number, componentData: T): T {\n // get the component map\n let map = this.componentMaps.get(componentData.constructor.name);\n if (map === undefined)\n throw new ReferenceError(\n `Component map does not exist using the name: ${componentData.constructor.name}`\n );\n\n // set the entity on the entity map\n map.set(entityId, componentData);\n\n // return instance\n return componentData;\n }\n\n /**\n * Set multiple component values for an entity\n * \n * @param entityId\n * @param components: ComponentClass<any>[]\n * \n * @example\n *\n * ```javascript\n * // write the component values to the entity\n * ecs.setValues(entityId, new PlayerComponent(), new PositionComponent());\n * ```\n */\n setValues<\n T1 extends IComponent,\n T2 extends IComponent,\n T3 extends IComponent,\n T4 extends IComponent,\n T5 extends IComponent\n >(\n entityId: number,\n a: T1,\n b: T2,\n c?: T3,\n d?: T4,\n e?: T5\n ): [T1, T2, T3, T4, T5];\n setValues(entityId: number, ...components: IComponent[]): IComponent[] {\n return components.map(x => this.set(entityId, x))\n }\n\n /**\n * Removes an entity from its entity map.\n * Removes any related Node entities that are mapped to the entity\n * \n * @example\n *\n * ```javascript\n * // remove an entity from its entity map\n * EntityMap.remove(entityId, Components.PositionComponent);\n * ```\n */\n remove<T extends IComponent>(entityId: number, component: ComponentClass<T>) {\n return this.removeByKey(entityId, component.name);\n }\n\n /**\n * Removes an entity from its entity map.\n * Removes any related Node entities that are mapped to the entity\n * \n * @example\n *\n * ```javascript\n * // remove an entity from its entity map\n * EntityMap.removeByKey(entityId, \"PositionComponent\");\n * ```\n */\n removeByKey(entityId: number, componentName: string) {\n // get the entity map\n let entityMap = this.componentMaps.get(componentName);\n\n // ensure the map is defined\n if (entityMap === undefined)\n throw new ReferenceError(`A registered entity map does not exist for the given key: ${componentName}`);\n\n // get the entity\n let entity = entityMap.get(entityId);\n if (entity === undefined) return false;\n\n // remove the entity from the entity map\n return entityMap.delete(entityId);\n }\n\n /**\n * Destroys an entity across all component maps\n */\n destroyEntity(entityId: number) {\n this.componentMaps.forEach((dataMap: ComponentDataMap<any>) => {\n if (dataMap.has(entityId)) dataMap.delete(entityId);\n });\n }\n\n // TODO generate a non repeatable id for network play?\n getNextId() {\n this.nextId++;\n return this.nextId;\n }\n\n clear() {\n this.componentMaps.clear();\n return this;\n }\n\n /**\n * Prints all component maps in a tabular format to the console\n */\n printTable() {\n this.componentMaps.forEach(map => console.table(map.toTable(true)));\n return this;\n }\n\n /**\n * Prints an entity component data in tabular format to the console\n */\n printEntity(entityId: number) {\n for (const map of this.componentMaps.values()) {\n if (map.has(entityId) === false) continue;\n\n const data = map.get(entityId);\n const columns = {\n name: data.constructor.name,\n ...data\n };\n console.table({ [entityId]: columns });\n }\n\n return this;\n }\n\n /**\n * Parse's the JSON and returns an EntityMap object\n * \n * @example\n *\n * ```javascript\n * // remove an entity from its entity map\n * const json = JSON.stringfy(ecs);\n * const restoredMap = EntityMap.parse(json);\n * ```\n */\n static parse(json: string) {\n const ecs = new EntityMap();\n\n const restored = JSON.parse(json, function (key: string, value: any) {\n\n if (value.hasOwnProperty('componentMaps')) {\n Reflect.setPrototypeOf(value, EntityMap.prototype);\n return value;\n }\n\n if (value.hasOwnProperty('__KeyMap__')) {\n return new KeyMap(value.iterable);\n }\n\n return this[key];\n });\n\n ecs.componentMaps = restored.componentMaps;\n ecs.nextId = restored.nextId;\n return ecs;\n }\n\n /**\n * A tracing method used for debugging.\n * Intercepts all functions specified and logs each call to the console.\n * \n * @method createWithTracing\n * @static\n * @param {Array} funcFilter A list of function names you want to intercept. If no function names are specified then will log all functions called\n * @return {EntityMap} A new entity map with tracing enabled\n */\n static createWithTracing(funcFilter: any) {\n let traceHandler = {\n get(target: any, propKey: string) {\n const targetValue = target[propKey]\n\n if (typeof targetValue === 'function' && (funcFilter.length === 0 || funcFilter.includes(propKey))) {\n return function (this: any, ...args: any[]) {\n console.groupCollapsed('ecs trace', propKey, args);\n console.trace();\n console.groupEnd();\n return targetValue.apply(this, args);\n }\n }\n\n return targetValue;\n }\n }\n\n return new Proxy(new EntityMap(), traceHandler)\n }\n\n}", "/*\n ecsjs is an entity component system library for JavaScript\n Copyright (C) 2014 Peter Flannery\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as\n published by the Free Software Foundation, either version 3 of the\n License, or (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n/**\n * ### An entity component system library for JavaScript\n *\n * @module ecsjs\n * @main ecsjs\n */\nimport { EntityMap } from './entity-map.js'\n\nexport const ecs = new EntityMap()\n\nif (typeof window !== 'undefined') {\n // @ts-ignore: exports to window\n window.ecs = ecs\n} else if (typeof module !== 'undefined' && module !== null) {\n // exports to nodejs\n module.exports = { ecs };\n}"],
5
- "mappings": "AAsBO,IAAMA,EAAN,cAAmC,GAAkB,CAE1D,YAAYC,EAAiB,CAAC,EAAG,CAC/B,MAAMA,CAAO,CACf,CAEA,YAAqD,CACnD,OAAI,KAAK,OAAS,EAAG,OAEJ,KAAK,QAAQ,EACN,KAAK,EACf,KAChB,CAEA,UAA6B,CAC3B,OAAI,KAAK,OAAS,EAAG,OAEJ,KAAK,KAAK,EACH,KAAK,EACf,KAChB,CAEA,YAAiC,CAC/B,OAAI,KAAK,OAAS,EAAG,OAEJ,KAAK,OAAO,EACL,KAAK,EACf,KAChB,CAEA,QAAS,CACP,MAAO,CAAE,WAAY,EAAG,SAAU,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAE,CACxD,CAEA,QAAQC,EAAc,GAAc,CAClC,IAAMC,EAAQ,CAAC,EACf,OAAW,CAACC,EAAKC,CAAK,IAAK,KAAK,QAAQ,EAAG,CACzC,IAAMC,EAASD,EACTE,EAA2B,CAAC,EAC9BL,GAAe,KAAOK,EAAK,YAAY,EAAIH,GAC/CG,EAAK,aAAa,EAAID,EAAO,YAAY,KACzCH,EAAM,KAAK,CAAE,GAAGI,EAAM,GAAGD,CAAO,CAAC,CACnC,CACA,OAAOH,CACT,CAKA,WAAWD,EAAc,GAAa,CACpC,QAAQ,MAAM,KAAK,QAAQA,CAAW,CAAC,CACzC,CAEA,SAAuC,CACrC,OAAO,MAAM,QAAQ,EAAE,OAAOM,GAAwBA,GAAM,IAAI,CAClE,CAEA,MAA0B,CACxB,OAAO,MAAM,KAAK,EAAE,OAAOA,GAAwBA,GAAM,IAAI,CAC/D,CAEA,QAA8B,CAC5B,OAAO,MAAM,OAAO,EAAE,OAAOA,GAAwBA,GAAM,IAAI,CACjE,CAEA,WAAY,OAAO,OAAO,GAAI,CAAE,OAAO,GAAK,CAE9C,ECvDO,IAAMC,EAAN,MAAMC,CAAU,CAGb,cAA8B,IAAIC,EAElC,OAAiB,EAEzB,aAAc,CAAE,CAoBhB,YAAYC,EAAkC,CAC5C,QAAWC,KAAcD,EAAW,CAClC,IAAME,EAAgBD,EAAW,KACjC,GAAIC,IAAkB,OACpB,MAAM,IAAI,eAAe,2EAA2E,EAGtG,IAAMC,EAA0C,IAAIJ,EACpD,KAAK,cAAc,IAAIG,EAAeC,CAAgB,CACxD,CAGA,OAAO,IACT,CAKA,OAA6BH,EAA+D,CAC1F,OAAO,KAAK,cAAc,IAAIA,EAAU,IAAI,CAC9C,CAWA,WAAiCA,EAA8B,CAC7D,OAAO,KAAK,OAAOA,CAAS,GAAG,WAAW,CAC5C,CAWA,SAA+BA,EAA8B,CAC3D,OAAO,KAAK,OAAOA,CAAS,GAAG,SAAS,CAC1C,CAWA,WAAiCA,EAA8B,CAC7D,OAAO,KAAK,OAAOA,CAAS,GAAG,WAAW,CAC5C,CAYA,IAA0BI,EAAkBJ,EAAiC,CAC3E,IAAIK,EAAK,KAAK,cAAc,IAAIL,EAAU,IAAI,EAC9C,GAAIK,IAAO,OACT,MAAM,IAAI,eAAe,IAAIL,CAAS,uDAAuD,EAE/F,OAAOK,EAAG,IAAID,CAAQ,CACxB,CA6BA,UAAUA,KAAqBE,EAAiD,CAC9E,OAAOA,EAAW,IAAIC,GAAK,KAAK,IAAIH,EAAUG,CAAC,CAAC,CAClD,CAYA,SAASH,EAAkBF,EAAuB,CAEhD,IAAIM,EAAM,KAAK,cAAc,IAAIN,CAAa,EAC9C,GAAIM,IAAQ,OACV,MAAM,IAAI,eAAe,IAAIN,CAAa,iDAAiD,EAE7F,OAAOM,EAAI,IAAIJ,CAAQ,CACzB,CAaA,IAA0BA,EAAkBJ,EAAuC,CAEjF,IAAIQ,EAAM,KAAK,cAAc,IAAIR,EAAU,IAAI,EAC/C,OAAIQ,IAAQ,OAAkB,GAEvBA,EAAI,IAAIJ,CAAQ,CACzB,CAYA,IAA0BA,EAAkBK,EAAqB,CAE/D,IAAID,EAAM,KAAK,cAAc,IAAIC,EAAc,YAAY,IAAI,EAC/D,GAAID,IAAQ,OACV,MAAM,IAAI,eACR,gDAAgDC,EAAc,YAAY,IAAI,EAChF,EAGF,OAAAD,EAAI,IAAIJ,EAAUK,CAAa,EAGxBA,CACT,CA6BA,UAAUL,KAAqBE,EAAwC,CACrE,OAAOA,EAAW,IAAIC,GAAK,KAAK,IAAIH,EAAUG,CAAC,CAAC,CAClD,CAaA,OAA6BH,EAAkBJ,EAA8B,CAC3E,OAAO,KAAK,YAAYI,EAAUJ,EAAU,IAAI,CAClD,CAaA,YAAYI,EAAkBF,EAAuB,CAEnD,IAAIQ,EAAY,KAAK,cAAc,IAAIR,CAAa,EAGpD,GAAIQ,IAAc,OAChB,MAAM,IAAI,eAAe,6DAA6DR,CAAa,EAAE,EAIvG,OADaQ,EAAU,IAAIN,CAAQ,IACpB,OAAkB,GAG1BM,EAAU,OAAON,CAAQ,CAClC,CAKA,cAAcA,EAAkB,CAC9B,KAAK,cAAc,QAASO,GAAmC,CACzDA,EAAQ,IAAIP,CAAQ,GAAGO,EAAQ,OAAOP,CAAQ,CACpD,CAAC,CACH,CAGA,WAAY,CACV,YAAK,SACE,KAAK,MACd,CAEA,OAAQ,CACN,YAAK,cAAc,MAAM,EAClB,IACT,CAKA,YAAa,CACX,YAAK,cAAc,QAAQI,GAAO,QAAQ,MAAMA,EAAI,QAAQ,EAAI,CAAC,CAAC,EAC3D,IACT,CAKA,YAAYJ,EAAkB,CAC5B,QAAWI,KAAO,KAAK,cAAc,OAAO,EAAG,CAC7C,GAAIA,EAAI,IAAIJ,CAAQ,IAAM,GAAO,SAEjC,IAAMQ,EAAOJ,EAAI,IAAIJ,CAAQ,EACvBS,EAAU,CACd,KAAMD,EAAK,YAAY,KACvB,GAAGA,CACL,EACA,QAAQ,MAAM,CAAE,CAACR,CAAQ,EAAGS,CAAQ,CAAC,CACvC,CAEA,OAAO,IACT,CAaA,OAAO,MAAMC,EAAc,CACzB,IAAMC,EAAM,IAAIjB,EAEVkB,EAAW,KAAK,MAAMF,EAAM,SAAUG,EAAaC,EAAY,CAEnE,OAAIA,EAAM,eAAe,eAAe,GACtC,QAAQ,eAAeA,EAAOpB,EAAU,SAAS,EAC1CoB,GAGLA,EAAM,eAAe,YAAY,EAC5B,IAAInB,EAAOmB,EAAM,QAAQ,EAG3B,KAAKD,CAAG,CACjB,CAAC,EAED,OAAAF,EAAI,cAAgBC,EAAS,cAC7BD,EAAI,OAASC,EAAS,OACfD,CACT,CAWA,OAAO,kBAAkBI,EAAiB,CACxC,IAAIC,EAAe,CACjB,IAAIC,EAAaC,EAAiB,CAChC,IAAMC,EAAcF,EAAOC,CAAO,EAElC,OAAI,OAAOC,GAAgB,aAAeJ,EAAW,SAAW,GAAKA,EAAW,SAASG,CAAO,GACvF,YAAwBE,EAAa,CAC1C,eAAQ,eAAe,YAAaF,EAASE,CAAI,EACjD,QAAQ,MAAM,EACd,QAAQ,SAAS,EACVD,EAAY,MAAM,KAAMC,CAAI,CACrC,EAGKD,CACT,CACF,EAEA,OAAO,IAAI,MAAM,IAAIzB,EAAasB,CAAY,CAChD,CAEF,ECtYO,IAAMK,EAAM,IAAIC,EAEnB,OAAO,OAAW,IAEpB,OAAO,IAAMD,EACJ,OAAO,OAAW,KAAe,SAAW,OAErD,OAAO,QAAU,CAAE,IAAAA,CAAI",
6
- "names": ["KeyMap", "entries", "excludeKeys", "table", "key", "value", "entity", "meta", "x", "EntityMap", "_EntityMap", "KeyMap", "component", "definition", "componentName", "componentDataMap", "entityId", "cm", "components", "x", "map", "componentData", "entityMap", "dataMap", "data", "columns", "json", "ecs", "restored", "key", "value", "funcFilter", "traceHandler", "target", "propKey", "targetValue", "args", "ecs", "EntityMap"]
4
+ "sourcesContent": ["/*\n ecsjs is an entity component system library for JavaScript\n Copyright (C) 2014 Peter Flannery\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as\n published by the Free Software Foundation, either version 3 of the\n License, or (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport type { KeyCollection } from './definitions.js';\n\n/**\n * Class for storing keys and values\n */\nexport class KeyMap<TKey, TValue> extends Map<TKey, TValue> {\n\n constructor(entries: any[] = []) {\n super(entries)\n }\n\n firstEntry(): [key: TKey, value: TValue] | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.entries();\n const result = iterator.next();\n return result.value;\n }\n\n firstKey(): TKey | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.keys();\n const result = iterator.next();\n return result.value;\n }\n\n firstValue(): TValue | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.values();\n const result = iterator.next();\n return result.value;\n }\n\n toJSON() {\n return { __KeyMap__: 1, iterable: [...this.entries()] }\n }\n\n toTable(excludeKeys = false): any[] {\n const table = []\n for (const [key, value] of this.entries()) {\n const entity = value as { new(): TValue }\n const meta: KeyCollection<any> = {}\n if (excludeKeys == false) meta[\"entity.key\"] = key\n meta[\"entity.type\"] = entity.constructor.name\n table.push({ ...meta, ...entity })\n }\n return table\n }\n\n /**\n * Outputs keys and values in a tabular format to the console\n */\n printTable(excludeKeys = false): void {\n console.table(this.toTable(excludeKeys))\n }\n\n entries(): MapIterator<[TKey, TValue]> {\n return super.entries().filter(x => x !== undefined && x !== null)\n }\n\n keys(): MapIterator<TKey> {\n return super.keys().filter(x => x !== undefined && x !== null)\n }\n\n values(): MapIterator<TValue> {\n return super.values().filter(x => x !== undefined && x !== null)\n }\n\n static get [Symbol.species]() { return Map; }\n\n}", "/*\n ecsjs is an entity component system library for JavaScript\n Copyright (C) 2014 Peter Flannery\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as\n published by the Free Software Foundation, either version 3 of the\n License, or (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n/**\n * @module ecsjs\n */\nimport {\n type ComponentClass,\n type ComponentDataMap,\n type ComponentInstances,\n type ComponentMap,\n type IComponent\n} from './definitions.js';\nimport { KeyMap } from './key-map.js';\n\n/**\n * Class for storing entities and their relationships\n * \n * @class EntityMap\n */\nexport class EntityMap {\n\n // entity class maps\n private componentMaps: ComponentMap = new KeyMap()\n\n private nextId: number = 0\n\n constructor() { }\n\n /**\n * Registers component classes\n * \n * @example\n * // component class\n * class MyComponent {\n * constructor(x) {\n * this.x = x;\n * }\n * }\n *\n * ecs.register(MyComponent);\n * // or\n * ecs.register(MyComponent1, MyComponent2);\n */\n register<TArgs extends ComponentClass<any>[]>(...componentClasses: TArgs) {\n for (const componentClass of componentClasses) {\n const componentName = componentClass.name;\n if (componentName === undefined)\n throw new ReferenceError(\"The component class does not have a name defined. i.e. a constructor name\");\n\n // create the component map\n const componentDataMap: ComponentDataMap<any> = new KeyMap();\n this.componentMaps.set(componentName, componentDataMap);\n }\n\n // chain\n return this;\n }\n\n /**\n * Get a component class map\n */\n getMap<T>(component: ComponentClass<T>): ComponentDataMap<T> | undefined {\n return this.componentMaps.get(component.name);\n }\n\n /**\n * Get the first entity entry for a component class\n * \n * @example\n * const [entityId, player] = ecs.firstEntry(PlayerComponent) ?? [];\n */\n firstEntry<T>(component: ComponentClass<T>) {\n return this.getMap(component)?.firstEntry();\n }\n\n /**\n * Get the first entity id for a component class\n * \n * @example\n * const entityId = ecs.firstKey(PlayerComponent);\n */\n firstKey<T>(component: ComponentClass<T>) {\n return this.getMap(component)?.firstKey();\n }\n\n /**\n * Get the first entity component value for a component class\n * \n * @example\n * const player = ecs.firstValue(PlayerComponent);\n */\n firstValue<T>(component: ComponentClass<T>) {\n return this.getMap(component)?.firstValue();\n }\n\n /**\n * Get a component related to an entity\n *\n * @example\n * const position = ecs.get(entityId, Components.PositionComponent);\n */\n get<T>(entityId: number, component: ComponentClass<T>): T {\n const map = this.componentMaps.get(component.name);\n if (map === undefined)\n throw new ReferenceError(`\"${component}\" component class does not exist in the componentMaps`);\n\n return map.get(entityId);\n }\n\n /**\n * Get multiple component values related to an entity\n * \n * @param entityId\n * @param components: ComponentClass<any>[]\n * \n * @example\n * const [player, position] = ecs.getValues(entityId, PlayerComponent, PositionComponent);\n */\n getValues<TArgs extends ComponentClass<any>[]>(\n entityId: number,\n ...components: TArgs\n ): ComponentInstances<TArgs> {\n return components.map(x => this.get(entityId, x)) as any\n }\n\n /**\n * Retrieves an entity from its registered entity map\n *\n * @example\n * const positionData = ecs.getByKey(entityId, \"PositionComponent\");\n */\n getByKey(entityId: number, componentName: string) {\n // get the component map\n const map = this.componentMaps.get(componentName);\n if (map === undefined)\n throw new ReferenceError(`\"${componentName}\" component does not exist in the componentMaps`);\n\n return map.get(entityId);\n }\n\n /**\n * Check if a component exists for an entity\n * \n * @example\n * const exists = ecs.has(entityId, PositionComponent);\n */\n has<T>(entityId: number, component: ComponentClass<T>): boolean {\n // get the component map\n const map = this.componentMaps.get(component.name);\n if (map === undefined) return false\n\n return map.has(entityId);\n }\n\n /**\n * Add or update a component value for an entity\n *\n * @example\n * const position = ecs.set(entityId, new Components.PositionComponent(0, 0));\n */\n set<T extends IComponent>(entityId: number, componentData: T): T {\n // get the component map\n const map = this.componentMaps.get(componentData.constructor.name);\n if (map === undefined)\n throw new ReferenceError(\n `Component map does not exist using the name: ${componentData.constructor.name}`\n );\n\n // set the entity on the entity map\n map.set(entityId, componentData);\n\n // return instance\n return componentData;\n }\n\n /**\n * Add or update multiple component values for an entity\n * \n * @example\n * const [player, position] = ecs.setValues(entityId, new PlayerComponent(), new PositionComponent());\n */\n setValues<T extends IComponent[]>(entityId: number, ...components: T): T;\n setValues(entityId: number, ...components: IComponent[]): IComponent[] {\n return components.map(x => this.set(entityId, x))\n }\n\n /**\n * Removes the specified component(s) from an entity\n * \n * @example\n * ecs.remove(entityId, Components.PositionComponent);\n */\n remove<T extends ComponentClass<any>[]>(entityId: number, ...components: T) {\n for (const component of components) {\n this.removeByKey(entityId, component.name)\n }\n }\n\n /**\n * Removes the specified component from an entity\n * \n * @example\n * ecs.removeByKey(entityId, \"PositionComponent\");\n */\n removeByKey(entityId: number, componentName: string) {\n // get the entity map\n const entityMap = this.componentMaps.get(componentName);\n\n // ensure the map is defined\n if (entityMap === undefined)\n throw new ReferenceError(`A registered entity map does not exist for the given key: ${componentName}`);\n\n // get the entity\n const entity = entityMap.get(entityId);\n if (entity === undefined) return false;\n\n // remove the entity from the entity map\n return entityMap.delete(entityId);\n }\n\n /**\n * Deletes an entity from all component maps\n * \n * @example\n * ecs.destroyEntity(entityId);\n */\n destroyEntity(entityId: number) {\n for (const map of this.componentMaps.values()) {\n if (map.has(entityId)) map.delete(entityId);\n }\n }\n\n // TODO generate a non repeatable id for network play?\n getNextId() {\n this.nextId++;\n return this.nextId;\n }\n\n clear() {\n this.componentMaps.clear();\n return this;\n }\n\n /**\n * Prints all component maps in a tabular format to the console\n */\n printTable() {\n this.componentMaps.forEach(map => console.table(map.toTable(true)));\n return this;\n }\n\n /**\n * Prints an entity component data in tabular format to the console\n */\n printEntity(entityId: number) {\n for (const map of this.componentMaps.values()) {\n if (map.has(entityId) === false) continue;\n\n const data = map.get(entityId);\n const columns = {\n name: data.constructor.name,\n ...data\n };\n console.table({ [entityId]: columns });\n }\n\n return this;\n }\n\n /**\n * Parse's the JSON and returns an EntityMap object\n * \n * @example\n * const json = JSON.stringfy(ecs);\n * const restoredMap = ecs.parse(json);\n */\n static parse(json: string) {\n const ecs = new EntityMap();\n\n const restored = JSON.parse(json, function (key: string, value: any) {\n\n if (value.hasOwnProperty('componentMaps')) {\n Reflect.setPrototypeOf(value, EntityMap.prototype);\n return value;\n }\n\n if (value.hasOwnProperty('__KeyMap__')) {\n return new KeyMap(value.iterable);\n }\n\n return this[key];\n });\n\n ecs.componentMaps = restored.componentMaps;\n ecs.nextId = restored.nextId;\n return ecs;\n }\n\n /**\n * A tracing method used for debugging.\n * Intercepts all functions specified and logs each call to the console.\n * \n * @method createWithTracing\n * @static\n * @param {Array} funcFilter A list of function names you want to intercept. If no function names are specified then will log all functions called\n * @return {EntityMap} A new entity map with tracing enabled\n */\n static createWithTracing(funcFilter: any) {\n const traceHandler = {\n get(target: any, propKey: string) {\n const targetValue = target[propKey]\n\n if (typeof targetValue === 'function' && (funcFilter.length === 0 || funcFilter.includes(propKey))) {\n return function (this: any, ...args: any[]) {\n console.groupCollapsed('ecs trace', propKey, args);\n console.trace();\n console.groupEnd();\n return targetValue.apply(this, args);\n }\n }\n\n return targetValue;\n }\n }\n\n return new Proxy(new EntityMap(), traceHandler)\n }\n\n}", "/*\n ecsjs is an entity component system library for JavaScript\n Copyright (C) 2014 Peter Flannery\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as\n published by the Free Software Foundation, either version 3 of the\n License, or (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n/**\n * ### An entity component system library for JavaScript\n *\n * @module ecsjs\n * @main ecsjs\n */\nimport { EntityMap } from './entity-map.js'\n\nexport const ecs = new EntityMap()\n\nif (typeof window !== 'undefined') {\n // @ts-ignore: exports to window\n window.ecs = ecs\n} else if (typeof module !== 'undefined' && module !== null) {\n // exports to nodejs\n module.exports = { ecs };\n}"],
5
+ "mappings": "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",
6
+ "names": ["KeyMap", "entries", "excludeKeys", "table", "key", "value", "entity", "meta", "x", "EntityMap", "_EntityMap", "KeyMap", "componentClasses", "componentClass", "componentName", "componentDataMap", "component", "entityId", "map", "components", "x", "componentData", "entityMap", "data", "columns", "json", "ecs", "restored", "key", "value", "funcFilter", "traceHandler", "target", "propKey", "targetValue", "args", "ecs", "EntityMap"]
7
7
  }
@@ -4,8 +4,9 @@ export type KeyCollection<T> = {
4
4
  };
5
5
  export interface IComponent {
6
6
  }
7
- export type ComponentClass<T extends IComponent> = {
8
- new (...args: any[]): T;
7
+ export type ComponentClass<TInstance> = new (...args: any[]) => TInstance;
8
+ export type ComponentInstances<TClasses> = {
9
+ [Index in keyof TClasses]: TClasses[Index] extends ComponentClass<infer U> ? U : never;
9
10
  };
10
11
  export type ComponentDataMap<T> = KeyMap<number, T>;
11
12
  export type ComponentMap = KeyMap<string, ComponentDataMap<any>>;
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../../src/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAA;CAAE,CAAA;AAEnD,MAAM,WAAW,UAAU;CAAI;AAE/B,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,UAAU,IAAI;IACjD,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAEnD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../../src/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE1C,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAA;CAAE,CAAA;AAEnD,MAAM,WAAW,UAAU;CAAI;AAE/B,MAAM,MAAM,cAAc,CAAC,SAAS,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,SAAS,CAAA;AAEzE,MAAM,MAAM,kBAAkB,CAAC,QAAQ,IAAI;KACxC,KAAK,IAAI,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CACvF,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAEnD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAA"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @module ecsjs
3
3
  */
4
- import { type ComponentClass, type ComponentDataMap, type IComponent } from './definitions.js';
4
+ import { type ComponentClass, type ComponentDataMap, type ComponentInstances, type IComponent } from './definitions.js';
5
5
  /**
6
6
  * Class for storing entities and their relationships
7
7
  *
@@ -12,69 +12,53 @@ export declare class EntityMap {
12
12
  private nextId;
13
13
  constructor();
14
14
  /**
15
- * Registers a component class
15
+ * Registers component classes
16
16
  *
17
17
  * @example
18
+ * // component class
19
+ * class MyComponent {
20
+ * constructor(x) {
21
+ * this.x = x;
22
+ * }
23
+ * }
18
24
  *
19
- * ```javascript
20
- * // component class
21
- * class MyComponent {
22
- * constructor(x) {
23
- * this.x = x;
24
- * }
25
- * }
26
- *
27
- * ecs.register(MyComponent);
28
- * // or
29
- * ecs.register(MyComponent1, MyComponent2);
30
- * ```
25
+ * ecs.register(MyComponent);
26
+ * // or
27
+ * ecs.register(MyComponent1, MyComponent2);
31
28
  */
32
- register(...component: ComponentClass<any>[]): this;
29
+ register<TArgs extends ComponentClass<any>[]>(...componentClasses: TArgs): this;
33
30
  /**
34
- * Retrieves an entity map by it's registered type
31
+ * Get a component class map
35
32
  */
36
- getMap<T extends IComponent>(component: ComponentClass<T>): ComponentDataMap<T> | undefined;
33
+ getMap<T>(component: ComponentClass<T>): ComponentDataMap<T> | undefined;
37
34
  /**
38
35
  * Get the first entity entry for a component class
39
36
  *
40
37
  * @example
41
- *
42
- * ```javascript
43
- * const [entityId, player] = ecs.firstEntry(PlayerComponent) ?? [];
44
- * ```
38
+ * const [entityId, player] = ecs.firstEntry(PlayerComponent) ?? [];
45
39
  */
46
- firstEntry<T extends IComponent>(component: ComponentClass<T>): [key: number, value: T] | undefined;
40
+ firstEntry<T>(component: ComponentClass<T>): [key: number, value: T] | undefined;
47
41
  /**
48
42
  * Get the first entity id for a component class
49
43
  *
50
44
  * @example
51
- *
52
- * ```javascript
53
- * const entityId = ecs.firstKey(PlayerComponent);
54
- * ```
45
+ * const entityId = ecs.firstKey(PlayerComponent);
55
46
  */
56
- firstKey<T extends IComponent>(component: ComponentClass<T>): number | undefined;
47
+ firstKey<T>(component: ComponentClass<T>): number | undefined;
57
48
  /**
58
49
  * Get the first entity component value for a component class
59
50
  *
60
51
  * @example
61
- *
62
- * ```javascript
63
- * const player = ecs.firstValue(PlayerComponent);
64
- * ```
52
+ * const player = ecs.firstValue(PlayerComponent);
65
53
  */
66
- firstValue<T extends IComponent>(component: ComponentClass<T>): T | undefined;
54
+ firstValue<T>(component: ComponentClass<T>): T | undefined;
67
55
  /**
68
- * Retrieves an entity from its registered entity map
56
+ * Get a component related to an entity
69
57
  *
70
58
  * @example
71
- *
72
- * ```javascript
73
- * // get an entity
74
- * let positionData = ecs.get(entityId, Components.PositionComponent);
75
- * ```
59
+ * const position = ecs.get(entityId, Components.PositionComponent);
76
60
  */
77
- get<T extends IComponent>(entityId: number, component: ComponentClass<T>): T;
61
+ get<T>(entityId: number, component: ComponentClass<T>): T;
78
62
  /**
79
63
  * Get multiple component values related to an entity
80
64
  *
@@ -82,87 +66,56 @@ export declare class EntityMap {
82
66
  * @param components: ComponentClass<any>[]
83
67
  *
84
68
  * @example
85
- *
86
- * ```javascript
87
- * // get an entity
88
- * const [player, position] = ecs.getValues(entityId, PlayerComponent, PositionComponent);
89
- * ```
69
+ * const [player, position] = ecs.getValues(entityId, PlayerComponent, PositionComponent);
90
70
  */
91
- getValues<T1 extends IComponent, T2 extends IComponent, T3 extends IComponent, T4 extends IComponent, T5 extends IComponent>(entityId: number, a: ComponentClass<T1>, b: ComponentClass<T2>, c?: ComponentClass<T3>, d?: ComponentClass<T4>, e?: ComponentClass<T5>): [T1, T2, T3, T4, T5];
71
+ getValues<TArgs extends ComponentClass<any>[]>(entityId: number, ...components: TArgs): ComponentInstances<TArgs>;
92
72
  /**
93
73
  * Retrieves an entity from its registered entity map
94
74
  *
95
75
  * @example
96
- *
97
- * ```javascript
98
- * // get an entity
99
- * let positionData = ecs.getByKey(entityId, "PositionComponent");
100
- * ```
76
+ * const positionData = ecs.getByKey(entityId, "PositionComponent");
101
77
  */
102
78
  getByKey(entityId: number, componentName: string): any;
103
79
  /**
104
- * Checks if the entity exists in it's registed component map
105
- * The entity type must be registered before calling this method
80
+ * Check if a component exists for an entity
106
81
  *
107
82
  * @example
108
- *
109
- * ```javascript
110
- * // get an entity
111
- * let exists = ecs.has(entityId, PositionComponent);
112
- * ```
83
+ * const exists = ecs.has(entityId, PositionComponent);
113
84
  */
114
- has<T extends IComponent>(entityId: number, component: ComponentClass<T>): boolean;
85
+ has<T>(entityId: number, component: ComponentClass<T>): boolean;
115
86
  /**
116
- * Adds or updates an entity to it's registered entity map
87
+ * Add or update a component value for an entity
117
88
  *
118
89
  * @example
119
- *
120
- * ```javascript
121
- * // add/update an entity
122
- * let playerPos = ecs.set(entityId, new Components.PositionComponent(0, 0));
123
- * ```
90
+ * const position = ecs.set(entityId, new Components.PositionComponent(0, 0));
124
91
  */
125
92
  set<T extends IComponent>(entityId: number, componentData: T): T;
126
93
  /**
127
- * Set multiple component values for an entity
128
- *
129
- * @param entityId
130
- * @param components: ComponentClass<any>[]
94
+ * Add or update multiple component values for an entity
131
95
  *
132
96
  * @example
133
- *
134
- * ```javascript
135
- * // write the component values to the entity
136
- * ecs.setValues(entityId, new PlayerComponent(), new PositionComponent());
137
- * ```
97
+ * const [player, position] = ecs.setValues(entityId, new PlayerComponent(), new PositionComponent());
138
98
  */
139
- setValues<T1 extends IComponent, T2 extends IComponent, T3 extends IComponent, T4 extends IComponent, T5 extends IComponent>(entityId: number, a: T1, b: T2, c?: T3, d?: T4, e?: T5): [T1, T2, T3, T4, T5];
99
+ setValues<T extends IComponent[]>(entityId: number, ...components: T): T;
140
100
  /**
141
- * Removes an entity from its entity map.
142
- * Removes any related Node entities that are mapped to the entity
101
+ * Removes the specified component(s) from an entity
143
102
  *
144
103
  * @example
145
- *
146
- * ```javascript
147
- * // remove an entity from its entity map
148
- * EntityMap.remove(entityId, Components.PositionComponent);
149
- * ```
104
+ * ecs.remove(entityId, Components.PositionComponent);
150
105
  */
151
- remove<T extends IComponent>(entityId: number, component: ComponentClass<T>): boolean;
106
+ remove<T extends ComponentClass<any>[]>(entityId: number, ...components: T): void;
152
107
  /**
153
- * Removes an entity from its entity map.
154
- * Removes any related Node entities that are mapped to the entity
108
+ * Removes the specified component from an entity
155
109
  *
156
110
  * @example
157
- *
158
- * ```javascript
159
- * // remove an entity from its entity map
160
- * EntityMap.removeByKey(entityId, "PositionComponent");
161
- * ```
111
+ * ecs.removeByKey(entityId, "PositionComponent");
162
112
  */
163
113
  removeByKey(entityId: number, componentName: string): boolean;
164
114
  /**
165
- * Destroys an entity across all component maps
115
+ * Deletes an entity from all component maps
116
+ *
117
+ * @example
118
+ * ecs.destroyEntity(entityId);
166
119
  */
167
120
  destroyEntity(entityId: number): void;
168
121
  getNextId(): number;
@@ -179,12 +132,8 @@ export declare class EntityMap {
179
132
  * Parse's the JSON and returns an EntityMap object
180
133
  *
181
134
  * @example
182
- *
183
- * ```javascript
184
- * // remove an entity from its entity map
185
- * const json = JSON.stringfy(ecs);
186
- * const restoredMap = EntityMap.parse(json);
187
- * ```
135
+ * const json = JSON.stringfy(ecs);
136
+ * const restoredMap = ecs.parse(json);
188
137
  */
189
138
  static parse(json: string): EntityMap;
190
139
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"entity-map.d.ts","sourceRoot":"","sources":["../../../src/entity-map.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity-map.d.ts","sourceRoot":"","sources":["../../../src/entity-map.ts"],"names":[],"mappings":"AAkBA;;GAEG;AACH,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAG1B;;;;GAIG;AACH,qBAAa,SAAS;IAGpB,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO,CAAC,MAAM,CAAY;;IAI1B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,KAAK,SAAS,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,gBAAgB,EAAE,KAAK;IAexE;;OAEG;IACH,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS;IAIxE;;;;;OAKG;IACH,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAI1C;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAIxC;;;;;OAKG;IACH,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAI1C;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;IAQzD;;;;;;;;OAQG;IACH,SAAS,CAAC,KAAK,SAAS,cAAc,CAAC,GAAG,CAAC,EAAE,EAC3C,QAAQ,EAAE,MAAM,EAChB,GAAG,UAAU,EAAE,KAAK,GACnB,kBAAkB,CAAC,KAAK,CAAC;IAI5B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;IAShD;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO;IAQ/D;;;;;OAKG;IACH,GAAG,CAAC,CAAC,SAAS,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC;IAehE;;;;;OAKG;IACH,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC,GAAG,CAAC;IAKxE;;;;;OAKG;IACH,MAAM,CAAC,CAAC,SAAS,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IAM1E;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;IAgBnD;;;;;OAKG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM;IAO9B,SAAS;IAKT,KAAK;IAKL;;OAEG;IACH,UAAU;IAKV;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM;IAe5B;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM;IAsBzB;;;;;;;;OAQG;IACH,MAAM,CAAC,iBAAiB,CAAC,UAAU,EAAE,GAAG;CAqBzC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "title": "ECS JS",
3
3
  "name": "ecsjs",
4
- "version": "1.0.0-beta.7",
4
+ "version": "1.0.0-beta.9",
5
5
  "description": "An entity component system library for JavaScript",
6
6
  "author": "2013+ pflannery (https://github.com/pflannery)",
7
7
  "license": "GNU GPL v3",
@@ -4,8 +4,10 @@ export type KeyCollection<T> = { [key: string]: T }
4
4
 
5
5
  export interface IComponent { }
6
6
 
7
- export type ComponentClass<T extends IComponent> = {
8
- new(...args: any[]): T
7
+ export type ComponentClass<TInstance> = new (...args: any[]) => TInstance
8
+
9
+ export type ComponentInstances<TClasses> = {
10
+ [Index in keyof TClasses]: TClasses[Index] extends ComponentClass<infer U> ? U : never
9
11
  }
10
12
 
11
13
  export type ComponentDataMap<T> = KeyMap<number, T>
package/src/entity-map.ts CHANGED
@@ -22,6 +22,7 @@
22
22
  import {
23
23
  type ComponentClass,
24
24
  type ComponentDataMap,
25
+ type ComponentInstances,
25
26
  type ComponentMap,
26
27
  type IComponent
27
28
  } from './definitions.js';
@@ -42,26 +43,23 @@ export class EntityMap {
42
43
  constructor() { }
43
44
 
44
45
  /**
45
- * Registers a component class
46
+ * Registers component classes
46
47
  *
47
48
  * @example
49
+ * // component class
50
+ * class MyComponent {
51
+ * constructor(x) {
52
+ * this.x = x;
53
+ * }
54
+ * }
48
55
  *
49
- * ```javascript
50
- * // component class
51
- * class MyComponent {
52
- * constructor(x) {
53
- * this.x = x;
54
- * }
55
- * }
56
- *
57
- * ecs.register(MyComponent);
58
- * // or
59
- * ecs.register(MyComponent1, MyComponent2);
60
- * ```
56
+ * ecs.register(MyComponent);
57
+ * // or
58
+ * ecs.register(MyComponent1, MyComponent2);
61
59
  */
62
- register(...component: ComponentClass<any>[]) {
63
- for (const definition of component) {
64
- const componentName = definition.name;
60
+ register<TArgs extends ComponentClass<any>[]>(...componentClasses: TArgs) {
61
+ for (const componentClass of componentClasses) {
62
+ const componentName = componentClass.name;
65
63
  if (componentName === undefined)
66
64
  throw new ReferenceError("The component class does not have a name defined. i.e. a constructor name");
67
65
 
@@ -75,9 +73,9 @@ export class EntityMap {
75
73
  }
76
74
 
77
75
  /**
78
- * Retrieves an entity map by it's registered type
76
+ * Get a component class map
79
77
  */
80
- getMap<T extends IComponent>(component: ComponentClass<T>): ComponentDataMap<T> | undefined {
78
+ getMap<T>(component: ComponentClass<T>): ComponentDataMap<T> | undefined {
81
79
  return this.componentMaps.get(component.name);
82
80
  }
83
81
 
@@ -85,12 +83,9 @@ export class EntityMap {
85
83
  * Get the first entity entry for a component class
86
84
  *
87
85
  * @example
88
- *
89
- * ```javascript
90
- * const [entityId, player] = ecs.firstEntry(PlayerComponent) ?? [];
91
- * ```
86
+ * const [entityId, player] = ecs.firstEntry(PlayerComponent) ?? [];
92
87
  */
93
- firstEntry<T extends IComponent>(component: ComponentClass<T>) {
88
+ firstEntry<T>(component: ComponentClass<T>) {
94
89
  return this.getMap(component)?.firstEntry();
95
90
  }
96
91
 
@@ -98,12 +93,9 @@ export class EntityMap {
98
93
  * Get the first entity id for a component class
99
94
  *
100
95
  * @example
101
- *
102
- * ```javascript
103
- * const entityId = ecs.firstKey(PlayerComponent);
104
- * ```
96
+ * const entityId = ecs.firstKey(PlayerComponent);
105
97
  */
106
- firstKey<T extends IComponent>(component: ComponentClass<T>) {
98
+ firstKey<T>(component: ComponentClass<T>) {
107
99
  return this.getMap(component)?.firstKey();
108
100
  }
109
101
 
@@ -111,31 +103,24 @@ export class EntityMap {
111
103
  * Get the first entity component value for a component class
112
104
  *
113
105
  * @example
114
- *
115
- * ```javascript
116
- * const player = ecs.firstValue(PlayerComponent);
117
- * ```
106
+ * const player = ecs.firstValue(PlayerComponent);
118
107
  */
119
- firstValue<T extends IComponent>(component: ComponentClass<T>) {
108
+ firstValue<T>(component: ComponentClass<T>) {
120
109
  return this.getMap(component)?.firstValue();
121
110
  }
122
111
 
123
112
  /**
124
- * Retrieves an entity from its registered entity map
113
+ * Get a component related to an entity
125
114
  *
126
115
  * @example
127
- *
128
- * ```javascript
129
- * // get an entity
130
- * let positionData = ecs.get(entityId, Components.PositionComponent);
131
- * ```
116
+ * const position = ecs.get(entityId, Components.PositionComponent);
132
117
  */
133
- get<T extends IComponent>(entityId: number, component: ComponentClass<T>): T {
134
- let cm = this.componentMaps.get(component.name);
135
- if (cm === undefined)
118
+ get<T>(entityId: number, component: ComponentClass<T>): T {
119
+ const map = this.componentMaps.get(component.name);
120
+ if (map === undefined)
136
121
  throw new ReferenceError(`"${component}" component class does not exist in the componentMaps`);
137
122
 
138
- return cm.get(entityId);
123
+ return map.get(entityId);
139
124
  }
140
125
 
141
126
  /**
@@ -145,43 +130,24 @@ export class EntityMap {
145
130
  * @param components: ComponentClass<any>[]
146
131
  *
147
132
  * @example
148
- *
149
- * ```javascript
150
- * // get an entity
151
- * const [player, position] = ecs.getValues(entityId, PlayerComponent, PositionComponent);
152
- * ```
133
+ * const [player, position] = ecs.getValues(entityId, PlayerComponent, PositionComponent);
153
134
  */
154
- getValues<
155
- T1 extends IComponent,
156
- T2 extends IComponent,
157
- T3 extends IComponent,
158
- T4 extends IComponent,
159
- T5 extends IComponent
160
- >(
135
+ getValues<TArgs extends ComponentClass<any>[]>(
161
136
  entityId: number,
162
- a: ComponentClass<T1>,
163
- b: ComponentClass<T2>,
164
- c?: ComponentClass<T3>,
165
- d?: ComponentClass<T4>,
166
- e?: ComponentClass<T5>
167
- ): [T1, T2, T3, T4, T5];
168
- getValues(entityId: number, ...components: ComponentClass<any>[]): IComponent[] {
169
- return components.map(x => this.get(entityId, x))
137
+ ...components: TArgs
138
+ ): ComponentInstances<TArgs> {
139
+ return components.map(x => this.get(entityId, x)) as any
170
140
  }
171
141
 
172
142
  /**
173
143
  * Retrieves an entity from its registered entity map
174
144
  *
175
145
  * @example
176
- *
177
- * ```javascript
178
- * // get an entity
179
- * let positionData = ecs.getByKey(entityId, "PositionComponent");
180
- * ```
146
+ * const positionData = ecs.getByKey(entityId, "PositionComponent");
181
147
  */
182
148
  getByKey(entityId: number, componentName: string) {
183
149
  // get the component map
184
- let map = this.componentMaps.get(componentName);
150
+ const map = this.componentMaps.get(componentName);
185
151
  if (map === undefined)
186
152
  throw new ReferenceError(`"${componentName}" component does not exist in the componentMaps`);
187
153
 
@@ -189,37 +155,28 @@ export class EntityMap {
189
155
  }
190
156
 
191
157
  /**
192
- * Checks if the entity exists in it's registed component map
193
- * The entity type must be registered before calling this method
158
+ * Check if a component exists for an entity
194
159
  *
195
160
  * @example
196
- *
197
- * ```javascript
198
- * // get an entity
199
- * let exists = ecs.has(entityId, PositionComponent);
200
- * ```
161
+ * const exists = ecs.has(entityId, PositionComponent);
201
162
  */
202
- has<T extends IComponent>(entityId: number, component: ComponentClass<T>): boolean {
163
+ has<T>(entityId: number, component: ComponentClass<T>): boolean {
203
164
  // get the component map
204
- let map = this.componentMaps.get(component.name);
165
+ const map = this.componentMaps.get(component.name);
205
166
  if (map === undefined) return false
206
167
 
207
168
  return map.has(entityId);
208
169
  }
209
170
 
210
171
  /**
211
- * Adds or updates an entity to it's registered entity map
172
+ * Add or update a component value for an entity
212
173
  *
213
174
  * @example
214
- *
215
- * ```javascript
216
- * // add/update an entity
217
- * let playerPos = ecs.set(entityId, new Components.PositionComponent(0, 0));
218
- * ```
175
+ * const position = ecs.set(entityId, new Components.PositionComponent(0, 0));
219
176
  */
220
177
  set<T extends IComponent>(entityId: number, componentData: T): T {
221
178
  // get the component map
222
- let map = this.componentMaps.get(componentData.constructor.name);
179
+ const map = this.componentMaps.get(componentData.constructor.name);
223
180
  if (map === undefined)
224
181
  throw new ReferenceError(
225
182
  `Component map does not exist using the name: ${componentData.constructor.name}`
@@ -233,72 +190,44 @@ export class EntityMap {
233
190
  }
234
191
 
235
192
  /**
236
- * Set multiple component values for an entity
237
- *
238
- * @param entityId
239
- * @param components: ComponentClass<any>[]
193
+ * Add or update multiple component values for an entity
240
194
  *
241
195
  * @example
242
- *
243
- * ```javascript
244
- * // write the component values to the entity
245
- * ecs.setValues(entityId, new PlayerComponent(), new PositionComponent());
246
- * ```
196
+ * const [player, position] = ecs.setValues(entityId, new PlayerComponent(), new PositionComponent());
247
197
  */
248
- setValues<
249
- T1 extends IComponent,
250
- T2 extends IComponent,
251
- T3 extends IComponent,
252
- T4 extends IComponent,
253
- T5 extends IComponent
254
- >(
255
- entityId: number,
256
- a: T1,
257
- b: T2,
258
- c?: T3,
259
- d?: T4,
260
- e?: T5
261
- ): [T1, T2, T3, T4, T5];
198
+ setValues<T extends IComponent[]>(entityId: number, ...components: T): T;
262
199
  setValues(entityId: number, ...components: IComponent[]): IComponent[] {
263
200
  return components.map(x => this.set(entityId, x))
264
201
  }
265
202
 
266
203
  /**
267
- * Removes an entity from its entity map.
268
- * Removes any related Node entities that are mapped to the entity
204
+ * Removes the specified component(s) from an entity
269
205
  *
270
206
  * @example
271
- *
272
- * ```javascript
273
- * // remove an entity from its entity map
274
- * EntityMap.remove(entityId, Components.PositionComponent);
275
- * ```
207
+ * ecs.remove(entityId, Components.PositionComponent);
276
208
  */
277
- remove<T extends IComponent>(entityId: number, component: ComponentClass<T>) {
278
- return this.removeByKey(entityId, component.name);
209
+ remove<T extends ComponentClass<any>[]>(entityId: number, ...components: T) {
210
+ for (const component of components) {
211
+ this.removeByKey(entityId, component.name)
212
+ }
279
213
  }
280
214
 
281
215
  /**
282
- * Removes an entity from its entity map.
283
- * Removes any related Node entities that are mapped to the entity
216
+ * Removes the specified component from an entity
284
217
  *
285
218
  * @example
286
- *
287
- * ```javascript
288
- * // remove an entity from its entity map
289
- * EntityMap.removeByKey(entityId, "PositionComponent");
290
- * ```
219
+ * ecs.removeByKey(entityId, "PositionComponent");
291
220
  */
292
221
  removeByKey(entityId: number, componentName: string) {
293
222
  // get the entity map
294
- let entityMap = this.componentMaps.get(componentName);
223
+ const entityMap = this.componentMaps.get(componentName);
295
224
 
296
225
  // ensure the map is defined
297
226
  if (entityMap === undefined)
298
227
  throw new ReferenceError(`A registered entity map does not exist for the given key: ${componentName}`);
299
228
 
300
229
  // get the entity
301
- let entity = entityMap.get(entityId);
230
+ const entity = entityMap.get(entityId);
302
231
  if (entity === undefined) return false;
303
232
 
304
233
  // remove the entity from the entity map
@@ -306,12 +235,15 @@ export class EntityMap {
306
235
  }
307
236
 
308
237
  /**
309
- * Destroys an entity across all component maps
238
+ * Deletes an entity from all component maps
239
+ *
240
+ * @example
241
+ * ecs.destroyEntity(entityId);
310
242
  */
311
243
  destroyEntity(entityId: number) {
312
- this.componentMaps.forEach((dataMap: ComponentDataMap<any>) => {
313
- if (dataMap.has(entityId)) dataMap.delete(entityId);
314
- });
244
+ for (const map of this.componentMaps.values()) {
245
+ if (map.has(entityId)) map.delete(entityId);
246
+ }
315
247
  }
316
248
 
317
249
  // TODO generate a non repeatable id for network play?
@@ -355,12 +287,8 @@ export class EntityMap {
355
287
  * Parse's the JSON and returns an EntityMap object
356
288
  *
357
289
  * @example
358
- *
359
- * ```javascript
360
- * // remove an entity from its entity map
361
- * const json = JSON.stringfy(ecs);
362
- * const restoredMap = EntityMap.parse(json);
363
- * ```
290
+ * const json = JSON.stringfy(ecs);
291
+ * const restoredMap = ecs.parse(json);
364
292
  */
365
293
  static parse(json: string) {
366
294
  const ecs = new EntityMap();
@@ -394,7 +322,7 @@ export class EntityMap {
394
322
  * @return {EntityMap} A new entity map with tracing enabled
395
323
  */
396
324
  static createWithTracing(funcFilter: any) {
397
- let traceHandler = {
325
+ const traceHandler = {
398
326
  get(target: any, propKey: string) {
399
327
  const targetValue = target[propKey]
400
328