ecsjs 1.3.0-beta.3 → 1.3.0

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 c="ComponentMap",d="ComponentClassesMap";var p=class{indices=[];entities=[];instances=[];constructor(e){if(e)for(let t=0;t<e.length;t++){let n=e[t];this.set(n[0],n[1])}}get size(){return this.instances.length}clear(){this.indices=[],this.entities.length=0,this.instances.length=0}set(e,t){if(this.has(e)){this.instances[this.indices[e]]=t;return}this.indices[e]=this.instances.length,this.entities.push(e),this.instances.push(t)}get(e){let t=this.indices[e];return t!==void 0&&this.entities[t]===e?this.instances[t]:void 0}delete(e){let t=this.indices[e];if(t===void 0||t===-1||this.entities[t]!==e)return!1;let n=this.instances.length-1,s=this.entities[n];return this.instances[t]=this.instances[n],this.entities[t]=s,this.indices[s]=t,this.instances.pop(),this.entities.pop(),this.indices[e]=-1,!0}has(e){let t=this.indices[e];return t!==void 0&&t!==-1&&this.entities[t]===e}forEach(e){for(let t=0;t<this.instances.length;t++)e(this.instances[t],this.entities[t])}firstEntry(){return this.entities.length===0?void 0:[this.entities[0],this.instances[0]]}firstKey(){return this.entities.length===0?void 0:this.entities[0]}firstValue(){return this.instances.length===0?void 0:this.instances[0]}[Symbol.iterator](){return this.entries()}keys(){return this.entities.values()}values(){return this.instances.values()}entries(){let e=0,t=this.entities,n=this.instances;return{next(){if(e<n.length){let s={value:[t[e],n[e]],done:!1};return e++,s}return{value:void 0,done:!0}},reset(){e=0},[Symbol.iterator](){return this}}}toJSON(){return{[c]:1,iterable:[...this.entries()]}}toTable(){let e=[];for(let[t,n]of this.entries()){let s=n,r={};r["entity.key"]=t,r["entity.type"]=s.constructor.name,e.push({...r,...s})}return e}printTable(e=[]){console.table(this.toTable(),e)}},m=class extends Map{toJSON(){return{[d]:1,iterable:[...this.entries()]}}static get[Symbol.species](){return Map}};var h=class extends Error{constructor(){super("Component type is missing the 'name' parameter. i.e. a constructor name")}},i=class extends Error{constructor(t){super(`Component map does not exist for '${t}'`);this.componentName=t}};var a=class{keyMap;componentMaps=[];entries;constructor(e){this.keyMap=e.keyMap,this.componentMaps=e.componentMaps,this.entries=this.keyMap.entries()}next(){let e=this.entries.next(),{value:t,done:n}=e;if(n)return{value:t,done:n};let s=t[0];for(let r=0;r<this.componentMaps.length;r++){let l=this.componentMaps[r];t.push(l.get(s))}return{value:t,done:!1}}reset(){this.entries=this.keyMap.entries()}[Symbol.iterator](){return this}};var u=class{constructor(e,...t){this.ecs=e;this.keyMap=this.ecs.getMap(t[0]);for(let n=1;n<t.length;n++)this.componentMaps.push(this.ecs.getMap(t[n]));this.keys=this.keyMap.keys,this.entries=this[Symbol.iterator]}keyMap;componentMaps=[];keys;entries;firstEntry(){if(this.componentMaps.length===0)return this.keyMap.firstEntry();let[e,t]=this.keyMap.firstEntry()??[];if(e===void 0)return;let n=[e,t];for(let s=0;s<this.componentMaps.length;s++)n.push(this.componentMaps[s].get(e));return n}firstKey(){let e=this.keyMap.firstKey();if(this.componentMaps.length===0)return e;if(e===void 0)return;let t=[e];for(let n=0;n<this.componentMaps.length;n++)t.push(this.componentMaps[n].get(e));return t}firstValue(){if(this.componentMaps.length===0)return this.keyMap.firstValue();let[e,t]=this.keyMap.firstEntry()??[];if(e===void 0)return;let n=[t];for(let s=0;s<this.componentMaps.length;s++)n.push(this.componentMaps[s].get(e));return n}get entityCount(){return this.keyMap.size}destroyEntities(){return this.ecs.destroyEntity(...this.keyMap.keys())}values(){let e=this.keyMap,t=this.componentMaps,n=e.keys();return{next(){let s=n.next();if(s.done)return{value:void 0,done:!0};let r=s.value,C=[e.get(r)];for(let f=0;f<t.length;f++){let g=t[f];C.push(g.get(r))}return{value:C,done:!1}},reset(){n=e.keys()},[Symbol.iterator](){return this}}}[Symbol.iterator](){return new a(this)}};var y=class o{components=new m;nextId=0;register(...e){for(let t of e){let n=t.name;if(n===void 0)throw new h;let s=new p;this.components.set(n,s)}return this}getMap(e){let t=this.components.get(e.name);if(t===void 0)throw new i(e.name);return t}first(e){let t=this.getMap(e)?.firstKey();if(t!==void 0)return this.get(t)}firstEntry(e,...t){return t.length===0?this.getMap(e)?.firstEntry():this.firstKey(e,e,...t)}firstKey(e,...t){let n=this.getMap(e)?.firstKey();if(arguments.length===1)return n;if(n!==void 0)return[n,...t.map(s=>this.getEntity(n,s))]}firstValue(e,...t){if(arguments.length===1)return this.getMap(e)?.firstValue();let[n,s]=this.getMap(e)?.firstEntry()??[];if(n!==void 0)return[s,...t.map(r=>this.getEntity(n,r))]}getEntity(e,t){let n=this.components.get(t.name);if(n===void 0)throw new i(t.name);return n.get(e)}get(e,...t){return t.length===1?this.getEntity(e,t[0]):t.length>1?t.map(n=>this.getEntity(e,n)):[...this.components.values()].filter(n=>n.has(e)).map(n=>n.get(e))}has(e,t){let n=this.components.get(t.name);return n===void 0?!1:n.has(e)}hasAll(e,...t){for(let n=0;n<t.length;n++){let s=t[n],r=this.components.get(s.name);if(r===void 0||r.has(e)===!1)return!1}return!0}hasAny(e,...t){for(let n=0;n<t.length;n++){let s=t[n],r=this.components.get(s.name);if(r!==void 0&&r.has(e))return!0}return!1}setEntity(e,t){let n=this.components.get(t.constructor.name);if(n===void 0)throw new i(t.constructor.name);return n.set(e,t),t}set(e,...t){return t.length>1?t.map(n=>this.setEntity(e,n)):this.setEntity(e,t[0])}remove(e,...t){for(let n of t)this.removeByKey(e,n.name)}removeByKey(e,t){let n=this.components.get(t);if(n===void 0)throw new i(t);return n.get(e)===void 0?!1:n.delete(e)}destroyEntity(...e){let t=0;for(let n=0;n<e.length;n++){let s=e[n];for(let r of this.components.values())r.has(s)&&(r.delete(s),t++)}return t}getNextId(){return this.nextId++,this.nextId}clear(){return this.components.clear(),this.nextId=0,this}clearComponents(){return this.components.forEach(e=>e.clear()),this.nextId=0,this}iterator(e,...t){return new a(new u(this,e,...t))}query(e,...t){return new u(this,e,...t)}printTable(){let e=arguments[0]??[],t=arguments[1]??[];return this.components.forEach((n,s)=>{(e.length===0||e.includes(s))&&console.table(n.toTable(),t)}),this}printEntity(e,t=[]){for(let n of this.components.values()){if(n.has(e)===!1)continue;let s=n.get(e),r={"entity.type":s.constructor.name,...s};console.table({[e]:r},t)}return this}static parse(e){return JSON.parse(e,function(n,s){return s.hasOwnProperty("components")?(Reflect.setPrototypeOf(s,o.prototype),s):s.hasOwnProperty(c)?new p(s.iterable):s.hasOwnProperty(d)?new m(s.iterable):this[n]})}static createWithTracing(e){let t={get(n,s){let r=n[s];return typeof r=="function"&&(e.length===0||e.includes(s))?function(...l){return console.groupCollapsed("ecs trace",s,l),console.trace(),console.groupEnd(),r.apply(this,l)}:r}};return new Proxy(new o,t)}};var T=new y;typeof window<"u"?window.ecs=T:typeof module<"u"&&module!==null&&(module.exports={ecs:T});export{m as ComponentClassesMap,a as ComponentIterator,p as ComponentMap,u as ComponentQuery,y as EntityMap,T as ecs};
1
+ var d="ComponentMap",y="ComponentClassesMap";function T(r){let e=0;for(let t=0;t<r.length;t++){let n=r.charCodeAt(t);e=(e<<5)-e+n,e|=0}return e}var p=class{hashIdToName=new Map;hashIdToIndex=new Map;indexToHashId=[];maps=[];constructor(e){if(e)for(let t=0;t<e.length;t++){let n=e[t];this.setByHashId(n[0],n[1])}}get size(){return this.maps.length}clear(){this.maps.length=0,this.indexToHashId.length=0,this.hashIdToIndex.clear()}get(e){let t=this.hashIdToIndex.get(e.hashId);return t!==void 0?this.maps[t]:void 0}set(e,t){return e.hashId===void 0&&(e.hashId=T(e.name)),this.hashIdToName.set(e.hashId,e.name),this.setByHashId(e.hashId,t)}setByHashId(e,t){let n=this.hashIdToIndex.get(e);return n!==void 0?this.maps[n]=t:(this.hashIdToIndex.set(e,this.maps.length),this.indexToHashId.push(e),this.maps.push(t)),this}delete(e){let t=e.hashId,n=this.hashIdToIndex.get(t);if(n===void 0)return!1;let s=this.maps.length-1,o=this.indexToHashId[s];return this.maps[n]=this.maps[s],this.indexToHashId[n]=o,this.hashIdToIndex.set(o,n),this.maps.pop(),this.indexToHashId.pop(),this.hashIdToIndex.delete(t),!0}forEach(e){for(let t=0;t<this.maps.length;t++)e(this.maps[t],this.hashIdToName.get(this.indexToHashId[t]))}values(){return this.maps.values()}entries(){let e=0,t=this.maps,n=this.indexToHashId;return{next(){if(e<t.length){let s=[n[e],t[e]];return e++,{value:s,done:!1}}return{value:void 0,done:!0}},reset(){e=0},[Symbol.iterator](){return this}}}toJSON(){return{[y]:1,iterable:[...this.entries()]}}};var m=class{indices=[];entities=[];instances=[];constructor(e){if(e)for(let t=0;t<e.length;t++){let n=e[t];this.set(n[0],n[1])}}get size(){return this.instances.length}clear(){this.indices=[],this.entities.length=0,this.instances.length=0}set(e,t){if(this.has(e)){this.instances[this.indices[e]]=t;return}this.indices[e]=this.instances.length,this.entities.push(e),this.instances.push(t)}get(e){let t=this.indices[e];return t!==void 0&&this.entities[t]===e?this.instances[t]:void 0}delete(e){let t=this.indices[e];if(t===void 0||t===-1||this.entities[t]!==e)return!1;let n=this.instances.length-1,s=this.entities[n];return this.instances[t]=this.instances[n],this.entities[t]=s,this.indices[s]=t,this.instances.pop(),this.entities.pop(),this.indices[e]=-1,!0}has(e){let t=this.indices[e];return t!==void 0&&t!==-1&&this.entities[t]===e}forEach(e){for(let t=0;t<this.instances.length;t++)e(this.instances[t],this.entities[t])}firstEntry(){return this.entities.length===0?void 0:[this.entities[0],this.instances[0]]}firstKey(){return this.entities.length===0?void 0:this.entities[0]}firstValue(){return this.instances.length===0?void 0:this.instances[0]}[Symbol.iterator](){return this.entries()}keys(){return this.entities.values()}values(){return this.instances.values()}entries(){let e=0,t=this.entities,n=this.instances;return{next(){if(e<n.length){let s={value:[t[e],n[e]],done:!1};return e++,s}return{value:void 0,done:!0}},reset(){e=0},[Symbol.iterator](){return this}}}toJSON(){return{[d]:1,iterable:[...this.entries()]}}toTable(){let e=[];for(let[t,n]of this.entries()){let s=n,o={};o["entity.key"]=t,o["entity.type"]=s.constructor.name,e.push({...o,...s})}return e}printTable(e=[]){console.table(this.toTable(),e)}};var c=class extends Error{constructor(){super("Component type is missing the 'name' parameter. i.e. a constructor name")}},i=class extends Error{constructor(t){super(`Component map does not exist for '${t}'`);this.componentName=t}};var a=class{keyMap;componentMaps=[];entries;constructor(e){this.keyMap=e.keyMap,this.componentMaps=e.componentMaps,this.entries=this.keyMap.entries()}next(){let e=this.entries.next(),{value:t,done:n}=e;if(n)return{value:t,done:n};let s=t[0];for(let o=0;o<this.componentMaps.length;o++){let h=this.componentMaps[o];t.push(h.get(s))}return{value:t,done:!1}}reset(){this.entries=this.keyMap.entries()}[Symbol.iterator](){return this}};var u=class{constructor(e,...t){this.ecs=e;this.keyMap=this.ecs.getMap(t[0]);for(let n=1;n<t.length;n++)this.componentMaps.push(this.ecs.getMap(t[n]))}keyMap;componentMaps=[];firstEntry(){if(this.componentMaps.length===0)return this.keyMap.firstEntry();let[e,t]=this.keyMap.firstEntry()??[];if(e===void 0)return;let n=[e,t];for(let s=0;s<this.componentMaps.length;s++)n.push(this.componentMaps[s].get(e));return n}firstKey(){let e=this.keyMap.firstKey();if(this.componentMaps.length===0)return e;if(e===void 0)return;let t=[e];for(let n=0;n<this.componentMaps.length;n++)t.push(this.componentMaps[n].get(e));return t}firstValue(){if(this.componentMaps.length===0)return this.keyMap.firstValue();let[e,t]=this.keyMap.firstEntry()??[];if(e===void 0)return;let n=[t];for(let s=0;s<this.componentMaps.length;s++)n.push(this.componentMaps[s].get(e));return n}get entityCount(){return this.keyMap.size}destroyEntities(){return this.ecs.destroyEntity(...this.keyMap.keys())}keys(){return this.keyMap.keys()}values(){let e=this.keyMap,t=this.componentMaps,n=e.keys();return{next(){let s=n.next();if(s.done)return{value:void 0,done:!0};let o=s.value,C=[e.get(o)];for(let f=0;f<t.length;f++){let I=t[f];C.push(I.get(o))}return{value:C,done:!1}},reset(){n=e.keys()},[Symbol.iterator](){return this}}}entries(){return this[Symbol.iterator]()}[Symbol.iterator](){return new a(this)}};var l=class r{components=new p;nextId=0;register(...e){for(let t of e){if(t.name===void 0)throw new c;this.components.set(t,new m)}return this}getMap(e){let t=this.components.get(e);if(t===void 0)throw new i(e.name);return t}first(e){let t=this.getMap(e)?.firstKey();if(t!==void 0)return this.get(t)}firstEntry(e,...t){return t.length===0?this.getMap(e)?.firstEntry():this.firstKey(e,e,...t)}firstKey(e,...t){let n=this.getMap(e)?.firstKey();if(arguments.length===1)return n;if(n!==void 0)return[n,...t.map(s=>this.getEntity(n,s))]}firstValue(e,...t){if(arguments.length===1)return this.getMap(e)?.firstValue();let[n,s]=this.getMap(e)?.firstEntry()??[];if(n!==void 0)return[s,...t.map(o=>this.getEntity(n,o))]}getEntity(e,t){let n=this.components.get(t);if(n===void 0)throw new i(t.name);return n.get(e)}get(e,...t){return t.length===1?this.getEntity(e,t[0]):t.length>1?t.map(n=>this.getEntity(e,n)):[...this.components.values()].filter(n=>n.has(e)).map(n=>n.get(e))}has(e,t){let n=this.components.get(t);return n===void 0?!1:n.has(e)}hasAll(e,...t){for(let n=0;n<t.length;n++){let s=t[n],o=this.components.get(s);if(o===void 0||o.has(e)===!1)return!1}return!0}hasAny(e,...t){for(let n=0;n<t.length;n++){let s=t[n],o=this.components.get(s);if(o!==void 0&&o.has(e))return!0}return!1}setEntity(e,t){let n=this.components.get(t.constructor);if(n===void 0)throw new i(t.constructor.name);return n.set(e,t),t}set(e,...t){return t.length>1?t.map(n=>this.setEntity(e,n)):this.setEntity(e,t[0])}remove(e,...t){for(let n of t)this.removeByKey(e,n)}removeByKey(e,t){let n=this.components.get(t);if(n===void 0)throw new i(t.name);return n.get(e)===void 0?!1:n.delete(e)}destroyEntity(...e){let t=0;for(let n=0;n<e.length;n++){let s=e[n];for(let o of this.components.values())o.has(s)&&(o.delete(s),t++)}return t}getNextId(){return this.nextId++,this.nextId}clear(){return this.components.clear(),this.nextId=0,this}clearComponents(){return this.components.forEach(e=>e.clear()),this.nextId=0,this}iterator(e,...t){return new a(new u(this,e,...t))}query(e,...t){return new u(this,e,...t)}printTable(){let e=arguments[0]??[],t=arguments[1]??[];return this.components.forEach((n,s)=>{(e.length===0||e.includes(s))&&console.table(n.toTable(),t)}),this}printEntity(e,t=[]){for(let n of this.components.values()){if(n.has(e)===!1)continue;let s=n.get(e),o={"entity.type":s.constructor.name,...s};console.table({[e]:o},t)}return this}static parse(e){return JSON.parse(e,function(n,s){return s.hasOwnProperty("components")?(Reflect.setPrototypeOf(s,r.prototype),s):s.hasOwnProperty(d)?new m(s.iterable):s.hasOwnProperty(y)?new p(s.iterable):this[n]})}static createWithTracing(e){let t={get(n,s){let o=n[s];return typeof o=="function"&&(e.length===0||e.includes(s))?function(...h){return console.groupCollapsed("ecs trace",s,h),console.trace(),console.groupEnd(),o.apply(this,h)}:o}};return new Proxy(new r,t)}};var g=new l;typeof window<"u"?window.ecs=g:typeof module<"u"&&module!==null&&(module.exports={ecs:g});export{p as ComponentClassesMap,a as ComponentIterator,m as ComponentMap,u as ComponentQuery,l as EntityMap,g 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
- "sources": ["../src/types.ts", "../src/component-map.ts", "../src/errors.ts", "../src/iterator.ts", "../src/query.ts", "../src/entity-map.ts", "../src/ecs.ts"],
4
- "sourcesContent": ["export const ComponentMapKey = \"ComponentMap\"\nexport const ComponentClassesMapKey = \"ComponentClassesMap\"\n\nexport type KeyCollection<T> = { [key: string]: T }\n\nexport interface Component { }\n\n/**\n * @category Types\n * @example\n * \n * class PositionComponent {\n * constructor(x, y) {\n * this.x = x;\n * this.y = y;\n * }\n * }\n */\nexport type ComponentClass<ComponentInstance> = new (...args: any[]) => ComponentInstance\n\n/**\n* Used for infering generic type spread for classes\n*/\nexport type ComponentClasses<T extends Component[]> =\n { [Index in keyof T]: ComponentClass<T[Index]> }\n\nexport type SingleOrArray<T extends any[]> =\n // return a single variadic item when only 1 item is specified\n T['length'] extends 1 ? T[0]\n // otherwise return an array of variadic types\n : { [Index in keyof T]: T[Index] }\n\nexport type IteratorResult<T> = {\n done: boolean,\n value: T\n}\n\nexport type Iterator<T> = {\n next: () => IteratorResult<T>\n reset: () => void\n [Symbol.iterator]: () => Iterator<T>\n}\n\n/**\n * allow late bound assignment type for intellisense\n * @category Types\n * @example\n * \n * let someIterator: IComponentIterator<[Player, Position]>\n * \n * // assignment made somewhere else in the code\n * const [player, position] = someIterator(Player, Position) ?? []\n * position?.x = 123 // position will have intellisense\n */\nexport type IComponentIterator<T extends Component[]>\n = Iterator<ComponentClasses<[number, ...T]>>", "/*\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 {\n ComponentClassesMapKey,\n ComponentMapKey,\n type Iterator,\n type IteratorResult,\n type KeyCollection\n} from './types.js';\n\n/**\n * Component map for storing entity ids and related component data\n * @category Maps\n */\nexport class ComponentMap<TComponentInstance> implements Iterable<[number, TComponentInstance]> {\n\n private indices: number[] = [];\n\n private entities: number[] = [];\n\n private instances: TComponentInstance[] = [];\n\n constructor(entries?: readonly (readonly [number, TComponentInstance])[] | null) {\n if (entries) {\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n this.set(entry[0], entry[1]);\n }\n }\n }\n\n get size() {\n return this.instances.length;\n }\n\n clear() {\n this.indices = [];\n this.entities.length = 0;\n this.instances.length = 0;\n }\n\n set(entityId: number, component: TComponentInstance) {\n if (this.has(entityId)) {\n this.instances[this.indices[entityId]] = component;\n return;\n }\n this.indices[entityId] = this.instances.length;\n this.entities.push(entityId);\n this.instances.push(component);\n }\n\n get(entityId: number) {\n const index = this.indices[entityId];\n return index !== undefined && this.entities[index] === entityId\n ? this.instances[index]\n : undefined;\n }\n\n delete(entityId: number) {\n const index = this.indices[entityId];\n if (index === undefined || index === -1 || this.entities[index] !== entityId) return false;\n\n // swap and pop with last element to keep dense\n const lastIdx = this.instances.length - 1;\n const lastEntity = this.entities[lastIdx];\n this.instances[index] = this.instances[lastIdx];\n this.entities[index] = lastEntity;\n this.indices[lastEntity] = index;\n this.instances.pop();\n this.entities.pop();\n\n // invalidate index\n this.indices[entityId] = -1;\n\n return true;\n }\n\n has(entityId: number) {\n const index = this.indices[entityId];\n return index !== undefined && index !== -1 && this.entities[index] === entityId;\n }\n\n forEach(callback: (value: TComponentInstance, key: number) => void) {\n for (let i = 0; i < this.instances.length; i++) {\n callback(this.instances[i], this.entities[i]);\n }\n }\n\n /**\n * Returns the first entity entry\n */\n firstEntry(): [entityId: number, value: TComponentInstance] | undefined {\n return this.entities.length === 0\n ? undefined\n : [this.entities[0], this.instances[0]];\n }\n\n /**\n * Returns the first entity id\n */\n firstKey(): number | undefined {\n return this.entities.length === 0\n ? undefined\n : this.entities[0];\n }\n\n /**\n * Returns the first entity value\n */\n firstValue(): TComponentInstance | undefined {\n return this.instances.length === 0\n ? undefined\n : this.instances[0];\n }\n\n [Symbol.iterator](): Iterator<[number, TComponentInstance]> {\n return this.entries();\n }\n\n keys(): ArrayIterator<number> {\n return this.entities.values();\n }\n\n values(): ArrayIterator<TComponentInstance> {\n return this.instances.values();\n }\n\n entries(): Iterator<[number, TComponentInstance]> {\n let index = 0;\n const entities = this.entities;\n const instances = this.instances;\n\n return {\n next(): IteratorResult<[number, TComponentInstance]> {\n if (index < instances.length) {\n const result: IteratorResult<[number, TComponentInstance]> = {\n value: [entities[index], instances[index]],\n done: false\n };\n index++;\n return result;\n }\n return { value: <any>undefined, done: true };\n },\n reset() {\n index = 0;\n },\n [Symbol.iterator]() {\n return this;\n },\n };\n }\n\n /**\n * Called when using JSON.stringify\n */\n toJSON() {\n return { [ComponentMapKey]: 1, iterable: [...this.entries()] };\n }\n\n toTable(): any[] {\n const table = []\n for (const [key, value] of this.entries()) {\n const entity = value as { new(): TComponentInstance };\n const meta: KeyCollection<any> = {};\n meta[\"entity.key\"] = key;\n meta[\"entity.type\"] = entity.constructor.name;\n table.push({ ...meta, ...entity });\n }\n return table;\n }\n\n /**\n * Prints entity data in a tabular format to the console\n */\n printTable(properties: string[] = []): void {\n console.table(this.toTable(), properties);\n }\n\n}\n\n/**\n * Component class map for storing registered component maps\n * @category Maps\n */\nexport class ComponentClassesMap extends Map<string, ComponentMap<any>> {\n\n /**\n * Called when using JSON.stringify\n */\n toJSON() {\n return { [ComponentClassesMapKey]: 1, iterable: [...this.entries()] };\n }\n\n static get [Symbol.species]() {\n return Map;\n }\n\n}", "/**\n * Thrown when trying to register a component that is missing a 'name' parameter\n * @category Errors\n */\nexport class ComponentTypeKeyMissing extends Error {\n constructor() {\n super(`Component type is missing the 'name' parameter. i.e. a constructor name`);\n }\n}\n\n/**\n * Thrown when trying to access a component that has not been registered\n * @category Errors\n */\nexport class ComponentNotRegistered extends Error {\n constructor(public componentName: string) {\n super(`Component map does not exist for '${componentName}'`);\n }\n}", "import type { ComponentMap } from './component-map.js';\nimport type { ComponentQuery } from './query.js';\nimport type { IteratorResult } from './types.js';\n\n/**\n * @category Iterators\n * @example\n * // construct an instance\n * const iterator = new ComponentIterator(new ComponentQuery(entityMap, Player, Position))\n * \n * // iterate each component value that is related to the Player\n * for(const [entityId, player, position] of iterator) { }\n * \n * // you can also reset the iterator back to the start\n * // without having to create a new ComponentIterator instance\n * iterator.reset()\n * for(const [entityId, player, position] of iterator) { }\n */\nexport class ComponentIterator<TKey, TRelated extends any[]> {\n private keyMap: ComponentMap<TKey>;\n private componentMaps: ComponentMap<any>[] = [];\n // iteration state\n private entries: Iterator<[number, TKey]>;\n\n constructor(query: ComponentQuery<TKey, TRelated>) {\n // @ts-ignore internal private var accessor\n this.keyMap = query.keyMap\n // @ts-ignore internal private var accessor\n this.componentMaps = query.componentMaps\n this.entries = this.keyMap.entries();\n }\n\n /**\n * gets the next iterator value\n */\n next(): IteratorResult<[number, TKey, ...TRelated]> {\n const entry = this.entries.next();\n const { value, done } = entry;\n if (done) return { value, done };\n\n const entityId = value[0];\n\n // append the related components\n for (let i = 0; i < this.componentMaps.length; i++) {\n const map = this.componentMaps[i];\n value.push(map.get(entityId));\n }\n\n return { value: value as any, done: false };\n }\n\n /**\n * resets the iterator back to the first entry\n */\n reset() {\n this.entries = this.keyMap.entries();\n }\n\n [Symbol.iterator]() { return this; }\n\n}", "import type { ComponentMap } from './component-map.js';\nimport type { EntityMap } from './entity-map.js';\nimport { ComponentIterator } from './iterator.js';\nimport type { ComponentClass, ComponentClasses, Iterator, IteratorResult, SingleOrArray } from './types.js';\n\n/**\n * @category Queries\n * @example\n * const query = ecs.query(Player, Position)\n * \n * // get the first entry\n * const [playerId, player, position] = query.firstEntry() ?? []\n * \n * // get the first key\n * const [playerId, position] = query.firstKey() ?? []\n * \n * // get the first value\n * const [player, position] = query.firstValue() ?? []\n * \n * // iterate\n * for (const [playerId, player, position] of query) {\n * \n * }\n */\nexport class ComponentQuery<TKey, TRelated extends any[]> {\n private keyMap: ComponentMap<TKey>\n private componentMaps: ComponentMap<any>[] = []\n\n\n /**\n * Returns a [entityId] iterator\n */\n public keys: () => ArrayIterator<number>;\n\n /**\n * Returns a [entityId, KeyComponent, ...RelatedComponents] iterator\n */\n public entries: () => ComponentIterator<TKey, TRelated>;\n\n /**\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n */\n constructor(\n public ecs: EntityMap,\n ...components: [ComponentClass<TKey>, ...ComponentClasses<TRelated>]\n ) {\n this.keyMap = this.ecs.getMap(components[0])!;\n for (let i = 1; i < components.length; i++) {\n this.componentMaps.push(this.ecs.getMap(components[i])!)\n }\n this.keys = this.keyMap.keys;\n this.entries = this[Symbol.iterator];\n }\n\n /**\n * Returns the first entity entry\n * \n * Optionally returns related components specified in the query constructor\n */\n firstEntry(): [number, TKey, ...TRelated] | undefined;\n firstEntry() {\n if (this.componentMaps.length === 0) return this.keyMap.firstEntry()\n\n const [entityId, entryValue] = this.keyMap.firstEntry() ?? []\n if (entityId === undefined) return undefined;\n\n const results: any[] = [entityId, entryValue]\n for (let i = 0; i < this.componentMaps.length; i++) {\n results.push(this.componentMaps[i].get(entityId));\n }\n\n return results\n }\n\n /**\n * Returns the first entity id\n * \n * Optionally returns related components specified in the query constructor\n */\n firstKey(): SingleOrArray<[number, ...TRelated]> | undefined;\n firstKey() {\n const entityId = this.keyMap.firstKey()\n if (this.componentMaps.length === 0) return entityId;\n if (entityId === undefined) return undefined;\n\n const results: any[] = [entityId]\n for (let i = 0; i < this.componentMaps.length; i++) {\n results.push(this.componentMaps[i].get(entityId));\n }\n\n return results\n }\n\n /**\n * Returns the first value\n * \n * Optionally returns related components specified in the query constructor\n */\n firstValue(): SingleOrArray<[TKey, ...TRelated]> | undefined;\n firstValue() {\n if (this.componentMaps.length === 0) return this.keyMap.firstValue()\n\n const [entityId, keyValue] = this.keyMap.firstEntry() ?? []\n if (entityId === undefined) return undefined;\n\n const results = [keyValue]\n for (let i = 0; i < this.componentMaps.length; i++) {\n results.push(this.componentMaps[i].get(entityId));\n }\n\n return results\n }\n\n /**\n * Returns the count of entities in the query\n */\n get entityCount() {\n return this.keyMap.size\n }\n\n /**\n * Destroys all entities in the query\n * \n * Returns the destroyed count\n * @example\n * const destroyedCount = query.destroyEntities()\n */\n destroyEntities(): number {\n return this.ecs.destroyEntity(...this.keyMap.keys())\n }\n\n /**\n * Returns a [KeyComponent, ...RelatedComponents] iterator\n */\n values(): Iterator<[TKey, ...TRelated]> {\n const keyMap = this.keyMap;\n const componentMaps = this.componentMaps;\n let keysIterator = keyMap.keys();\n\n return {\n next(): IteratorResult<[TKey, ...TRelated]> {\n const key = keysIterator.next();\n if (key.done) return { value: <any>undefined, done: true };\n\n const entityId = key.value;\n const keyComponent = keyMap.get(entityId);\n\n // append the related components\n const value = [keyComponent];\n for (let i = 0; i < componentMaps.length; i++) {\n const map = componentMaps[i];\n value.push(map.get(entityId));\n }\n\n return { value: value as any, done: false };\n },\n reset() { keysIterator = keyMap.keys(); },\n [Symbol.iterator]() { return this; },\n };\n }\n\n /**\n * Returns a [entityId, KeyComponent, ...RelatedComponents] iterator\n */\n [Symbol.iterator]() {\n return new ComponentIterator(this);\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 */\nimport { ComponentClassesMap, ComponentMap } from './component-map.js';\nimport { ComponentNotRegistered, ComponentTypeKeyMissing } from './errors.js';\nimport { ComponentIterator } from './iterator.js';\nimport { ComponentQuery } from './query.js';\nimport {\n ComponentClassesMapKey,\n ComponentMapKey,\n type Component,\n type ComponentClass,\n type ComponentClasses,\n type SingleOrArray\n} from './types.js';\n\n/**\n * Class for storing entities and their relationships\n * @category Maps\n */\nexport class EntityMap {\n /**\n * Registered component classes that contain the component instance data\n */\n public components = new ComponentClassesMap()\n\n private nextId: number = 0\n\n /**\n * Registers component classes with the {@link EntityMap}\n * @throwsError {@link ComponentTypeKeyMissing} when the specified component type is missing a 'name' parameter\n * @example\n * // component class\n * class MyComponent {\n * constructor(x) {\n * this.x = x;\n * }\n * }\n *\n * ecs.register(MyComponent);\n * // or mulitple\n * ecs.register(MyComponent1, MyComponent2);\n */\n register<TComponentClasses extends ComponentClass<any>[]>(...componentClasses: TComponentClasses) {\n for (const componentClass of componentClasses) {\n const componentName = componentClass.name;\n if (componentName === undefined) throw new ComponentTypeKeyMissing()\n\n // create the component map\n const componentDataMap: ComponentMap<any> = new ComponentMap();\n this.components.set(componentName, componentDataMap);\n }\n\n // chain\n return this;\n }\n\n /**\n * Gets a component class map\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * const positionMap = ecs.getMap(Position)\n * for(const [entityId, position] of positionMap) {\n * position.x += 1\n * }\n */\n getMap<T>(component: ComponentClass<T>): ComponentMap<T> | undefined {\n const map = this.components.get(component.name);\n if (map === undefined) throw new ComponentNotRegistered(component.name)\n return map\n }\n\n /**\n * Returns all components for the first entity by component\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * // return the first entity\n * const playerEntity = ecs.first(Player) ?? []\n * )\n */\n first(keyComponent: ComponentClass<any>): Component[] | undefined {\n const entityId = this.getMap(keyComponent)?.firstKey();\n if (entityId === undefined) return undefined;\n\n return this.get(entityId);\n }\n\n /**\n * Gets the first entity entry for a component class\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * // return the first entry\n * const [entityId, player] = ecs.firstEntry(Player) ?? []\n * \n * // or return multiple related components in addition to the first entry\n * const [entityId, player, position, direction] = ecs.firstEntry(\n * Player,\n * Position,\n * Direction\n * )\n */\n firstEntry<TKey, TRelated extends any[]>(\n keyComponent: ComponentClass<TKey>,\n ...components: ComponentClasses<TRelated>\n ): [number, TKey, ...TRelated] | undefined;\n firstEntry(keyComponent: ComponentClass<any>, ...components: ComponentClass<any>[]) {\n if (components.length === 0) return this.getMap(keyComponent)?.firstEntry()\n\n return this.firstKey(keyComponent, keyComponent, ...components);\n }\n\n /**\n * Gets the first entity id for a component class \n * and optionally any related component data\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n * @example\n * // return the first entity id\n * const entityId = ecs.firstKey(Player)\n * \n * // or return multiple related component in addition to entity id\n * const [entityId, position, direction] = ecs.firstKey(\n * Player,\n * Position,\n * Direction\n * ) ?? []\n */\n firstKey<TKey, TRelated extends any[]>(\n keyComponent: TKey,\n ...components: ComponentClasses<TRelated>\n ): SingleOrArray<[number, ...TRelated]> | undefined;\n firstKey(keyComponent: ComponentClass<any>, ...components: ComponentClass<any>[]) {\n const entityId = this.getMap(keyComponent)?.firstKey();\n\n // single component key\n if (arguments.length === 1) return entityId;\n if (entityId === undefined) return undefined;\n\n // attach related component values\n return [entityId, ...components.map(x => this.getEntity(entityId, x))];\n }\n\n /**\n * Gets the first entity component data for a component class\n * and optionally any related component data\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n * @example\n * // return the first component value\n * const player = ecs.firstValue(Player)\n * \n * // or multiple related values in addition to the first component\n * const [player, position, direction] = ecs.firstValue(\n * Player,\n * Position,\n * Direction\n * )\n */\n firstValue<TKey, TRelated extends any[]>(\n keyComponent: ComponentClass<TKey>,\n ...components: ComponentClasses<TRelated>\n ): SingleOrArray<[TKey, ...TRelated]> | undefined;\n firstValue(keyComponent: ComponentClass<any>, ...components: ComponentClass<any>[]) {\n // single component\n if (arguments.length === 1) return this.getMap(keyComponent)?.firstValue();\n\n // get the first entry\n const [entityId, keyValue] = this.getMap(keyComponent)?.firstEntry() ?? [];\n if (entityId === undefined) return undefined;\n\n // attach related components\n return [keyValue, ...components.map(x => this.getEntity(entityId, x))]\n }\n\n /**\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered \n */\n private getEntity<T>(entityId: number, component: ComponentClass<T>): T | undefined {\n const map = this.components.get(component.name);\n if (map === undefined) throw new ComponentNotRegistered(component.name)\n\n return map.get(entityId);\n }\n\n /**\n * Gets component values related to an entity id\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n * @example\n * // get one by id\n * const player = ecs.get(entityId, Player)\n * \n * // get multiple by id\n * const [player, position] = ecs.get(entityId, Player, Position) ?? []\n * \n * // get all by id\n * const playerEntity = ecs.get(entityId) ?? []\n */\n get(entityId: number): Component[] | undefined;\n get<T>(entityId: number, component: ComponentClass<T>): T | undefined;\n get<T extends any[]>(entityId: number, ...components: ComponentClasses<T>): SingleOrArray<T> | undefined;\n get(entityId: number, ...components: ComponentClasses<any>): Component | Component[] | undefined {\n // return a single component\n if (components.length === 1) return this.getEntity(entityId, components[0]);\n // return filtered components\n if (components.length > 1) return components.map(x => this.getEntity(entityId, x));\n // return all components\n return [...this.components.values()]\n .filter(v => v.has(entityId))\n .map(v => v.get(entityId));\n }\n\n /**\n * Check if a component exists for an entity\n * @example\n * const exists = ecs.has(entityId, Position)\n */\n has<T>(entityId: number, component: ComponentClass<T>): boolean {\n // get the component map\n const map = this.components.get(component.name);\n if (map === undefined) return false\n\n return map.has(entityId);\n }\n\n /**\n * Checks if all of the specified components exist for an entity\n * @example\n * const hasAll = ecs.hasAll(entityId, Position, Velocity)\n */\n hasAll<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean {\n for (let index = 0; index < components.length; index++) {\n const component = components[index];\n const map = this.components.get(component.name);\n if (map === undefined) return false;\n if (map.has(entityId) === false) return false;\n }\n return true\n }\n\n /**\n * Checks if any of the specified components exist for an entity\n * @example\n * const hasAny = ecs.hasAny(entityId, Position, Velocity)\n */\n hasAny<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean {\n for (let index = 0; index < components.length; index++) {\n const component = components[index];\n const map = this.components.get(component.name);\n if (map === undefined) continue;\n if (map.has(entityId)) return true;\n }\n return false\n }\n\n private setEntity<T extends Component>(entityId: number, componentData: T): T {\n // get the component map\n const map = this.components.get(componentData.constructor.name);\n if (map === undefined) throw new ComponentNotRegistered(componentData.constructor.name)\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 * @example\n * // set one\n * const player = ecs.set(entityId, new Player());\n * \n * // or set multiple\n * const [player, position] = ecs.set(\n * entityId,\n * new Player(),\n * new Position()\n * );\n */\n set<T extends Component>(entityId: number, component: T): T;\n set<T extends Component[]>(entityId: number, ...components: T): T;\n set(entityId: number, ...components: Component[]): Component | Component[] {\n if (components.length > 1) return components.map(x => this.setEntity(entityId, x))\n\n // set and return a single component\n return this.setEntity(entityId, components[0])\n }\n\n /**\n * Removes the specified component(s) from an entity\n * @example\n * ecs.remove(entityId, Position);\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 * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * ecs.removeByKey(entityId, \"Position\");\n */\n removeByKey(entityId: number, componentName: string) {\n // get the entity map\n const entityMap = this.components.get(componentName);\n\n // ensure the map is defined\n if (entityMap === undefined) throw new ComponentNotRegistered(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 all components from an entity\n * @example\n * const destroyedCount = ecs.destroyEntity(entityId1)\n * \n * // or multiple\n * const destroyedCount = ecs.destroyEntity(entityId1, entityId2)\n */\n destroyEntity(...entityIds: number[]): number {\n let deletedCount = 0;\n for (let index = 0; index < entityIds.length; index++) {\n const entityId = entityIds[index];\n for (const map of this.components.values()) {\n if (map.has(entityId)) {\n map.delete(entityId);\n deletedCount++;\n }\n }\n }\n return deletedCount;\n }\n\n // TODO create id generator\n /**\n * Creates a new entity id for the EntityMap\n * @example\n * const newEntityId = ecs.getNextId()\n * ecs.set(newEntityId, new Player())\n */\n getNextId(): number {\n this.nextId++;\n return this.nextId;\n }\n\n /**\n * Clears all registered components\n */\n clear() {\n this.components.clear();\n this.nextId = 0\n return this;\n }\n\n /**\n * Clears all component data\n */\n clearComponents() {\n this.components.forEach(x => x.clear())\n this.nextId = 0\n return this;\n }\n\n /**\n * Iterates over each component value that is related to the key component\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n * @example\n * // iterate each component value that is related to the Player entity\n * const iterator = ecs.iterator(Player, Position)\n * \n * for(const [playerId, player, position] of iterator) { }\n * \n * // you can also declare the type of iterator before it's assigned\n * let iterator: IComponentIterator<[Player, Position]>\n * \n * // then with late bound assignment (keeping the iterator intellisense)\n * iterator = ecs.iterator(Player, Position)\n * \n * for(const [playerId, player, position] of iterator) {\n * const moving = player.isMoving\n * }\n */\n iterator<TKey, TRelated extends any[]>(\n keyComponent: ComponentClass<TKey>,\n ...components: ComponentClasses<TRelated>\n ) {\n return new ComponentIterator(new ComponentQuery(this, keyComponent, ...components));\n }\n\n /**\n * Creates a query that can be stored and reused\n * \n * @param keyComponent\n * @param components\n * @example\n * const query = ecs.query(Player, Position)\n * \n * // get the first entry\n * const [playerId, player, position] = query.firstEntry() ?? []\n * \n * // get the first key\n * const [playerId, position] = query.firstKey() ?? []\n * \n * // get the first value\n * const [player, position] = query.firstValue() ?? []\n * \n * // iterate\n * for (const [playerId, player, position] of query) {\n * \n * }\n */\n query<TKey, TRelated extends any[]>(\n keyComponent: ComponentClass<TKey>,\n ...components: ComponentClasses<TRelated>\n ) {\n return new ComponentQuery(this, keyComponent, ...components)\n }\n\n /**\n * Prints all component maps in a tabular format to the console.\n * \n * Additional generated columns are:\n * \n * 'Entity.Key' is the entity id\n * \n * 'Entity.Type' is the component name\n * \n * @param components - Optional. Filters the output to only include specific components.\n * @param properties - Optional. Specifies which property columns to display in the tables.\n */\n printTable(components?: string[]): this;\n printTable(components?: string[], properties?: string[]): this;\n printTable() {\n const componentsFilter = arguments[0] ?? [];\n const propertiesFilter = arguments[1] ?? [];\n this.components.forEach((map, key) => {\n if (componentsFilter.length === 0 || componentsFilter.includes(key)) {\n console.table(map.toTable(), propertiesFilter);\n }\n });\n return this;\n }\n\n /**\n * Prints all component data for the specified entity id in a tabular format to the console\n * \n * Additional generated columns are:\n * \n * 'Entity.Type' is the component name\n * \n * @param properties - Optional. Specifies which property columns to display in the tables.\n */\n printEntity(entityId: number, properties: string[] = []) {\n for (const map of this.components.values()) {\n if (map.has(entityId) === false) continue;\n\n const data = map.get(entityId);\n const columns = {\n 'entity.type': data.constructor.name,\n ...data\n };\n console.table({ [entityId]: columns }, properties);\n }\n\n return this;\n }\n\n /**\n * Parse's the JSON and returns an EntityMap object\n * @example\n * const json = JSON.stringfy(ecs);\n * const restoredMap = ecs.parse(json);\n */\n static parse(json: string): EntityMap {\n const restored = JSON.parse(json, function (key: string, value: any) {\n if (value.hasOwnProperty('components')) {\n Reflect.setPrototypeOf(value, EntityMap.prototype);\n return value;\n }\n if (value.hasOwnProperty(ComponentMapKey)) return new ComponentMap(value.iterable);\n if (value.hasOwnProperty(ComponentClassesMapKey)) return new ComponentClassesMap(value.iterable);\n return this[key];\n });\n return restored;\n }\n\n /**\n * A tracing method used for debugging.\n * Intercepts all functions specified and logs each call to the console.\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 * @showCategories\n * @module ecsjs\n */\nimport { EntityMap } from './entity-map.js'\nexport { ComponentClassesMap, ComponentMap } from './component-map.js'\nexport { EntityMap } from './entity-map.js'\nexport type { ComponentNotRegistered, ComponentTypeKeyMissing } from './errors.js'\nexport { ComponentIterator } from './iterator.js'\nexport { ComponentQuery } from './query.js'\nexport type { ComponentClass, IComponentIterator } from './types.js'\n\n/**\n * Global instance of an {@link EntityMap}\n * \n * See the [cheat sheet](https://gitlab.com/ecsjs/ecs/-/blob/master/docs/cheat-sheet.md) for more examples\n * @category Constants\n * @example\n * \n * // register component(s)\n * ecs.register(Player, Position)\n * \n * // create an entity\n * const [player, position] = ecs.set(ecs.getNextId(), new Player(), new Position(10, 40))\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": ["ComponentMapKey", "ComponentClassesMapKey", "ComponentMap", "entries", "i", "entry", "entityId", "component", "index", "lastIdx", "lastEntity", "callback", "entities", "instances", "result", "ComponentMapKey", "table", "key", "value", "entity", "meta", "properties", "ComponentClassesMap", "ComponentClassesMapKey", "ComponentTypeKeyMissing", "ComponentNotRegistered", "componentName", "ComponentIterator", "query", "entry", "value", "done", "entityId", "i", "map", "ComponentQuery", "ecs", "components", "i", "entityId", "entryValue", "results", "keyValue", "keyMap", "componentMaps", "keysIterator", "key", "value", "map", "ComponentIterator", "EntityMap", "_EntityMap", "ComponentClassesMap", "componentClasses", "componentClass", "componentName", "ComponentTypeKeyMissing", "componentDataMap", "ComponentMap", "component", "map", "ComponentNotRegistered", "keyComponent", "entityId", "components", "x", "keyValue", "v", "index", "componentData", "entityMap", "entityIds", "deletedCount", "ComponentIterator", "ComponentQuery", "componentsFilter", "propertiesFilter", "key", "properties", "data", "columns", "json", "value", "ComponentMapKey", "ComponentClassesMapKey", "funcFilter", "traceHandler", "target", "propKey", "targetValue", "args", "ecs", "EntityMap"]
3
+ "sources": ["../src/types.ts", "../src/utils.ts", "../src/component-classes.ts", "../src/component-map.ts", "../src/errors.ts", "../src/iterator.ts", "../src/query.ts", "../src/entity-map.ts", "../src/ecs.ts"],
4
+ "sourcesContent": ["export const ComponentMapKey = \"ComponentMap\"\nexport const ComponentClassesMapKey = \"ComponentClassesMap\"\n\nexport type KeyCollection<T> = { [key: string]: T }\n\nexport interface Component { }\n\n/**\n * @category Types\n * @example\n * \n * class PositionComponent {\n * constructor(x, y) {\n * this.x = x;\n * this.y = y;\n * }\n * }\n */\nexport type ComponentClass<ComponentInstance> = (new (...args: any[]) => ComponentInstance) & {\n // static property\n hashId?: number;\n};\n\n/**\n* Used for infering generic type spread for classes\n*/\nexport type ComponentClasses<T extends Component[]> =\n { [Index in keyof T]: ComponentClass<T[Index]> }\n\nexport type SingleOrArray<T extends any[]> =\n // return a single variadic item when only 1 item is specified\n T['length'] extends 1 ? T[0]\n // otherwise return an array of variadic types\n : { [Index in keyof T]: T[Index] }\n\nexport type IteratorResult<T> = {\n done: boolean,\n value: T\n}\n\nexport type Iterator<T> = {\n next: () => IteratorResult<T>\n reset: () => void\n [Symbol.iterator]: () => Iterator<T>\n}\n\n/**\n * allow late bound assignment type for intellisense\n * @category Types\n * @example\n * \n * let someIterator: IComponentIterator<[Player, Position]>\n * \n * // assignment made somewhere else in the code\n * const [player, position] = someIterator(Player, Position) ?? []\n * position?.x = 123 // position will have intellisense\n */\nexport type IComponentIterator<T extends Component[]>\n = Iterator<ComponentClasses<[number, ...T]>>", "export function hashString(str: string) {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash |= 0; // Convert to 32bit\n }\n return hash;\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 */\nimport type { ComponentMap } from './component-map.js';\nimport {\n ComponentClassesMapKey,\n type ComponentClass,\n type Iterator,\n type IteratorResult\n} from './types.js';\nimport { hashString } from './utils.js';\n\n/**\n * Component class map for storing registered component maps\n * @category Maps\n */\nexport class ComponentClassesMap {\n\n private hashIdToName: Map<number, string> = new Map<number, string>()\n private hashIdToIndex = new Map<number, number>();\n private indexToHashId: number[] = [];\n private maps: ComponentMap<any>[] = [];\n\n constructor(entries?: readonly (readonly [number, ComponentMap<any>])[] | null) {\n if (entries) {\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n this.setByHashId(entry[0], entry[1]);\n }\n }\n }\n\n /**\n * The number of registered component maps\n */\n get size() {\n return this.maps.length;\n }\n\n /**\n * Clears all maps and internal indices while preserving array references\n */\n clear(): void {\n this.maps.length = 0;\n this.indexToHashId.length = 0;\n this.hashIdToIndex.clear();\n }\n\n /**\n * Retrieves a component map using the static hashId of a component class\n */\n get<T>(componentClass: ComponentClass<T>): ComponentMap<T> | undefined {\n const index = this.hashIdToIndex.get(componentClass.hashId!);\n return index !== undefined ? this.maps[index] : undefined;\n }\n\n /**\n * Registers a component map. Automatically generates a hashId from the class name if missing\n */\n set<T>(componentClass: ComponentClass<T>, map: ComponentMap<T>): this {\n if (componentClass.hashId === undefined) {\n componentClass.hashId = hashString(componentClass.name);\n }\n\n this.hashIdToName.set(componentClass.hashId, componentClass.name);\n return this.setByHashId(componentClass.hashId!, map);\n }\n\n /**\n * Maps a specific numeric hash id to a component map instance.\n */\n setByHashId(hash: number, map: ComponentMap<any>): this {\n const existingIndex = this.hashIdToIndex.get(hash);\n\n if (existingIndex !== undefined) {\n this.maps[existingIndex] = map;\n } else {\n this.hashIdToIndex.set(hash, this.maps.length);\n this.indexToHashId.push(hash);\n this.maps.push(map);\n }\n\n return this;\n }\n\n /**\n * Removes a component map and re-orders internal storage to maintain density\n */\n delete(componentClass: ComponentClass<any>): boolean {\n const hashId = componentClass.hashId!;\n const index = this.hashIdToIndex.get(hashId);\n if (index === undefined) return false;\n\n const lastIndex = this.maps.length - 1;\n const lastHash = this.indexToHashId[lastIndex];\n\n // Swap\n this.maps[index] = this.maps[lastIndex];\n this.indexToHashId[index] = lastHash;\n\n // Update map pointer\n this.hashIdToIndex.set(lastHash, index);\n\n // Pop\n this.maps.pop();\n this.indexToHashId.pop();\n this.hashIdToIndex.delete(hashId);\n return true;\n }\n\n /**\n * Executes a callback for every map, providing the instance and its registered name\n */\n forEach(callback: (value: ComponentMap<any>, name: string) => void) {\n for (let i = 0; i < this.maps.length; i++) {\n callback(this.maps[i], this.hashIdToName.get(this.indexToHashId[i])!);\n }\n }\n\n /**\n * Returns an iterator of all component map instances \n */\n values(): ArrayIterator<ComponentMap<any>> { return this.maps.values() }\n\n /**\n * Returns an iterator of [hashId, componentMap] pairs\n */\n entries(): Iterator<[number, ComponentMap<any>]> {\n let index = 0;\n const instances = this.maps;\n const hashes = this.indexToHashId;\n\n return {\n next(): IteratorResult<[number, ComponentMap<any>]> {\n if (index < instances.length) {\n const value: [number, ComponentMap<any>] = [hashes[index], instances[index]];\n index++;\n return { value, done: false };\n }\n return { value: undefined as any, done: true };\n },\n reset() { index = 0; },\n [Symbol.iterator]() { return this; }\n };\n }\n\n /**\n * Called when using JSON.stringify\n */\n toJSON() {\n return { [ComponentClassesMapKey]: 1, iterable: [...this.entries()] };\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 */\nimport {\n ComponentMapKey,\n type Iterator,\n type IteratorResult,\n type KeyCollection\n} from './types.js';\n\n/**\n * Component map for storing entity ids and related component data\n * @category Maps\n */\nexport class ComponentMap<TComponentInstance> implements Iterable<[number, TComponentInstance]> {\n\n private indices: number[] = [];\n\n private entities: number[] = [];\n\n private instances: TComponentInstance[] = [];\n\n constructor(entries?: readonly (readonly [number, TComponentInstance])[] | null) {\n if (entries) {\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n this.set(entry[0], entry[1]);\n }\n }\n }\n\n get size() {\n return this.instances.length;\n }\n\n clear() {\n this.indices = [];\n this.entities.length = 0;\n this.instances.length = 0;\n }\n\n set(entityId: number, component: TComponentInstance) {\n if (this.has(entityId)) {\n this.instances[this.indices[entityId]] = component;\n return;\n }\n this.indices[entityId] = this.instances.length;\n this.entities.push(entityId);\n this.instances.push(component);\n }\n\n get(entityId: number) {\n const index = this.indices[entityId];\n return index !== undefined && this.entities[index] === entityId\n ? this.instances[index]\n : undefined;\n }\n\n delete(entityId: number) {\n const index = this.indices[entityId];\n if (index === undefined || index === -1 || this.entities[index] !== entityId) return false;\n\n // swap and pop with last element to keep dense\n const lastIdx = this.instances.length - 1;\n const lastEntity = this.entities[lastIdx];\n this.instances[index] = this.instances[lastIdx];\n this.entities[index] = lastEntity;\n this.indices[lastEntity] = index;\n this.instances.pop();\n this.entities.pop();\n\n // invalidate index\n this.indices[entityId] = -1;\n\n return true;\n }\n\n has(entityId: number) {\n const index = this.indices[entityId];\n return index !== undefined && index !== -1 && this.entities[index] === entityId;\n }\n\n /**\n * Executes a callback for every map, providing the instance and its entity id\n */\n forEach(callback: (value: TComponentInstance, key: number) => void) {\n for (let i = 0; i < this.instances.length; i++) {\n callback(this.instances[i], this.entities[i]);\n }\n }\n\n /**\n * Returns the first entity entry\n */\n firstEntry(): [entityId: number, value: TComponentInstance] | undefined {\n return this.entities.length === 0\n ? undefined\n : [this.entities[0], this.instances[0]];\n }\n\n /**\n * Returns the first entity id\n */\n firstKey(): number | undefined {\n return this.entities.length === 0\n ? undefined\n : this.entities[0];\n }\n\n /**\n * Returns the first entity value\n */\n firstValue(): TComponentInstance | undefined {\n return this.instances.length === 0\n ? undefined\n : this.instances[0];\n }\n\n [Symbol.iterator](): Iterator<[number, TComponentInstance]> {\n return this.entries();\n }\n\n /**\n * Returns an iterator of all entity ids \n */\n keys(): ArrayIterator<number> {\n return this.entities.values();\n }\n\n /**\n * Returns an iterator of all component instances \n */\n values(): ArrayIterator<TComponentInstance> {\n return this.instances.values();\n }\n\n /**\n * Returns an iterator of [entityId, componentInstance] pairs\n */\n entries(): Iterator<[number, TComponentInstance]> {\n let index = 0;\n const entities = this.entities;\n const instances = this.instances;\n\n return {\n next(): IteratorResult<[number, TComponentInstance]> {\n if (index < instances.length) {\n const result: IteratorResult<[number, TComponentInstance]> = {\n value: [entities[index], instances[index]],\n done: false\n };\n index++;\n return result;\n }\n return { value: <any>undefined, done: true };\n },\n reset() {\n index = 0;\n },\n [Symbol.iterator]() {\n return this;\n },\n };\n }\n\n /**\n * Called when using JSON.stringify\n */\n toJSON() {\n return { [ComponentMapKey]: 1, iterable: [...this.entries()] };\n }\n\n toTable(): any[] {\n const table = []\n for (const [key, value] of this.entries()) {\n const entity = value as { new(): TComponentInstance };\n const meta: KeyCollection<any> = {};\n meta[\"entity.key\"] = key;\n meta[\"entity.type\"] = entity.constructor.name;\n table.push({ ...meta, ...entity });\n }\n return table;\n }\n\n /**\n * Prints entity data in a tabular format to the console\n */\n printTable(properties: string[] = []): void {\n console.table(this.toTable(), properties);\n }\n\n}", "/**\n * Thrown when trying to register a component that is missing a 'name' parameter\n * @category Errors\n */\nexport class ComponentTypeKeyMissing extends Error {\n constructor() {\n super(`Component type is missing the 'name' parameter. i.e. a constructor name`);\n }\n}\n\n/**\n * Thrown when trying to access a component that has not been registered\n * @category Errors\n */\nexport class ComponentNotRegistered extends Error {\n constructor(public componentName: string) {\n super(`Component map does not exist for '${componentName}'`);\n }\n}", "import type { ComponentMap } from './component-map.js';\nimport type { ComponentQuery } from './query.js';\nimport type { IteratorResult } from './types.js';\n\n/**\n * @category Iterators\n * @example\n * // construct an instance\n * const iterator = new ComponentIterator(new ComponentQuery(entityMap, Player, Position))\n * \n * // iterate each component value that is related to the Player\n * for(const [entityId, player, position] of iterator) { }\n * \n * // you can also reset the iterator back to the start\n * // without having to create a new ComponentIterator instance\n * iterator.reset()\n * for(const [entityId, player, position] of iterator) { }\n */\nexport class ComponentIterator<TKey, TRelated extends any[]> {\n private keyMap: ComponentMap<TKey>;\n private componentMaps: ComponentMap<any>[] = [];\n // iteration state\n private entries: Iterator<[number, TKey]>;\n\n constructor(query: ComponentQuery<TKey, TRelated>) {\n // @ts-ignore internal private var accessor\n this.keyMap = query.keyMap\n // @ts-ignore internal private var accessor\n this.componentMaps = query.componentMaps\n this.entries = this.keyMap.entries();\n }\n\n /**\n * gets the next iterator value\n */\n next(): IteratorResult<[number, TKey, ...TRelated]> {\n const entry = this.entries.next();\n const { value, done } = entry;\n if (done) return { value, done };\n\n const entityId = value[0];\n\n // append the related components\n for (let i = 0; i < this.componentMaps.length; i++) {\n const map = this.componentMaps[i];\n value.push(map.get(entityId));\n }\n\n return { value: value as any, done: false };\n }\n\n /**\n * resets the iterator back to the first entry\n */\n reset() {\n this.entries = this.keyMap.entries();\n }\n\n [Symbol.iterator]() { return this; }\n\n}", "import type { ComponentMap } from './component-map.js';\nimport type { EntityMap } from './entity-map.js';\nimport { ComponentIterator } from './iterator.js';\nimport type { ComponentClass, ComponentClasses, Iterator, IteratorResult, SingleOrArray } from './types.js';\n\n/**\n * @category Queries\n * @example\n * const query = ecs.query(Player, Position)\n * \n * // get the first entry\n * const [playerId, player, position] = query.firstEntry() ?? []\n * \n * // get the first key\n * const [playerId, position] = query.firstKey() ?? []\n * \n * // get the first value\n * const [player, position] = query.firstValue() ?? []\n * \n * // iterate\n * for (const [playerId, player, position] of query) {\n * \n * }\n */\nexport class ComponentQuery<TKey, TRelated extends any[]> {\n private keyMap: ComponentMap<TKey>\n private componentMaps: ComponentMap<any>[] = []\n\n /**\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n */\n constructor(\n public ecs: EntityMap,\n ...components: [ComponentClass<TKey>, ...ComponentClasses<TRelated>]\n ) {\n this.keyMap = this.ecs.getMap(components[0])!;\n for (let i = 1; i < components.length; i++) {\n this.componentMaps.push(this.ecs.getMap(components[i])!)\n }\n }\n\n /**\n * Returns the first entity entry\n * \n * Optionally returns related components specified in the query constructor\n */\n firstEntry(): [number, TKey, ...TRelated] | undefined;\n firstEntry() {\n if (this.componentMaps.length === 0) return this.keyMap.firstEntry()\n\n const [entityId, entryValue] = this.keyMap.firstEntry() ?? []\n if (entityId === undefined) return undefined;\n\n const results: any[] = [entityId, entryValue]\n for (let i = 0; i < this.componentMaps.length; i++) {\n results.push(this.componentMaps[i].get(entityId));\n }\n\n return results\n }\n\n /**\n * Returns the first entity id\n * \n * Optionally returns related components specified in the query constructor\n */\n firstKey(): SingleOrArray<[number, ...TRelated]> | undefined;\n firstKey() {\n const entityId = this.keyMap.firstKey()\n if (this.componentMaps.length === 0) return entityId;\n if (entityId === undefined) return undefined;\n\n const results: any[] = [entityId]\n for (let i = 0; i < this.componentMaps.length; i++) {\n results.push(this.componentMaps[i].get(entityId));\n }\n\n return results\n }\n\n /**\n * Returns the first value\n * \n * Optionally returns related components specified in the query constructor\n */\n firstValue(): SingleOrArray<[TKey, ...TRelated]> | undefined;\n firstValue() {\n if (this.componentMaps.length === 0) return this.keyMap.firstValue()\n\n const [entityId, keyValue] = this.keyMap.firstEntry() ?? []\n if (entityId === undefined) return undefined;\n\n const results = [keyValue]\n for (let i = 0; i < this.componentMaps.length; i++) {\n results.push(this.componentMaps[i].get(entityId));\n }\n\n return results\n }\n\n /**\n * Returns the count of entities in the query\n */\n get entityCount() {\n return this.keyMap.size\n }\n\n /**\n * Destroys all entities in the query\n * \n * Returns the destroyed count\n * @example\n * const destroyedCount = query.destroyEntities()\n */\n destroyEntities(): number {\n return this.ecs.destroyEntity(...this.keyMap.keys())\n }\n\n /**\n * Returns an iterator of all the entityIds\n */\n keys(): ArrayIterator<number> { return this.keyMap.keys() }\n\n /**\n * Returns an iterator of all ComponentMap instances stored in this container\n */\n values(): Iterator<[TKey, ...TRelated]> {\n const keyMap = this.keyMap;\n const componentMaps = this.componentMaps;\n let keysIterator = keyMap.keys();\n\n return {\n next(): IteratorResult<[TKey, ...TRelated]> {\n const key = keysIterator.next();\n if (key.done) return { value: <any>undefined, done: true };\n\n const entityId = key.value;\n const keyComponent = keyMap.get(entityId);\n\n // append the related components\n const value = [keyComponent];\n for (let i = 0; i < componentMaps.length; i++) {\n const map = componentMaps[i];\n value.push(map.get(entityId));\n }\n\n return { value: value as any, done: false };\n },\n reset() { keysIterator = keyMap.keys(); },\n [Symbol.iterator]() { return this; },\n };\n }\n\n /**\n * Returns an iterator that flattens all internal maps into [entityId, KeyComponent, ...RelatedComponents]\n */\n entries() { return this[Symbol.iterator](); }\n\n /**\n * Returns an iterator that flattens all internal maps into [entityId, KeyComponent, ...RelatedComponents]\n */\n [Symbol.iterator]() {\n return new ComponentIterator(this);\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 */\nimport { ComponentClassesMap } from './component-classes.js';\nimport { ComponentMap } from './component-map.js';\nimport { ComponentNotRegistered, ComponentTypeKeyMissing } from './errors.js';\nimport { ComponentIterator } from './iterator.js';\nimport { ComponentQuery } from './query.js';\nimport {\n ComponentClassesMapKey,\n ComponentMapKey,\n type Component,\n type ComponentClass,\n type ComponentClasses,\n type SingleOrArray\n} from './types.js';\n\n/**\n * Class for storing entities and their relationships\n * @category Maps\n */\nexport class EntityMap {\n /**\n * Registered component classes that contain the component instance data\n */\n public components = new ComponentClassesMap()\n\n private nextId: number = 0\n\n /**\n * Registers component classes with the {@link EntityMap}\n * @throwsError {@link ComponentTypeKeyMissing} when the specified component type is missing a 'name' parameter\n * @example\n * // component class\n * class MyComponent {\n * constructor(x) {\n * this.x = x;\n * }\n * }\n *\n * ecs.register(MyComponent);\n * // or mulitple\n * ecs.register(MyComponent1, MyComponent2);\n */\n register<TComponentClasses extends ComponentClass<any>[]>(...componentClasses: TComponentClasses) {\n for (const componentClass of componentClasses) {\n const componentName = componentClass.name;\n if (componentName === undefined) throw new ComponentTypeKeyMissing();\n\n // create the component map\n // const componentDataMap: ComponentMap<any> = new ComponentMap();\n this.components.set(componentClass, new ComponentMap());\n }\n\n // chain\n return this;\n }\n\n /**\n * Gets a component class map\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * const positionMap = ecs.getMap(Position)\n * for(const [entityId, position] of positionMap) {\n * position.x += 1\n * }\n */\n getMap<T>(component: ComponentClass<T>): ComponentMap<T> | undefined {\n const map = this.components.get(component);\n if (map === undefined) throw new ComponentNotRegistered(component.name)\n return map\n }\n\n /**\n * Returns all components for the first entity by component\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * // return the first entity\n * const playerEntity = ecs.first(Player) ?? []\n * )\n */\n first(keyComponent: ComponentClass<any>): Component[] | undefined {\n const entityId = this.getMap(keyComponent)?.firstKey();\n if (entityId === undefined) return undefined;\n\n return this.get(entityId);\n }\n\n /**\n * Gets the first entity entry for a component class\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * // return the first entry\n * const [entityId, player] = ecs.firstEntry(Player) ?? []\n * \n * // or return multiple related components in addition to the first entry\n * const [entityId, player, position, direction] = ecs.firstEntry(\n * Player,\n * Position,\n * Direction\n * )\n */\n firstEntry<TKey, TRelated extends any[]>(\n keyComponent: ComponentClass<TKey>,\n ...components: ComponentClasses<TRelated>\n ): [number, TKey, ...TRelated] | undefined;\n firstEntry(keyComponent: ComponentClass<any>, ...components: ComponentClass<any>[]) {\n if (components.length === 0) return this.getMap(keyComponent)?.firstEntry()\n\n return this.firstKey(keyComponent, keyComponent, ...components);\n }\n\n /**\n * Gets the first entity id for a component class \n * and optionally any related component data\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n * @example\n * // return the first entity id\n * const entityId = ecs.firstKey(Player)\n * \n * // or return multiple related component in addition to entity id\n * const [entityId, position, direction] = ecs.firstKey(\n * Player,\n * Position,\n * Direction\n * ) ?? []\n */\n firstKey<TKey, TRelated extends any[]>(\n keyComponent: TKey,\n ...components: ComponentClasses<TRelated>\n ): SingleOrArray<[number, ...TRelated]> | undefined;\n firstKey(keyComponent: ComponentClass<any>, ...components: ComponentClass<any>[]) {\n const entityId = this.getMap(keyComponent)?.firstKey();\n\n // single component key\n if (arguments.length === 1) return entityId;\n if (entityId === undefined) return undefined;\n\n // attach related component values\n return [entityId, ...components.map(x => this.getEntity(entityId, x))];\n }\n\n /**\n * Gets the first entity component data for a component class\n * and optionally any related component data\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n * @example\n * // return the first component value\n * const player = ecs.firstValue(Player)\n * \n * // or multiple related values in addition to the first component\n * const [player, position, direction] = ecs.firstValue(\n * Player,\n * Position,\n * Direction\n * )\n */\n firstValue<TKey, TRelated extends any[]>(\n keyComponent: ComponentClass<TKey>,\n ...components: ComponentClasses<TRelated>\n ): SingleOrArray<[TKey, ...TRelated]> | undefined;\n firstValue(keyComponent: ComponentClass<any>, ...components: ComponentClass<any>[]) {\n // single component\n if (arguments.length === 1) return this.getMap(keyComponent)?.firstValue();\n\n // get the first entry\n const [entityId, keyValue] = this.getMap(keyComponent)?.firstEntry() ?? [];\n if (entityId === undefined) return undefined;\n\n // attach related components\n return [keyValue, ...components.map(x => this.getEntity(entityId, x))]\n }\n\n /**\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered \n */\n private getEntity<T>(entityId: number, component: ComponentClass<T>): T | undefined {\n const map = this.components.get(component);\n if (map === undefined) throw new ComponentNotRegistered(component.name)\n\n return map.get(entityId);\n }\n\n /**\n * Gets component values related to an entity id\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n * @example\n * // get one by id\n * const player = ecs.get(entityId, Player)\n * \n * // get multiple by id\n * const [player, position] = ecs.get(entityId, Player, Position) ?? []\n * \n * // get all by id\n * const playerEntity = ecs.get(entityId) ?? []\n */\n get(entityId: number): Component[] | undefined;\n get<T>(entityId: number, component: ComponentClass<T>): T | undefined;\n get<T extends any[]>(entityId: number, ...components: ComponentClasses<T>): SingleOrArray<T> | undefined;\n get(entityId: number, ...components: ComponentClasses<any>): Component | Component[] | undefined {\n // return a single component\n if (components.length === 1) return this.getEntity(entityId, components[0]);\n // return filtered components\n if (components.length > 1) return components.map(x => this.getEntity(entityId, x));\n // return all components\n return [...this.components.values()]\n .filter(v => v.has(entityId))\n .map(v => v.get(entityId));\n }\n\n /**\n * Check if a component exists for an entity\n * @example\n * const exists = ecs.has(entityId, Position)\n */\n has<T>(entityId: number, component: ComponentClass<T>): boolean {\n // get the component map\n const map = this.components.get(component);\n if (map === undefined) return false\n\n return map.has(entityId);\n }\n\n /**\n * Checks if all of the specified components exist for an entity\n * @example\n * const hasAll = ecs.hasAll(entityId, Position, Velocity)\n */\n hasAll<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean {\n for (let index = 0; index < components.length; index++) {\n const component = components[index];\n const map = this.components.get(component);\n if (map === undefined) return false;\n if (map.has(entityId) === false) return false;\n }\n return true\n }\n\n /**\n * Checks if any of the specified components exist for an entity\n * @example\n * const hasAny = ecs.hasAny(entityId, Position, Velocity)\n */\n hasAny<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean {\n for (let index = 0; index < components.length; index++) {\n const component = components[index];\n const map = this.components.get(component);\n if (map === undefined) continue;\n if (map.has(entityId)) return true;\n }\n return false\n }\n\n private setEntity<T extends Component>(entityId: number, componentData: T): T {\n // get the component map\n const map = this.components.get((<ComponentClass<any>>componentData.constructor));\n if (map === undefined) throw new ComponentNotRegistered(componentData.constructor.name)\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 * @example\n * // set one\n * const player = ecs.set(entityId, new Player());\n * \n * // or set multiple\n * const [player, position] = ecs.set(\n * entityId,\n * new Player(),\n * new Position()\n * );\n */\n set<T extends Component>(entityId: number, component: T): T;\n set<T extends Component[]>(entityId: number, ...components: T): T;\n set(entityId: number, ...components: Component[]): Component | Component[] {\n if (components.length > 1) return components.map(x => this.setEntity(entityId, x))\n\n // set and return a single component\n return this.setEntity(entityId, components[0])\n }\n\n /**\n * Removes the specified component(s) from an entity\n * @example\n * ecs.remove(entityId, Position);\n */\n remove<T extends ComponentClass<any>[]>(entityId: number, ...components: T) {\n for (const component of components) {\n this.removeByKey(entityId, component)\n }\n }\n\n /**\n * Removes the specified component from an entity\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * ecs.removeByKey(entityId, \"Position\");\n */\n removeByKey(entityId: number, component: ComponentClass<any>) {\n // get the entity map\n const entityMap = this.components.get(component);\n\n // ensure the map is defined\n if (entityMap === undefined) throw new ComponentNotRegistered(component.name);\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 all components from an entity\n * @example\n * const destroyedCount = ecs.destroyEntity(entityId1)\n * \n * // or multiple\n * const destroyedCount = ecs.destroyEntity(entityId1, entityId2)\n */\n destroyEntity(...entityIds: number[]): number {\n let deletedCount = 0;\n for (let index = 0; index < entityIds.length; index++) {\n const entityId = entityIds[index];\n for (const map of this.components.values()) {\n if (map.has(entityId)) {\n map.delete(entityId);\n deletedCount++;\n }\n }\n }\n return deletedCount;\n }\n\n // TODO create id generator\n /**\n * Creates a new entity id for the EntityMap\n * @example\n * const newEntityId = ecs.getNextId()\n * ecs.set(newEntityId, new Player())\n */\n getNextId(): number {\n this.nextId++;\n return this.nextId;\n }\n\n /**\n * Clears all registered components\n */\n clear() {\n this.components.clear();\n this.nextId = 0\n return this;\n }\n\n /**\n * Clears all component data\n */\n clearComponents() {\n this.components.forEach(x => x.clear())\n this.nextId = 0\n return this;\n }\n\n /**\n * Iterates over each component value that is related to the key component\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n * @example\n * // iterate each component value that is related to the Player entity\n * const iterator = ecs.iterator(Player, Position)\n * \n * for(const [playerId, player, position] of iterator) { }\n * \n * // you can also declare the type of iterator before it's assigned\n * let iterator: IComponentIterator<[Player, Position]>\n * \n * // then with late bound assignment (keeping the iterator intellisense)\n * iterator = ecs.iterator(Player, Position)\n * \n * for(const [playerId, player, position] of iterator) {\n * const moving = player.isMoving\n * }\n */\n iterator<TKey, TRelated extends any[]>(\n keyComponent: ComponentClass<TKey>,\n ...components: ComponentClasses<TRelated>\n ) {\n return new ComponentIterator(new ComponentQuery(this, keyComponent, ...components));\n }\n\n /**\n * Creates a query that can be stored and reused\n * \n * @param keyComponent\n * @param components\n * @example\n * const query = ecs.query(Player, Position)\n * \n * // get the first entry\n * const [playerId, player, position] = query.firstEntry() ?? []\n * \n * // get the first key\n * const [playerId, position] = query.firstKey() ?? []\n * \n * // get the first value\n * const [player, position] = query.firstValue() ?? []\n * \n * // iterate\n * for (const [playerId, player, position] of query) {\n * \n * }\n */\n query<TKey, TRelated extends any[]>(\n keyComponent: ComponentClass<TKey>,\n ...components: ComponentClasses<TRelated>\n ) {\n return new ComponentQuery(this, keyComponent, ...components)\n }\n\n /**\n * Prints all component maps in a tabular format to the console.\n * \n * Additional generated columns are:\n * \n * 'Entity.Key' is the entity id\n * \n * 'Entity.Type' is the component name\n * \n * @param components - Optional. Filters the output to only include specific components.\n * @param properties - Optional. Specifies which property columns to display in the tables.\n */\n printTable(components?: string[]): this;\n printTable(components?: string[], properties?: string[]): this;\n printTable() {\n const componentsFilter = arguments[0] ?? [];\n const propertiesFilter = arguments[1] ?? [];\n this.components.forEach((map, key) => {\n if (componentsFilter.length === 0 || componentsFilter.includes(key)) {\n console.table(map.toTable(), propertiesFilter);\n }\n });\n return this;\n }\n\n /**\n * Prints all component data for the specified entity id in a tabular format to the console\n * \n * Additional generated columns are:\n * \n * 'Entity.Type' is the component name\n * \n * @param properties - Optional. Specifies which property columns to display in the tables.\n */\n printEntity(entityId: number, properties: string[] = []) {\n for (const map of this.components.values()) {\n if (map.has(entityId) === false) continue;\n\n const data = map.get(entityId);\n const columns = {\n 'entity.type': data.constructor.name,\n ...data\n };\n console.table({ [entityId]: columns }, properties);\n }\n\n return this;\n }\n\n /**\n * Parse's the JSON and returns an EntityMap object\n * @example\n * const json = JSON.stringfy(ecs);\n * const restoredMap = ecs.parse(json);\n */\n static parse(json: string): EntityMap {\n const restored = JSON.parse(json, function (key: string, value: any) {\n if (value.hasOwnProperty('components')) {\n Reflect.setPrototypeOf(value, EntityMap.prototype);\n return value;\n }\n if (value.hasOwnProperty(ComponentMapKey)) return new ComponentMap(value.iterable);\n if (value.hasOwnProperty(ComponentClassesMapKey)) return new ComponentClassesMap(value.iterable);\n return this[key];\n });\n return restored;\n }\n\n /**\n * A tracing method used for debugging.\n * Intercepts all functions specified and logs each call to the console.\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 * @showCategories\n * @module ecsjs\n */\nimport { EntityMap } from './entity-map.js'\nexport { ComponentClassesMap } from './component-classes.js'\nexport { ComponentMap } from './component-map.js'\nexport { EntityMap } from './entity-map.js'\nexport type { ComponentNotRegistered, ComponentTypeKeyMissing } from './errors.js'\nexport { ComponentIterator } from './iterator.js'\nexport { ComponentQuery } from './query.js'\nexport type { ComponentClass, IComponentIterator } from './types.js'\n\n/**\n * Global instance of an {@link EntityMap}\n * \n * See the [cheat sheet](https://gitlab.com/ecsjs/ecs/-/blob/master/docs/cheat-sheet.md) for more examples\n * @category Constants\n * @example\n * \n * // register component(s)\n * ecs.register(Player, Position)\n * \n * // create an entity\n * const [player, position] = ecs.set(ecs.getNextId(), new Player(), new Position(10, 40))\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": ["ComponentMapKey", "ComponentClassesMapKey", "hashString", "str", "hash", "i", "char", "ComponentClassesMap", "entries", "i", "entry", "componentClass", "index", "map", "hashString", "hash", "existingIndex", "hashId", "lastIndex", "lastHash", "callback", "instances", "hashes", "value", "ComponentClassesMapKey", "ComponentMap", "entries", "i", "entry", "entityId", "component", "index", "lastIdx", "lastEntity", "callback", "entities", "instances", "result", "ComponentMapKey", "table", "key", "value", "entity", "meta", "properties", "ComponentTypeKeyMissing", "ComponentNotRegistered", "componentName", "ComponentIterator", "query", "entry", "value", "done", "entityId", "i", "map", "ComponentQuery", "ecs", "components", "i", "entityId", "entryValue", "results", "keyValue", "keyMap", "componentMaps", "keysIterator", "key", "value", "map", "ComponentIterator", "EntityMap", "_EntityMap", "ComponentClassesMap", "componentClasses", "componentClass", "ComponentTypeKeyMissing", "ComponentMap", "component", "map", "ComponentNotRegistered", "keyComponent", "entityId", "components", "x", "keyValue", "v", "index", "componentData", "entityMap", "entityIds", "deletedCount", "ComponentIterator", "ComponentQuery", "componentsFilter", "propertiesFilter", "key", "properties", "data", "columns", "json", "value", "ComponentMapKey", "ComponentClassesMapKey", "funcFilter", "traceHandler", "target", "propKey", "targetValue", "args", "ecs", "EntityMap"]
7
7
  }
@@ -0,0 +1,57 @@
1
+ import type { ComponentMap } from './component-map.js';
2
+ import { type ComponentClass, type Iterator } from './types.js';
3
+ /**
4
+ * Component class map for storing registered component maps
5
+ * @category Maps
6
+ */
7
+ export declare class ComponentClassesMap {
8
+ private hashIdToName;
9
+ private hashIdToIndex;
10
+ private indexToHashId;
11
+ private maps;
12
+ constructor(entries?: readonly (readonly [number, ComponentMap<any>])[] | null);
13
+ /**
14
+ * The number of registered component maps
15
+ */
16
+ get size(): number;
17
+ /**
18
+ * Clears all maps and internal indices while preserving array references
19
+ */
20
+ clear(): void;
21
+ /**
22
+ * Retrieves a component map using the static hashId of a component class
23
+ */
24
+ get<T>(componentClass: ComponentClass<T>): ComponentMap<T> | undefined;
25
+ /**
26
+ * Registers a component map. Automatically generates a hashId from the class name if missing
27
+ */
28
+ set<T>(componentClass: ComponentClass<T>, map: ComponentMap<T>): this;
29
+ /**
30
+ * Maps a specific numeric hash id to a component map instance.
31
+ */
32
+ setByHashId(hash: number, map: ComponentMap<any>): this;
33
+ /**
34
+ * Removes a component map and re-orders internal storage to maintain density
35
+ */
36
+ delete(componentClass: ComponentClass<any>): boolean;
37
+ /**
38
+ * Executes a callback for every map, providing the instance and its registered name
39
+ */
40
+ forEach(callback: (value: ComponentMap<any>, name: string) => void): void;
41
+ /**
42
+ * Returns an iterator of all component map instances
43
+ */
44
+ values(): ArrayIterator<ComponentMap<any>>;
45
+ /**
46
+ * Returns an iterator of [hashId, componentMap] pairs
47
+ */
48
+ entries(): Iterator<[number, ComponentMap<any>]>;
49
+ /**
50
+ * Called when using JSON.stringify
51
+ */
52
+ toJSON(): {
53
+ ComponentClassesMap: number;
54
+ iterable: [number, ComponentMap<any>][];
55
+ };
56
+ }
57
+ //# sourceMappingURL=component-classes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-classes.d.ts","sourceRoot":"","sources":["../../../src/component-classes.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,QAAQ,EAEd,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,qBAAa,mBAAmB;IAE9B,OAAO,CAAC,YAAY,CAAiD;IACrE,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,IAAI,CAA2B;gBAE3B,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI;IAS9E;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS;IAKtE;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IASrE;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI;IAcvD;;OAEG;IACH,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,OAAO;IAsBpD;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI;IAMlE;;OAEG;IACH,MAAM,IAAI,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAE1C;;OAEG;IACH,OAAO,IAAI,QAAQ,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IAmBhD;;OAEG;IACH,MAAM;;;;CAIP"}
@@ -14,6 +14,9 @@ export declare class ComponentMap<TComponentInstance> implements Iterable<[numbe
14
14
  get(entityId: number): TComponentInstance | undefined;
15
15
  delete(entityId: number): boolean;
16
16
  has(entityId: number): boolean;
17
+ /**
18
+ * Executes a callback for every map, providing the instance and its entity id
19
+ */
17
20
  forEach(callback: (value: TComponentInstance, key: number) => void): void;
18
21
  /**
19
22
  * Returns the first entity entry
@@ -28,8 +31,17 @@ export declare class ComponentMap<TComponentInstance> implements Iterable<[numbe
28
31
  */
29
32
  firstValue(): TComponentInstance | undefined;
30
33
  [Symbol.iterator](): Iterator<[number, TComponentInstance]>;
34
+ /**
35
+ * Returns an iterator of all entity ids
36
+ */
31
37
  keys(): ArrayIterator<number>;
38
+ /**
39
+ * Returns an iterator of all component instances
40
+ */
32
41
  values(): ArrayIterator<TComponentInstance>;
42
+ /**
43
+ * Returns an iterator of [entityId, componentInstance] pairs
44
+ */
33
45
  entries(): Iterator<[number, TComponentInstance]>;
34
46
  /**
35
47
  * Called when using JSON.stringify
@@ -44,18 +56,4 @@ export declare class ComponentMap<TComponentInstance> implements Iterable<[numbe
44
56
  */
45
57
  printTable(properties?: string[]): void;
46
58
  }
47
- /**
48
- * Component class map for storing registered component maps
49
- * @category Maps
50
- */
51
- export declare class ComponentClassesMap extends Map<string, ComponentMap<any>> {
52
- /**
53
- * Called when using JSON.stringify
54
- */
55
- toJSON(): {
56
- ComponentClassesMap: number;
57
- iterable: [string, ComponentMap<any>][];
58
- };
59
- static get [Symbol.species](): MapConstructor;
60
- }
61
59
  //# sourceMappingURL=component-map.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component-map.d.ts","sourceRoot":"","sources":["../../../src/component-map.ts"],"names":[],"mappings":"AAiBA,OAAO,EAGL,KAAK,QAAQ,EAGd,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,qBAAa,YAAY,CAAC,kBAAkB,CAAE,YAAW,QAAQ,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAE7F,OAAO,CAAC,OAAO,CAAgB;IAE/B,OAAO,CAAC,QAAQ,CAAgB;IAEhC,OAAO,CAAC,SAAS,CAA4B;gBAEjC,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,GAAG,IAAI;IAS/E,IAAI,IAAI,WAEP;IAED,KAAK;IAML,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB;IAUnD,GAAG,CAAC,QAAQ,EAAE,MAAM;IAOpB,MAAM,CAAC,QAAQ,EAAE,MAAM;IAmBvB,GAAG,CAAC,QAAQ,EAAE,MAAM;IAKpB,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;IAMlE;;OAEG;IACH,UAAU,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,CAAC,GAAG,SAAS;IAMvE;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,SAAS;IAM9B;;OAEG;IACH,UAAU,IAAI,kBAAkB,GAAG,SAAS;IAM5C,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAI3D,IAAI,IAAI,aAAa,CAAC,MAAM,CAAC;IAI7B,MAAM,IAAI,aAAa,CAAC,kBAAkB,CAAC;IAI3C,OAAO,IAAI,QAAQ,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IA0BjD;;OAEG;IACH,MAAM;;;;IAIN,OAAO,IAAI,GAAG,EAAE;IAYhB;;OAEG;IACH,UAAU,CAAC,UAAU,GAAE,MAAM,EAAO,GAAG,IAAI;CAI5C;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;IAErE;;OAEG;IACH,MAAM;;;;IAIN,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,mBAE1B;CAEF"}
1
+ {"version":3,"file":"component-map.d.ts","sourceRoot":"","sources":["../../../src/component-map.ts"],"names":[],"mappings":"AAiBA,OAAO,EAEL,KAAK,QAAQ,EAGd,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,qBAAa,YAAY,CAAC,kBAAkB,CAAE,YAAW,QAAQ,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAE7F,OAAO,CAAC,OAAO,CAAgB;IAE/B,OAAO,CAAC,QAAQ,CAAgB;IAEhC,OAAO,CAAC,SAAS,CAA4B;gBAEjC,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,GAAG,IAAI;IAS/E,IAAI,IAAI,WAEP;IAED,KAAK;IAML,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB;IAUnD,GAAG,CAAC,QAAQ,EAAE,MAAM;IAOpB,MAAM,CAAC,QAAQ,EAAE,MAAM;IAmBvB,GAAG,CAAC,QAAQ,EAAE,MAAM;IAKpB;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;IAMlE;;OAEG;IACH,UAAU,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,CAAC,GAAG,SAAS;IAMvE;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,SAAS;IAM9B;;OAEG;IACH,UAAU,IAAI,kBAAkB,GAAG,SAAS;IAM5C,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAI3D;;OAEG;IACH,IAAI,IAAI,aAAa,CAAC,MAAM,CAAC;IAI7B;;OAEG;IACH,MAAM,IAAI,aAAa,CAAC,kBAAkB,CAAC;IAI3C;;OAEG;IACH,OAAO,IAAI,QAAQ,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IA0BjD;;OAEG;IACH,MAAM;;;;IAIN,OAAO,IAAI,GAAG,EAAE;IAYhB;;OAEG;IACH,UAAU,CAAC,UAAU,GAAE,MAAM,EAAO,GAAG,IAAI;CAI5C"}
@@ -4,7 +4,8 @@
4
4
  * @module ecsjs
5
5
  */
6
6
  import { EntityMap } from './entity-map.js';
7
- export { ComponentClassesMap, ComponentMap } from './component-map.js';
7
+ export { ComponentClassesMap } from './component-classes.js';
8
+ export { ComponentMap } from './component-map.js';
8
9
  export { EntityMap } from './entity-map.js';
9
10
  export type { ComponentNotRegistered, ComponentTypeKeyMissing } from './errors.js';
10
11
  export { ComponentIterator } from './iterator.js';
@@ -1 +1 @@
1
- {"version":3,"file":"ecs.d.ts","sourceRoot":"","sources":["../../../src/ecs.ts"],"names":[],"mappings":"AAkBA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,GAAG,WAAkB,CAAA"}
1
+ {"version":3,"file":"ecs.d.ts","sourceRoot":"","sources":["../../../src/ecs.ts"],"names":[],"mappings":"AAkBA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,GAAG,WAAkB,CAAA"}
@@ -1,4 +1,5 @@
1
- import { ComponentClassesMap, ComponentMap } from './component-map.js';
1
+ import { ComponentClassesMap } from './component-classes.js';
2
+ import { ComponentMap } from './component-map.js';
2
3
  import { ComponentIterator } from './iterator.js';
3
4
  import { ComponentQuery } from './query.js';
4
5
  import { type Component, type ComponentClass, type ComponentClasses, type SingleOrArray } from './types.js';
@@ -160,7 +161,7 @@ export declare class EntityMap {
160
161
  * @example
161
162
  * ecs.removeByKey(entityId, "Position");
162
163
  */
163
- removeByKey(entityId: number, componentName: string): boolean;
164
+ removeByKey(entityId: number, component: ComponentClass<any>): boolean;
164
165
  /**
165
166
  * Deletes all components from an entity
166
167
  * @example
@@ -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":"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"}
@@ -24,14 +24,6 @@ export declare class ComponentQuery<TKey, TRelated extends any[]> {
24
24
  ecs: EntityMap;
25
25
  private keyMap;
26
26
  private componentMaps;
27
- /**
28
- * Returns a [entityId] iterator
29
- */
30
- keys: () => ArrayIterator<number>;
31
- /**
32
- * Returns a [entityId, KeyComponent, ...RelatedComponents] iterator
33
- */
34
- entries: () => ComponentIterator<TKey, TRelated>;
35
27
  /**
36
28
  * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
37
29
  */
@@ -67,11 +59,19 @@ export declare class ComponentQuery<TKey, TRelated extends any[]> {
67
59
  */
68
60
  destroyEntities(): number;
69
61
  /**
70
- * Returns a [KeyComponent, ...RelatedComponents] iterator
62
+ * Returns an iterator of all the entityIds
63
+ */
64
+ keys(): ArrayIterator<number>;
65
+ /**
66
+ * Returns an iterator of all ComponentMap instances stored in this container
71
67
  */
72
68
  values(): Iterator<[TKey, ...TRelated]>;
73
69
  /**
74
- * Returns a [entityId, KeyComponent, ...RelatedComponents] iterator
70
+ * Returns an iterator that flattens all internal maps into [entityId, KeyComponent, ...RelatedComponents]
71
+ */
72
+ entries(): ComponentIterator<TKey, TRelated>;
73
+ /**
74
+ * Returns an iterator that flattens all internal maps into [entityId, KeyComponent, ...RelatedComponents]
75
75
  */
76
76
  [Symbol.iterator](): ComponentIterator<TKey, TRelated>;
77
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5G;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,cAAc,CAAC,IAAI,EAAE,QAAQ,SAAS,GAAG,EAAE;IAmB7C,GAAG,EAAE,SAAS;IAlBvB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,aAAa,CAA0B;IAG/C;;OAEG;IACI,IAAI,EAAE,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;IAEzC;;OAEG;IACI,OAAO,EAAE,MAAM,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAExD;;OAEG;gBAEM,GAAG,EAAE,SAAS,EACrB,GAAG,UAAU,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAUtE;;;;OAIG;IACH,UAAU,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,GAAG,SAAS;IAerD;;;;OAIG;IACH,QAAQ,IAAI,aAAa,CAAC,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,SAAS;IAc5D;;;;OAIG;IACH,UAAU,IAAI,aAAa,CAAC,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,SAAS;IAe5D;;OAEG;IACH,IAAI,WAAW,WAEd;IAED;;;;;;MAME;IACF,eAAe,IAAI,MAAM;IAIzB;;OAEG;IACH,MAAM,IAAI,QAAQ,CAAC,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;IA2BvC;;OAEG;IACH,CAAC,MAAM,CAAC,QAAQ,CAAC;CAIlB"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5G;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,cAAc,CAAC,IAAI,EAAE,QAAQ,SAAS,GAAG,EAAE;IAQ7C,GAAG,EAAE,SAAS;IAPvB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,aAAa,CAA0B;IAE/C;;OAEG;gBAEM,GAAG,EAAE,SAAS,EACrB,GAAG,UAAU,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAQtE;;;;OAIG;IACH,UAAU,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,GAAG,SAAS;IAerD;;;;OAIG;IACH,QAAQ,IAAI,aAAa,CAAC,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,SAAS;IAc5D;;;;OAIG;IACH,UAAU,IAAI,aAAa,CAAC,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,SAAS;IAe5D;;OAEG;IACH,IAAI,WAAW,WAEd;IAED;;;;;;MAME;IACF,eAAe,IAAI,MAAM;IAIzB;;OAEG;IACH,IAAI,IAAI,aAAa,CAAC,MAAM,CAAC;IAE7B;;OAEG;IACH,MAAM,IAAI,QAAQ,CAAC,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;IA2BvC;;OAEG;IACH,OAAO;IAEP;;OAEG;IACH,CAAC,MAAM,CAAC,QAAQ,CAAC;CAIlB"}
@@ -16,7 +16,9 @@ export interface Component {
16
16
  * }
17
17
  * }
18
18
  */
19
- export type ComponentClass<ComponentInstance> = new (...args: any[]) => ComponentInstance;
19
+ export type ComponentClass<ComponentInstance> = (new (...args: any[]) => ComponentInstance) & {
20
+ hashId?: number;
21
+ };
20
22
  /**
21
23
  * Used for infering generic type spread for classes
22
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,iBAAiB,CAAA;AAC7C,eAAO,MAAM,sBAAsB,wBAAwB,CAAA;AAE3D,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAA;CAAE,CAAA;AAEnD,MAAM,WAAW,SAAS;CAAI;AAE9B;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,CAAC,iBAAiB,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,iBAAiB,CAAA;AAEzF;;EAEE;AACF,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,SAAS,EAAE,IAChD;KAAG,KAAK,IAAI,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;CAAE,CAAA;AAElD,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,GAAG,EAAE,IAEvC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAE1B;KAAG,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;CAAE,CAAA;AAEpC,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,CAAC,CAAA;CACT,CAAA;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,IAAI,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,CAAA;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAA;CACrC,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,EAAE,IAChD,QAAQ,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,iBAAiB,CAAA;AAC7C,eAAO,MAAM,sBAAsB,wBAAwB,CAAA;AAE3D,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAA;CAAE,CAAA;AAEnD,MAAM,WAAW,SAAS;CAAI;AAE9B;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,CAAC,iBAAiB,IAAI,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,iBAAiB,CAAC,GAAG;IAE5F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;EAEE;AACF,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,SAAS,EAAE,IAChD;KAAG,KAAK,IAAI,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;CAAE,CAAA;AAElD,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,GAAG,EAAE,IAEvC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAE1B;KAAG,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;CAAE,CAAA;AAEpC,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,CAAC,CAAA;CACT,CAAA;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,IAAI,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,CAAA;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAA;CACrC,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,EAAE,IAChD,QAAQ,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function hashString(str: string): number;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,UAQrC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "title": "ECS JS",
3
3
  "name": "ecsjs",
4
- "version": "1.3.0-beta.3",
4
+ "version": "1.3.0",
5
5
  "description": "An entity component system library for JavaScript",
6
6
  "author": "2013+ pflannery (https://gitlab.com/pflannery)",
7
7
  "license": "GNU GPL v3",
@@ -46,7 +46,7 @@
46
46
  "mocha": "11.7.5",
47
47
  "mocha-ui-esm": "1.0.0-beta.14",
48
48
  "ts-mockito": "2.6.1",
49
- "rimraf": "6.1.2",
49
+ "rimraf": "6.1.3",
50
50
  "source-map-support": "0.5.21",
51
51
  "typedoc": "0.28.17",
52
52
  "typescript": "5.9.3"
@@ -0,0 +1,168 @@
1
+ /*
2
+ ecsjs is an entity component system library for JavaScript
3
+ Copyright (C) 2014 Peter Flannery
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as
7
+ published by the Free Software Foundation, either version 3 of the
8
+ License, or (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ import type { ComponentMap } from './component-map.js';
19
+ import {
20
+ ComponentClassesMapKey,
21
+ type ComponentClass,
22
+ type Iterator,
23
+ type IteratorResult
24
+ } from './types.js';
25
+ import { hashString } from './utils.js';
26
+
27
+ /**
28
+ * Component class map for storing registered component maps
29
+ * @category Maps
30
+ */
31
+ export class ComponentClassesMap {
32
+
33
+ private hashIdToName: Map<number, string> = new Map<number, string>()
34
+ private hashIdToIndex = new Map<number, number>();
35
+ private indexToHashId: number[] = [];
36
+ private maps: ComponentMap<any>[] = [];
37
+
38
+ constructor(entries?: readonly (readonly [number, ComponentMap<any>])[] | null) {
39
+ if (entries) {
40
+ for (let i = 0; i < entries.length; i++) {
41
+ const entry = entries[i];
42
+ this.setByHashId(entry[0], entry[1]);
43
+ }
44
+ }
45
+ }
46
+
47
+ /**
48
+ * The number of registered component maps
49
+ */
50
+ get size() {
51
+ return this.maps.length;
52
+ }
53
+
54
+ /**
55
+ * Clears all maps and internal indices while preserving array references
56
+ */
57
+ clear(): void {
58
+ this.maps.length = 0;
59
+ this.indexToHashId.length = 0;
60
+ this.hashIdToIndex.clear();
61
+ }
62
+
63
+ /**
64
+ * Retrieves a component map using the static hashId of a component class
65
+ */
66
+ get<T>(componentClass: ComponentClass<T>): ComponentMap<T> | undefined {
67
+ const index = this.hashIdToIndex.get(componentClass.hashId!);
68
+ return index !== undefined ? this.maps[index] : undefined;
69
+ }
70
+
71
+ /**
72
+ * Registers a component map. Automatically generates a hashId from the class name if missing
73
+ */
74
+ set<T>(componentClass: ComponentClass<T>, map: ComponentMap<T>): this {
75
+ if (componentClass.hashId === undefined) {
76
+ componentClass.hashId = hashString(componentClass.name);
77
+ }
78
+
79
+ this.hashIdToName.set(componentClass.hashId, componentClass.name);
80
+ return this.setByHashId(componentClass.hashId!, map);
81
+ }
82
+
83
+ /**
84
+ * Maps a specific numeric hash id to a component map instance.
85
+ */
86
+ setByHashId(hash: number, map: ComponentMap<any>): this {
87
+ const existingIndex = this.hashIdToIndex.get(hash);
88
+
89
+ if (existingIndex !== undefined) {
90
+ this.maps[existingIndex] = map;
91
+ } else {
92
+ this.hashIdToIndex.set(hash, this.maps.length);
93
+ this.indexToHashId.push(hash);
94
+ this.maps.push(map);
95
+ }
96
+
97
+ return this;
98
+ }
99
+
100
+ /**
101
+ * Removes a component map and re-orders internal storage to maintain density
102
+ */
103
+ delete(componentClass: ComponentClass<any>): boolean {
104
+ const hashId = componentClass.hashId!;
105
+ const index = this.hashIdToIndex.get(hashId);
106
+ if (index === undefined) return false;
107
+
108
+ const lastIndex = this.maps.length - 1;
109
+ const lastHash = this.indexToHashId[lastIndex];
110
+
111
+ // Swap
112
+ this.maps[index] = this.maps[lastIndex];
113
+ this.indexToHashId[index] = lastHash;
114
+
115
+ // Update map pointer
116
+ this.hashIdToIndex.set(lastHash, index);
117
+
118
+ // Pop
119
+ this.maps.pop();
120
+ this.indexToHashId.pop();
121
+ this.hashIdToIndex.delete(hashId);
122
+ return true;
123
+ }
124
+
125
+ /**
126
+ * Executes a callback for every map, providing the instance and its registered name
127
+ */
128
+ forEach(callback: (value: ComponentMap<any>, name: string) => void) {
129
+ for (let i = 0; i < this.maps.length; i++) {
130
+ callback(this.maps[i], this.hashIdToName.get(this.indexToHashId[i])!);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Returns an iterator of all component map instances
136
+ */
137
+ values(): ArrayIterator<ComponentMap<any>> { return this.maps.values() }
138
+
139
+ /**
140
+ * Returns an iterator of [hashId, componentMap] pairs
141
+ */
142
+ entries(): Iterator<[number, ComponentMap<any>]> {
143
+ let index = 0;
144
+ const instances = this.maps;
145
+ const hashes = this.indexToHashId;
146
+
147
+ return {
148
+ next(): IteratorResult<[number, ComponentMap<any>]> {
149
+ if (index < instances.length) {
150
+ const value: [number, ComponentMap<any>] = [hashes[index], instances[index]];
151
+ index++;
152
+ return { value, done: false };
153
+ }
154
+ return { value: undefined as any, done: true };
155
+ },
156
+ reset() { index = 0; },
157
+ [Symbol.iterator]() { return this; }
158
+ };
159
+ }
160
+
161
+ /**
162
+ * Called when using JSON.stringify
163
+ */
164
+ toJSON() {
165
+ return { [ComponentClassesMapKey]: 1, iterable: [...this.entries()] };
166
+ }
167
+
168
+ }
@@ -16,7 +16,6 @@
16
16
  along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
  import {
19
- ComponentClassesMapKey,
20
19
  ComponentMapKey,
21
20
  type Iterator,
22
21
  type IteratorResult,
@@ -95,6 +94,9 @@ export class ComponentMap<TComponentInstance> implements Iterable<[number, TComp
95
94
  return index !== undefined && index !== -1 && this.entities[index] === entityId;
96
95
  }
97
96
 
97
+ /**
98
+ * Executes a callback for every map, providing the instance and its entity id
99
+ */
98
100
  forEach(callback: (value: TComponentInstance, key: number) => void) {
99
101
  for (let i = 0; i < this.instances.length; i++) {
100
102
  callback(this.instances[i], this.entities[i]);
@@ -132,14 +134,23 @@ export class ComponentMap<TComponentInstance> implements Iterable<[number, TComp
132
134
  return this.entries();
133
135
  }
134
136
 
137
+ /**
138
+ * Returns an iterator of all entity ids
139
+ */
135
140
  keys(): ArrayIterator<number> {
136
141
  return this.entities.values();
137
142
  }
138
143
 
144
+ /**
145
+ * Returns an iterator of all component instances
146
+ */
139
147
  values(): ArrayIterator<TComponentInstance> {
140
148
  return this.instances.values();
141
149
  }
142
150
 
151
+ /**
152
+ * Returns an iterator of [entityId, componentInstance] pairs
153
+ */
143
154
  entries(): Iterator<[number, TComponentInstance]> {
144
155
  let index = 0;
145
156
  const entities = this.entities;
@@ -192,23 +203,4 @@ export class ComponentMap<TComponentInstance> implements Iterable<[number, TComp
192
203
  console.table(this.toTable(), properties);
193
204
  }
194
205
 
195
- }
196
-
197
- /**
198
- * Component class map for storing registered component maps
199
- * @category Maps
200
- */
201
- export class ComponentClassesMap extends Map<string, ComponentMap<any>> {
202
-
203
- /**
204
- * Called when using JSON.stringify
205
- */
206
- toJSON() {
207
- return { [ComponentClassesMapKey]: 1, iterable: [...this.entries()] };
208
- }
209
-
210
- static get [Symbol.species]() {
211
- return Map;
212
- }
213
-
214
206
  }
package/src/ecs.ts CHANGED
@@ -22,7 +22,8 @@
22
22
  * @module ecsjs
23
23
  */
24
24
  import { EntityMap } from './entity-map.js'
25
- export { ComponentClassesMap, ComponentMap } from './component-map.js'
25
+ export { ComponentClassesMap } from './component-classes.js'
26
+ export { ComponentMap } from './component-map.js'
26
27
  export { EntityMap } from './entity-map.js'
27
28
  export type { ComponentNotRegistered, ComponentTypeKeyMissing } from './errors.js'
28
29
  export { ComponentIterator } from './iterator.js'
package/src/entity-map.ts CHANGED
@@ -15,7 +15,8 @@
15
15
  You should have received a copy of the GNU Affero General Public License
16
16
  along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
- import { ComponentClassesMap, ComponentMap } from './component-map.js';
18
+ import { ComponentClassesMap } from './component-classes.js';
19
+ import { ComponentMap } from './component-map.js';
19
20
  import { ComponentNotRegistered, ComponentTypeKeyMissing } from './errors.js';
20
21
  import { ComponentIterator } from './iterator.js';
21
22
  import { ComponentQuery } from './query.js';
@@ -58,11 +59,11 @@ export class EntityMap {
58
59
  register<TComponentClasses extends ComponentClass<any>[]>(...componentClasses: TComponentClasses) {
59
60
  for (const componentClass of componentClasses) {
60
61
  const componentName = componentClass.name;
61
- if (componentName === undefined) throw new ComponentTypeKeyMissing()
62
+ if (componentName === undefined) throw new ComponentTypeKeyMissing();
62
63
 
63
64
  // create the component map
64
- const componentDataMap: ComponentMap<any> = new ComponentMap();
65
- this.components.set(componentName, componentDataMap);
65
+ // const componentDataMap: ComponentMap<any> = new ComponentMap();
66
+ this.components.set(componentClass, new ComponentMap());
66
67
  }
67
68
 
68
69
  // chain
@@ -79,7 +80,7 @@ export class EntityMap {
79
80
  * }
80
81
  */
81
82
  getMap<T>(component: ComponentClass<T>): ComponentMap<T> | undefined {
82
- const map = this.components.get(component.name);
83
+ const map = this.components.get(component);
83
84
  if (map === undefined) throw new ComponentNotRegistered(component.name)
84
85
  return map
85
86
  }
@@ -188,7 +189,7 @@ export class EntityMap {
188
189
  * @throwsError {@link ComponentNotRegistered} when the specified component is not registered
189
190
  */
190
191
  private getEntity<T>(entityId: number, component: ComponentClass<T>): T | undefined {
191
- const map = this.components.get(component.name);
192
+ const map = this.components.get(component);
192
193
  if (map === undefined) throw new ComponentNotRegistered(component.name)
193
194
 
194
195
  return map.get(entityId);
@@ -228,7 +229,7 @@ export class EntityMap {
228
229
  */
229
230
  has<T>(entityId: number, component: ComponentClass<T>): boolean {
230
231
  // get the component map
231
- const map = this.components.get(component.name);
232
+ const map = this.components.get(component);
232
233
  if (map === undefined) return false
233
234
 
234
235
  return map.has(entityId);
@@ -242,7 +243,7 @@ export class EntityMap {
242
243
  hasAll<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean {
243
244
  for (let index = 0; index < components.length; index++) {
244
245
  const component = components[index];
245
- const map = this.components.get(component.name);
246
+ const map = this.components.get(component);
246
247
  if (map === undefined) return false;
247
248
  if (map.has(entityId) === false) return false;
248
249
  }
@@ -257,7 +258,7 @@ export class EntityMap {
257
258
  hasAny<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean {
258
259
  for (let index = 0; index < components.length; index++) {
259
260
  const component = components[index];
260
- const map = this.components.get(component.name);
261
+ const map = this.components.get(component);
261
262
  if (map === undefined) continue;
262
263
  if (map.has(entityId)) return true;
263
264
  }
@@ -266,7 +267,7 @@ export class EntityMap {
266
267
 
267
268
  private setEntity<T extends Component>(entityId: number, componentData: T): T {
268
269
  // get the component map
269
- const map = this.components.get(componentData.constructor.name);
270
+ const map = this.components.get((<ComponentClass<any>>componentData.constructor));
270
271
  if (map === undefined) throw new ComponentNotRegistered(componentData.constructor.name)
271
272
 
272
273
  // set the entity on the entity map
@@ -305,7 +306,7 @@ export class EntityMap {
305
306
  */
306
307
  remove<T extends ComponentClass<any>[]>(entityId: number, ...components: T) {
307
308
  for (const component of components) {
308
- this.removeByKey(entityId, component.name)
309
+ this.removeByKey(entityId, component)
309
310
  }
310
311
  }
311
312
 
@@ -315,12 +316,12 @@ export class EntityMap {
315
316
  * @example
316
317
  * ecs.removeByKey(entityId, "Position");
317
318
  */
318
- removeByKey(entityId: number, componentName: string) {
319
+ removeByKey(entityId: number, component: ComponentClass<any>) {
319
320
  // get the entity map
320
- const entityMap = this.components.get(componentName);
321
+ const entityMap = this.components.get(component);
321
322
 
322
323
  // ensure the map is defined
323
- if (entityMap === undefined) throw new ComponentNotRegistered(componentName);
324
+ if (entityMap === undefined) throw new ComponentNotRegistered(component.name);
324
325
 
325
326
  // get the entity
326
327
  const entity = entityMap.get(entityId);
package/src/query.ts CHANGED
@@ -26,17 +26,6 @@ export class ComponentQuery<TKey, TRelated extends any[]> {
26
26
  private keyMap: ComponentMap<TKey>
27
27
  private componentMaps: ComponentMap<any>[] = []
28
28
 
29
-
30
- /**
31
- * Returns a [entityId] iterator
32
- */
33
- public keys: () => ArrayIterator<number>;
34
-
35
- /**
36
- * Returns a [entityId, KeyComponent, ...RelatedComponents] iterator
37
- */
38
- public entries: () => ComponentIterator<TKey, TRelated>;
39
-
40
29
  /**
41
30
  * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
42
31
  */
@@ -48,8 +37,6 @@ export class ComponentQuery<TKey, TRelated extends any[]> {
48
37
  for (let i = 1; i < components.length; i++) {
49
38
  this.componentMaps.push(this.ecs.getMap(components[i])!)
50
39
  }
51
- this.keys = this.keyMap.keys;
52
- this.entries = this[Symbol.iterator];
53
40
  }
54
41
 
55
42
  /**
@@ -130,7 +117,12 @@ export class ComponentQuery<TKey, TRelated extends any[]> {
130
117
  }
131
118
 
132
119
  /**
133
- * Returns a [KeyComponent, ...RelatedComponents] iterator
120
+ * Returns an iterator of all the entityIds
121
+ */
122
+ keys(): ArrayIterator<number> { return this.keyMap.keys() }
123
+
124
+ /**
125
+ * Returns an iterator of all ComponentMap instances stored in this container
134
126
  */
135
127
  values(): Iterator<[TKey, ...TRelated]> {
136
128
  const keyMap = this.keyMap;
@@ -160,7 +152,12 @@ export class ComponentQuery<TKey, TRelated extends any[]> {
160
152
  }
161
153
 
162
154
  /**
163
- * Returns a [entityId, KeyComponent, ...RelatedComponents] iterator
155
+ * Returns an iterator that flattens all internal maps into [entityId, KeyComponent, ...RelatedComponents]
156
+ */
157
+ entries() { return this[Symbol.iterator](); }
158
+
159
+ /**
160
+ * Returns an iterator that flattens all internal maps into [entityId, KeyComponent, ...RelatedComponents]
164
161
  */
165
162
  [Symbol.iterator]() {
166
163
  return new ComponentIterator(this);
package/src/types.ts CHANGED
@@ -16,7 +16,10 @@ export interface Component { }
16
16
  * }
17
17
  * }
18
18
  */
19
- export type ComponentClass<ComponentInstance> = new (...args: any[]) => ComponentInstance
19
+ export type ComponentClass<ComponentInstance> = (new (...args: any[]) => ComponentInstance) & {
20
+ // static property
21
+ hashId?: number;
22
+ };
20
23
 
21
24
  /**
22
25
  * Used for infering generic type spread for classes
package/src/utils.ts ADDED
@@ -0,0 +1,9 @@
1
+ export function hashString(str: string) {
2
+ let hash = 0;
3
+ for (let i = 0; i < str.length; i++) {
4
+ const char = str.charCodeAt(i);
5
+ hash = ((hash << 5) - hash) + char;
6
+ hash |= 0; // Convert to 32bit
7
+ }
8
+ return hash;
9
+ }