ecsjs 1.0.0 → 1.1.0-beta.2
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/README.md +1 -0
- package/dist/ecs.js +1 -1
- package/dist/ecs.js.map +3 -3
- package/dist/types/src/component-map.d.ts +10 -13
- package/dist/types/src/component-map.d.ts.map +1 -1
- package/dist/types/src/ecs.d.ts +8 -5
- package/dist/types/src/ecs.d.ts.map +1 -1
- package/dist/types/src/entity-map.d.ts +32 -21
- package/dist/types/src/entity-map.d.ts.map +1 -1
- package/dist/types/src/errors.d.ts +2 -4
- package/dist/types/src/errors.d.ts.map +1 -1
- package/dist/types/src/iterators.d.ts +3 -3
- package/dist/types/src/types.d.ts +1 -2
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/component-map.ts +14 -26
- package/src/ecs.ts +8 -5
- package/src/entity-map.ts +51 -25
- package/src/errors.ts +2 -4
- package/src/iterators.ts +3 -3
- package/src/types.ts +1 -2
package/README.md
CHANGED
package/dist/ecs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var C="ComponentMap",c="ComponentClassesMap";var i=class extends Map{
|
|
1
|
+
var C="ComponentMap",c="ComponentClassesMap";var i=class extends Map{firstEntry(){return this.size===0?void 0:this.entries().next().value}firstKey(){return this.size===0?void 0:this.keys().next().value}firstValue(){return this.size===0?void 0:this.values().next().value}toJSON(){return{[C]:1,iterable:[...this.entries()]}}toTable(n=!1){let e=[];for(let[t,o]of this.entries()){let s=o,r={};n==!1&&(r["entity.key"]=t),r["entity.type"]=s.constructor.name,e.push({...r,...s})}return e}printTable(n=!1){console.table(this.toTable(n))}static get[Symbol.species](){return Map}},m=class extends Map{toJSON(){return{[c]:1,iterable:[...this.entries()]}}static get[Symbol.species](){return Map}};var y=class extends Error{constructor(){super("Component type is missing the 'name' parameter. i.e. a constructor name")}},p=class extends Error{constructor(e){super(`Component map does not exist for '${e}'`);this.componentName=e}};var l=class{constructor(n,e,...t){this.ecs=n;this.key=e;this.keyMap=this.ecs.getMap(e),this.entries=this.keyMap.entries(),this.components=t.map(o=>this.ecs.getMap(o))}keyMap;components;entries;next(){let n=this.entries.next(),{value:e,done:t}=n;if(t)return{value:e,done:t};let[o,s]=e,r=[o,s];for(let d of this.components)r.push(d.get(o));return{value:r,done:!1}}reset(){this.entries=this.keyMap.entries()}[Symbol.iterator](){return this}};var u=class a{components=new m;nextId=0;register(...n){for(let e of n){let t=e.name;if(t===void 0)throw new y;let o=new i;this.components.set(t,o)}return this}getMap(n){let e=this.components.get(n.name);if(e===void 0)throw new p(n.name);return e}firstEntry(n){return this.getMap(n)?.firstEntry()}firstKey(n,...e){let t=this.getMap(n)?.firstKey();if(arguments.length===1)return t;if(t!==void 0)return[t,...e.map(o=>this.getEntity(t,o))]}firstValue(n,...e){if(arguments.length===1)return this.getMap(n)?.firstValue();let[t,o]=this.getMap(n)?.firstEntry()??[];if(t!==void 0)return[o,...e.map(s=>this.getEntity(t,s))]}getEntity(n,e){let t=this.components.get(e.name);if(t===void 0)throw new p(e.name);return t.get(n)}get(n,...e){return e.length>1?e.map(t=>this.getEntity(n,t)):this.getEntity(n,e[0])}has(n,e){let t=this.components.get(e.name);return t===void 0?!1:t.has(n)}hasAll(n,...e){for(let t=0;t<e.length;t++){let o=e[t],s=this.components.get(o.name);if(s===void 0||s.has(n)===!1)return!1}return!0}hasAny(n,...e){for(let t=0;t<e.length;t++){let o=e[t],s=this.components.get(o.name);if(s!==void 0&&s.has(n))return!0}return!1}setEntity(n,e){let t=this.components.get(e.constructor.name);if(t===void 0)throw new p(e.constructor.name);return t.set(n,e),e}set(n,...e){return e.length>1?e.map(t=>this.setEntity(n,t)):this.setEntity(n,e[0])}remove(n,...e){for(let t of e)this.removeByKey(n,t.name)}removeByKey(n,e){let t=this.components.get(e);if(t===void 0)throw new p(e);return t.get(n)===void 0?!1:t.delete(n)}destroyEntity(...n){for(let e=0;e<n.length;e++){let t=n[e];for(let o of this.components.values())o.has(t)&&o.delete(t)}}getNextId(){return this.nextId++,this.nextId}clear(){return this.components.clear(),this}clearComponents(){return this.components.forEach(n=>n.clear()),this}iterator(n,...e){return new l(this,n,...e)}printTable(){return this.components.forEach(n=>console.table(n.toTable(!0))),this}printEntity(n){for(let e of this.components.values()){if(e.has(n)===!1)continue;let t=e.get(n),o={name:t.constructor.name,...t};console.table({[n]:o})}return this}static parse(n){return JSON.parse(n,function(t,o){return o.hasOwnProperty("components")?(Reflect.setPrototypeOf(o,a.prototype),o):o.hasOwnProperty(C)?new i(o.iterable):o.hasOwnProperty(c)?new m(o.iterable):this[t]})}static createWithTracing(n){let e={get(t,o){let s=t[o];return typeof s=="function"&&(n.length===0||n.includes(o))?function(...r){return console.groupCollapsed("ecs trace",o,r),console.trace(),console.groupEnd(),s.apply(this,r)}:s}};return new Proxy(new a,e)}};var f=new u;typeof window<"u"?window.ecs=f:typeof module<"u"&&module!==null&&(module.exports={ecs:f});export{m as ComponentClassesMap,l as ComponentIterator,i as ComponentMap,u as EntityMap,f as ecs};
|
|
2
2
|
//# sourceMappingURL=ecs.js.map
|
package/dist/ecs.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/types.ts", "../src/component-map.ts", "../src/errors.ts", "../src/iterators.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<TClasses extends Component[]> =\n { [Index in keyof TClasses]: TClasses[Index] }\n\n/**\n * Used for infering generic type spread for class instances\n */\nexport type ComponentInstances<TClasses extends ComponentClass<any>[]> =\n // return a single variadic item when only 1 item is specified\n TClasses['length'] extends 1 ? TClasses[0] extends ComponentClass<infer R> ? R : never\n // otherwise return an array of variadic types\n : {\n [Index in keyof TClasses]: TClasses[Index] extends ComponentClass<infer R> ? R : never\n }\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 * @category Types\n * @description\n * allow late bound assignment type for intellisense\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 { ComponentClassesMapKey, ComponentMapKey, type KeyCollection } from './types.js';\n\n/**\n * @category Maps\n * @description Component map for storing entity ids and related component data\n */\nexport class ComponentMap<TComponentInstance> extends Map<number, TComponentInstance> {\n\n constructor(entries: [number, TComponentInstance][] = []) {\n super(entries);\n }\n\n /**\n * @description Returns the first entity entry\n */\n firstEntry(): [entityId: number, value: TComponentInstance] | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.entries();\n const result = iterator.next();\n return result.value;\n }\n\n /**\n * @description Returns the first entity id\n */\n firstKey(): number | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.keys();\n const result = iterator.next();\n return result.value;\n }\n\n /**\n * @description Returns the first entity value\n */\n firstValue(): TComponentInstance | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.values();\n const result = iterator.next();\n return result.value;\n }\n\n /**\n * @description Called when using JSON.stringify\n */\n toJSON() {\n return { [ComponentMapKey]: 1, iterable: [...this.entries()] };\n }\n\n toTable(excludeKeys = false): any[] {\n const table = []\n for (const [key, value] of this.entries()) {\n const entity = value as { new(): TComponentInstance };\n const meta: KeyCollection<any> = {};\n if (excludeKeys == false) meta[\"entity.key\"] = key;\n meta[\"entity.type\"] = entity.constructor.name;\n table.push({ ...meta, ...entity });\n }\n return table;\n }\n\n /**\n * @description Prints entity data in a tabular format to the console\n */\n printTable(excludeKeys = false): void {\n console.table(this.toTable(excludeKeys));\n }\n\n entries(): MapIterator<[number, TComponentInstance]> {\n return super.entries().filter(x => x !== undefined && x !== null);\n }\n\n keys(): MapIterator<number> {\n return super.keys().filter(x => x !== undefined && x !== null);\n }\n\n values(): MapIterator<TComponentInstance> {\n return super.values().filter(x => x !== undefined && x !== null);\n }\n\n}\n\n/**\n * @category Maps\n * @description Component class map for storing registered component maps\n */\nexport class ComponentClassesMap extends Map<string, ComponentMap<any>> {\n\n constructor(entries: [string, ComponentMap<any>][] = []) {\n super(entries);\n }\n\n /**\n * @description Called when using JSON.stringify\n */\n toJSON() {\n return { [ComponentClassesMapKey]: 1, iterable: [...this.entries()] };\n }\n\n}", "/**\n * @category Errors\n * @description\n * Thrown when trying to register a component that is missing a 'name' parameter\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 * @category Errors\n * @description\n * Thrown when a trying to access a component that has not been registered\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 { EntityMap } from './entity-map.js';\nimport type { ComponentClass, ComponentInstances, IteratorResult } from './types.js';\n\n/**\n * @category Iterators\n * @example\n * // construct an instance\n * const iterator = new ComponentIterator(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<\n TComponentKey extends ComponentClass<any>,\n TComponentClasses extends ComponentClass<any>[]\n> {\n\n private keyMap: ComponentMap<any>\n private components: ComponentMap<any>[]\n // iteration state\n private entries: MapIterator<[number, TComponentKey]>\n\n /**\n * @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered\n */\n constructor(public ecs: EntityMap, public key: TComponentKey, ...components: TComponentClasses) {\n this.keyMap = this.ecs.getMap(key)!;\n this.entries = this.keyMap.entries();\n this.components = components.map(x => this.ecs.getMap(x)!);\n }\n\n /**\n * @description gets the next iterator value\n */\n next(): IteratorResult<ComponentInstances<[ComponentClass<number>, TComponentKey, ...TComponentClasses]>> {\n const entry = this.entries.next();\n const { value, done } = entry;\n if (done) return { value: value as any, done };\n\n const [entityId, entityValue] = value;\n const results = [entityId, entityValue]\n for (const x of this.components) {\n results.push(x.get(entityId));\n }\n\n return { value: results as any, done: false };\n }\n\n /**\n * @description 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}", "/*\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 './iterators.js';\nimport {\n ComponentClassesMapKey,\n ComponentMapKey,\n type Component,\n type ComponentClass,\n type ComponentInstances\n} from './types.js';\n\n/**\n * @category Maps\n * @description\n * Class for storing entities and their relationships\n */\nexport class EntityMap {\n /**\n * @description Registered component classes that contain the component instance data\n */\n public components = new ComponentClassesMap()\n\n private nextId: number = 0\n\n /**\n * @description 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 * @description 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 * @description Gets the first entity entry for a component class\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * const [entityId, player] = ecs.firstEntry(Player) ?? []\n */\n firstEntry<TComponent>(component: ComponentClass<TComponent>) {\n return this.getMap(component)?.firstEntry();\n }\n\n /**\n * @description 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 extends ComponentClass<any>, T extends ComponentClass<any>[]>(\n keyComponent: TKey,\n ...components: T\n ): ComponentInstances<[ComponentClass<number>, ...T]> | 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 multiple related component values\n return [entityId, ...components.map(x => this.getEntity(entityId, x))];\n }\n\n /**\n * @description 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 extends ComponentClass<any>, T extends ComponentClass<any>[]>(\n keyComponent: TKey,\n ...components: T\n ): ComponentInstances<[TKey, ...T]> | 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, value] = this.getMap(keyComponent)?.firstEntry() ?? [];\n if (entityId === undefined) return undefined;\n\n // attach multiple related components\n return [value, ...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 * @description 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\n * const player = ecs.get(entityId, Player)\n * \n * // or get multiple\n * const [player, position] = ecs.get(entityId, Player, Position) ?? []\n */\n get<T extends ComponentClass<any>[]>(\n entityId: number,\n ...components: T\n ): ComponentInstances<T> | undefined;\n get<T extends Component>(entityId: number, ...components: ComponentClass<T>[]): T | (T | undefined)[] | undefined {\n if (components.length > 1) return components.map(x => this.getEntity(entityId, x))\n\n // return a single component\n return this.getEntity(entityId, components[0])\n }\n\n /**\n * @description Check if a component exists for an entity id\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 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 * @description 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 * @description 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 * @description 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 * @description Deletes all components from an entity\n * @example\n * ecs.destroyEntity(entityId1)\n * \n * // or multiple\n * ecs.destroyEntity(entityId1, entityId2)\n */\n destroyEntity(...entityIds: number[]) {\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)) map.delete(entityId);\n }\n }\n }\n\n // TODO create id generator\n /**\n * @description 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 * @description Clears all registered components\n */\n clear() {\n this.components.clear();\n return this;\n }\n\n /**\n * @description Clears all component data\n */\n clearComponents() {\n this.components.forEach(x => x.clear())\n return this;\n }\n\n /**\n * @description 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<K extends ComponentClass<any>, T extends ComponentClass<any>[]>(\n keyComponent: K,\n ...components: T\n ): ComponentIterator<K, T>\n iterator(keyComponent: ComponentClass<any>, ...components: ComponentClass<any>[]) {\n return new ComponentIterator(this, keyComponent, ...components) as any;\n }\n\n /**\n * @description Prints all component maps in a tabular format to the console\n */\n printTable() {\n this.components.forEach(map => console.table(map.toTable(true)));\n return this;\n }\n\n /**\n * @description Prints all component data for the specified entity id in a tabular format to the console\n */\n printEntity(entityId: number) {\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 name: data.constructor.name,\n ...data\n };\n console.table({ [entityId]: columns });\n }\n\n return this;\n }\n\n /**\n * @description 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 * @description 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 './iterators.js'\nexport type { ComponentClass, IComponentIterator } from './types.js'\n\n/**\n * @category Constants\n * @description\n * Global instance of an {@link EntityMap}\n * @example\n * ecs.register(Player, Position)\n * ecs.set(1, new Player(), new Position(10, 40))\n * \n * const [player, position] = ecs.firstValue(Player, Position) ?? []\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": "AAAO,IAAMA,EAAkB,eAClBC,EAAyB,sBCsB/B,IAAMC,EAAN,cAA+C,GAAgC,
|
|
6
|
-
"names": ["ComponentMapKey", "ComponentClassesMapKey", "ComponentMap", "
|
|
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<TClasses extends Component[]> =\n { [Index in keyof TClasses]: TClasses[Index] }\n\n/**\n * Used for infering generic type spread for class instances\n */\nexport type ComponentInstances<TClasses extends ComponentClass<any>[]> =\n // return a single variadic item when only 1 item is specified\n TClasses['length'] extends 1 ? TClasses[0] extends ComponentClass<infer R> ? R : never\n // otherwise return an array of variadic types\n : {\n [Index in keyof TClasses]: TClasses[Index] extends ComponentClass<infer R> ? R : never\n }\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 { ComponentClassesMapKey, ComponentMapKey, type KeyCollection } from './types.js';\n\n/**\n * Component map for storing entity ids and related component data\n * @category Maps\n */\nexport class ComponentMap<TComponentInstance> extends Map<number, TComponentInstance> {\n\n /**\n * Returns the first entity entry\n */\n firstEntry(): [entityId: number, value: TComponentInstance] | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.entries();\n const result = iterator.next();\n return result.value;\n }\n\n /**\n * Returns the first entity id\n */\n firstKey(): number | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.keys();\n const result = iterator.next();\n return result.value;\n }\n\n /**\n * Returns the first entity value\n */\n firstValue(): TComponentInstance | undefined {\n if (this.size === 0) return undefined;\n\n const iterator = this.values();\n const result = iterator.next();\n return result.value;\n }\n\n /**\n * Called when using JSON.stringify\n */\n toJSON() {\n return { [ComponentMapKey]: 1, iterable: [...this.entries()] };\n }\n\n toTable(excludeKeys = false): any[] {\n const table = []\n for (const [key, value] of this.entries()) {\n const entity = value as { new(): TComponentInstance };\n const meta: KeyCollection<any> = {};\n if (excludeKeys == false) meta[\"entity.key\"] = key;\n meta[\"entity.type\"] = entity.constructor.name;\n table.push({ ...meta, ...entity });\n }\n return table;\n }\n\n /**\n * Prints entity data in a tabular format to the console\n */\n printTable(excludeKeys = false): void {\n console.table(this.toTable(excludeKeys));\n }\n\n static get [Symbol.species]() {\n return Map;\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 { EntityMap } from './entity-map.js';\nimport type { ComponentClass, ComponentInstances, IteratorResult } from './types.js';\n\n/**\n * @category Iterators\n * @example\n * // construct an instance\n * const iterator = new ComponentIterator(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<\n TComponentKey extends ComponentClass<any>,\n TComponentClasses extends ComponentClass<any>[]\n> {\n\n private keyMap: ComponentMap<any>\n private components: ComponentMap<any>[]\n // iteration state\n private entries: MapIterator<[number, TComponentKey]>\n\n /**\n * {@link ComponentNotRegistered} when any of specified component(s) are not registered\n */\n constructor(public ecs: EntityMap, public key: TComponentKey, ...components: TComponentClasses) {\n this.keyMap = this.ecs.getMap(key)!;\n this.entries = this.keyMap.entries();\n this.components = components.map(x => this.ecs.getMap(x)!);\n }\n\n /**\n * gets the next iterator value\n */\n next(): IteratorResult<ComponentInstances<[ComponentClass<number>, TComponentKey, ...TComponentClasses]>> {\n const entry = this.entries.next();\n const { value, done } = entry;\n if (done) return { value: value as any, done };\n\n const [entityId, entityValue] = value;\n const results = [entityId, entityValue]\n for (const x of this.components) {\n results.push(x.get(entityId));\n }\n\n return { value: results 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}", "/*\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 './iterators.js';\nimport {\n ComponentClassesMapKey,\n ComponentMapKey,\n type Component,\n type ComponentClass,\n type ComponentInstances\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 * Gets the first entity entry for a component class\n * @throwsError {@link ComponentNotRegistered} when the specified component is not registered\n * @example\n * const [entityId, player] = ecs.firstEntry(Player) ?? []\n */\n firstEntry<TComponent>(component: ComponentClass<TComponent>) {\n return this.getMap(component)?.firstEntry();\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 extends ComponentClass<any>, T extends ComponentClass<any>[]>(\n keyComponent: TKey,\n ...components: T\n ): ComponentInstances<[ComponentClass<number>, ...T]> | 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 multiple 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 extends ComponentClass<any>, T extends ComponentClass<any>[]>(\n keyComponent: TKey,\n ...components: T\n ): ComponentInstances<[TKey, ...T]> | 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, value] = this.getMap(keyComponent)?.firstEntry() ?? [];\n if (entityId === undefined) return undefined;\n\n // attach multiple related components\n return [value, ...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\n * const player = ecs.get(entityId, Player)\n * \n * // or get multiple\n * const [player, position] = ecs.get(entityId, Player, Position) ?? []\n */\n get<T extends ComponentClass<any>[]>(entityId: number, ...components: T): ComponentInstances<T> | undefined;\n get<T extends Component>(entityId: number, ...components: ComponentClass<T>[]): T | (T | undefined)[] | undefined {\n if (components.length > 1) return components.map(x => this.getEntity(entityId, x))\n\n // return a single component\n return this.getEntity(entityId, components[0])\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 * ecs.destroyEntity(entityId1)\n * \n * // or multiple\n * ecs.destroyEntity(entityId1, entityId2)\n */\n destroyEntity(...entityIds: number[]) {\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)) map.delete(entityId);\n }\n }\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 return this;\n }\n\n /**\n * Clears all component data\n */\n clearComponents() {\n this.components.forEach(x => x.clear())\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<K extends ComponentClass<any>, T extends ComponentClass<any>[]>(\n keyComponent: K,\n ...components: T\n ): ComponentIterator<K, T>\n iterator(keyComponent: ComponentClass<any>, ...components: ComponentClass<any>[]) {\n return new ComponentIterator(this, keyComponent, ...components) as any;\n }\n\n /**\n * Prints all component maps in a tabular format to the console\n */\n printTable() {\n this.components.forEach(map => console.table(map.toTable(true)));\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 printEntity(entityId: number) {\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 name: data.constructor.name,\n ...data\n };\n console.table({ [entityId]: columns });\n }\n\n return this;\n }\n\n /**\n * Parse's the JSON and returns an EntityMap object\n * @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 './iterators.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", "ComponentMapKey", "excludeKeys", "table", "key", "value", "entity", "meta", "ComponentClassesMap", "ComponentClassesMapKey", "ComponentTypeKeyMissing", "ComponentNotRegistered", "componentName", "ComponentIterator", "ecs", "key", "components", "x", "entry", "value", "done", "entityId", "entityValue", "results", "EntityMap", "_EntityMap", "ComponentClassesMap", "componentClasses", "componentClass", "componentName", "ComponentTypeKeyMissing", "componentDataMap", "ComponentMap", "component", "map", "ComponentNotRegistered", "keyComponent", "components", "entityId", "x", "value", "index", "componentData", "entityMap", "entityIds", "ComponentIterator", "data", "columns", "json", "key", "ComponentMapKey", "ComponentClassesMapKey", "funcFilter", "traceHandler", "target", "propKey", "targetValue", "args", "ecs", "EntityMap"]
|
|
7
7
|
}
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Component map for storing entity ids and related component data
|
|
2
3
|
* @category Maps
|
|
3
|
-
* @description Component map for storing entity ids and related component data
|
|
4
4
|
*/
|
|
5
5
|
export declare class ComponentMap<TComponentInstance> extends Map<number, TComponentInstance> {
|
|
6
|
-
constructor(entries?: [number, TComponentInstance][]);
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
7
|
+
* Returns the first entity entry
|
|
9
8
|
*/
|
|
10
9
|
firstEntry(): [entityId: number, value: TComponentInstance] | undefined;
|
|
11
10
|
/**
|
|
12
|
-
*
|
|
11
|
+
* Returns the first entity id
|
|
13
12
|
*/
|
|
14
13
|
firstKey(): number | undefined;
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
15
|
+
* Returns the first entity value
|
|
17
16
|
*/
|
|
18
17
|
firstValue(): TComponentInstance | undefined;
|
|
19
18
|
/**
|
|
20
|
-
*
|
|
19
|
+
* Called when using JSON.stringify
|
|
21
20
|
*/
|
|
22
21
|
toJSON(): {
|
|
23
22
|
ComponentMap: number;
|
|
@@ -25,25 +24,23 @@ export declare class ComponentMap<TComponentInstance> extends Map<number, TCompo
|
|
|
25
24
|
};
|
|
26
25
|
toTable(excludeKeys?: boolean): any[];
|
|
27
26
|
/**
|
|
28
|
-
*
|
|
27
|
+
* Prints entity data in a tabular format to the console
|
|
29
28
|
*/
|
|
30
29
|
printTable(excludeKeys?: boolean): void;
|
|
31
|
-
|
|
32
|
-
keys(): MapIterator<number>;
|
|
33
|
-
values(): MapIterator<TComponentInstance>;
|
|
30
|
+
static get [Symbol.species](): MapConstructor;
|
|
34
31
|
}
|
|
35
32
|
/**
|
|
33
|
+
* Component class map for storing registered component maps
|
|
36
34
|
* @category Maps
|
|
37
|
-
* @description Component class map for storing registered component maps
|
|
38
35
|
*/
|
|
39
36
|
export declare class ComponentClassesMap extends Map<string, ComponentMap<any>> {
|
|
40
|
-
constructor(entries?: [string, ComponentMap<any>][]);
|
|
41
37
|
/**
|
|
42
|
-
*
|
|
38
|
+
* Called when using JSON.stringify
|
|
43
39
|
*/
|
|
44
40
|
toJSON(): {
|
|
45
41
|
ComponentClassesMap: number;
|
|
46
42
|
iterable: [string, ComponentMap<any>][];
|
|
47
43
|
};
|
|
44
|
+
static get [Symbol.species](): MapConstructor;
|
|
48
45
|
}
|
|
49
46
|
//# sourceMappingURL=component-map.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-map.d.ts","sourceRoot":"","sources":["../../../src/component-map.ts"],"names":[],"mappings":"AAmBA;;;GAGG;AACH,qBAAa,YAAY,CAAC,kBAAkB,CAAE,SAAQ,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"component-map.d.ts","sourceRoot":"","sources":["../../../src/component-map.ts"],"names":[],"mappings":"AAmBA;;;GAGG;AACH,qBAAa,YAAY,CAAC,kBAAkB,CAAE,SAAQ,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAEnF;;OAEG;IACH,UAAU,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,CAAC,GAAG,SAAS;IAQvE;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,SAAS;IAQ9B;;OAEG;IACH,UAAU,IAAI,kBAAkB,GAAG,SAAS;IAQ5C;;OAEG;IACH,MAAM;;;;IAIN,OAAO,CAAC,WAAW,UAAQ,GAAG,GAAG,EAAE;IAYnC;;OAEG;IACH,UAAU,CAAC,WAAW,UAAQ,GAAG,IAAI;IAIrC,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,mBAE1B;CAEF;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"}
|
package/dist/types/src/ecs.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* An entity component system library for JavaScript
|
|
3
3
|
* @showCategories
|
|
4
4
|
* @module ecsjs
|
|
5
5
|
*/
|
|
@@ -10,14 +10,17 @@ export type { ComponentNotRegistered, ComponentTypeKeyMissing } from './errors.j
|
|
|
10
10
|
export { ComponentIterator } from './iterators.js';
|
|
11
11
|
export type { ComponentClass, IComponentIterator } from './types.js';
|
|
12
12
|
/**
|
|
13
|
-
* @category Constants
|
|
14
|
-
* @description
|
|
15
13
|
* Global instance of an {@link EntityMap}
|
|
14
|
+
*
|
|
15
|
+
* See the [cheat sheet](https://gitlab.com/ecsjs/ecs/-/blob/master/docs/cheat-sheet.md) for more examples
|
|
16
|
+
* @category Constants
|
|
16
17
|
* @example
|
|
18
|
+
*
|
|
19
|
+
* // register component(s)
|
|
17
20
|
* ecs.register(Player, Position)
|
|
18
|
-
* ecs.set(1, new Player(), new Position(10, 40))
|
|
19
21
|
*
|
|
20
|
-
*
|
|
22
|
+
* // create an entity
|
|
23
|
+
* const [player, position] = ecs.set(ecs.getNextId(), new Player(), new Position(10, 40))
|
|
21
24
|
*/
|
|
22
25
|
export declare const ecs: EntityMap;
|
|
23
26
|
//# sourceMappingURL=ecs.d.ts.map
|
|
@@ -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,gBAAgB,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpE
|
|
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,gBAAgB,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,GAAG,WAAkB,CAAA"}
|
|
@@ -2,18 +2,17 @@ import { ComponentClassesMap, ComponentMap } from './component-map.js';
|
|
|
2
2
|
import { ComponentIterator } from './iterators.js';
|
|
3
3
|
import { type Component, type ComponentClass, type ComponentInstances } from './types.js';
|
|
4
4
|
/**
|
|
5
|
-
* @category Maps
|
|
6
|
-
* @description
|
|
7
5
|
* Class for storing entities and their relationships
|
|
6
|
+
* @category Maps
|
|
8
7
|
*/
|
|
9
8
|
export declare class EntityMap {
|
|
10
9
|
/**
|
|
11
|
-
*
|
|
10
|
+
* Registered component classes that contain the component instance data
|
|
12
11
|
*/
|
|
13
12
|
components: ComponentClassesMap;
|
|
14
13
|
private nextId;
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
15
|
+
* Registers component classes with the {@link EntityMap}
|
|
17
16
|
* @throwsError {@link ComponentTypeKeyMissing} when the specified component type is missing a 'name' parameter
|
|
18
17
|
* @example
|
|
19
18
|
* // component class
|
|
@@ -29,7 +28,7 @@ export declare class EntityMap {
|
|
|
29
28
|
*/
|
|
30
29
|
register<TComponentClasses extends ComponentClass<any>[]>(...componentClasses: TComponentClasses): this;
|
|
31
30
|
/**
|
|
32
|
-
*
|
|
31
|
+
* Gets a component class map
|
|
33
32
|
* @throwsError {@link ComponentNotRegistered} when the specified component is not registered
|
|
34
33
|
* @example
|
|
35
34
|
* const positionMap = ecs.getMap(Position)
|
|
@@ -39,14 +38,14 @@ export declare class EntityMap {
|
|
|
39
38
|
*/
|
|
40
39
|
getMap<T>(component: ComponentClass<T>): ComponentMap<T> | undefined;
|
|
41
40
|
/**
|
|
42
|
-
*
|
|
41
|
+
* Gets the first entity entry for a component class
|
|
43
42
|
* @throwsError {@link ComponentNotRegistered} when the specified component is not registered
|
|
44
43
|
* @example
|
|
45
44
|
* const [entityId, player] = ecs.firstEntry(Player) ?? []
|
|
46
45
|
*/
|
|
47
46
|
firstEntry<TComponent>(component: ComponentClass<TComponent>): [entityId: number, value: TComponent] | undefined;
|
|
48
47
|
/**
|
|
49
|
-
*
|
|
48
|
+
* Gets the first entity id for a component class
|
|
50
49
|
* and optionally any related component data
|
|
51
50
|
* @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
52
51
|
* @example
|
|
@@ -62,7 +61,7 @@ export declare class EntityMap {
|
|
|
62
61
|
*/
|
|
63
62
|
firstKey<TKey extends ComponentClass<any>, T extends ComponentClass<any>[]>(keyComponent: TKey, ...components: T): ComponentInstances<[ComponentClass<number>, ...T]> | undefined;
|
|
64
63
|
/**
|
|
65
|
-
*
|
|
64
|
+
* Gets the first entity component data for a component class
|
|
66
65
|
* and optionally any related component data
|
|
67
66
|
* @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
68
67
|
* @example
|
|
@@ -82,7 +81,7 @@ export declare class EntityMap {
|
|
|
82
81
|
*/
|
|
83
82
|
private getEntity;
|
|
84
83
|
/**
|
|
85
|
-
*
|
|
84
|
+
* Gets component values related to an entity id
|
|
86
85
|
* @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
87
86
|
* @example
|
|
88
87
|
* // get one
|
|
@@ -93,14 +92,26 @@ export declare class EntityMap {
|
|
|
93
92
|
*/
|
|
94
93
|
get<T extends ComponentClass<any>[]>(entityId: number, ...components: T): ComponentInstances<T> | undefined;
|
|
95
94
|
/**
|
|
96
|
-
*
|
|
95
|
+
* Check if a component exists for an entity
|
|
97
96
|
* @example
|
|
98
97
|
* const exists = ecs.has(entityId, Position)
|
|
99
98
|
*/
|
|
100
99
|
has<T>(entityId: number, component: ComponentClass<T>): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Checks if all of the specified components exist for an entity
|
|
102
|
+
* @example
|
|
103
|
+
* const hasAll = ecs.hasAll(entityId, Position, Velocity)
|
|
104
|
+
*/
|
|
105
|
+
hasAll<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Checks if any of the specified components exist for an entity
|
|
108
|
+
* @example
|
|
109
|
+
* const hasAny = ecs.hasAny(entityId, Position, Velocity)
|
|
110
|
+
*/
|
|
111
|
+
hasAny<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean;
|
|
101
112
|
private setEntity;
|
|
102
113
|
/**
|
|
103
|
-
*
|
|
114
|
+
* Add or update multiple component values for an entity
|
|
104
115
|
* @example
|
|
105
116
|
* // set one
|
|
106
117
|
* const player = ecs.set(entityId, new Player());
|
|
@@ -115,20 +126,20 @@ export declare class EntityMap {
|
|
|
115
126
|
set<T extends Component>(entityId: number, component: T): T;
|
|
116
127
|
set<T extends Component[]>(entityId: number, ...components: T): T;
|
|
117
128
|
/**
|
|
118
|
-
*
|
|
129
|
+
* Removes the specified component(s) from an entity
|
|
119
130
|
* @example
|
|
120
131
|
* ecs.remove(entityId, Position);
|
|
121
132
|
*/
|
|
122
133
|
remove<T extends ComponentClass<any>[]>(entityId: number, ...components: T): void;
|
|
123
134
|
/**
|
|
124
|
-
*
|
|
135
|
+
* Removes the specified component from an entity
|
|
125
136
|
* @throwsError {@link ComponentNotRegistered} when the specified component is not registered
|
|
126
137
|
* @example
|
|
127
138
|
* ecs.removeByKey(entityId, "Position");
|
|
128
139
|
*/
|
|
129
140
|
removeByKey(entityId: number, componentName: string): boolean;
|
|
130
141
|
/**
|
|
131
|
-
*
|
|
142
|
+
* Deletes all components from an entity
|
|
132
143
|
* @example
|
|
133
144
|
* ecs.destroyEntity(entityId1)
|
|
134
145
|
*
|
|
@@ -137,22 +148,22 @@ export declare class EntityMap {
|
|
|
137
148
|
*/
|
|
138
149
|
destroyEntity(...entityIds: number[]): void;
|
|
139
150
|
/**
|
|
140
|
-
*
|
|
151
|
+
* Creates a new entity id for the EntityMap
|
|
141
152
|
* @example
|
|
142
153
|
* const newEntityId = ecs.getNextId()
|
|
143
154
|
* ecs.set(newEntityId, new Player())
|
|
144
155
|
*/
|
|
145
156
|
getNextId(): number;
|
|
146
157
|
/**
|
|
147
|
-
*
|
|
158
|
+
* Clears all registered components
|
|
148
159
|
*/
|
|
149
160
|
clear(): this;
|
|
150
161
|
/**
|
|
151
|
-
*
|
|
162
|
+
* Clears all component data
|
|
152
163
|
*/
|
|
153
164
|
clearComponents(): this;
|
|
154
165
|
/**
|
|
155
|
-
*
|
|
166
|
+
* Iterates over each component value that is related to the key component
|
|
156
167
|
* @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
157
168
|
* @example
|
|
158
169
|
* // iterate each component value that is related to the Player entity
|
|
@@ -172,15 +183,15 @@ export declare class EntityMap {
|
|
|
172
183
|
*/
|
|
173
184
|
iterator<K extends ComponentClass<any>, T extends ComponentClass<any>[]>(keyComponent: K, ...components: T): ComponentIterator<K, T>;
|
|
174
185
|
/**
|
|
175
|
-
*
|
|
186
|
+
* Prints all component maps in a tabular format to the console
|
|
176
187
|
*/
|
|
177
188
|
printTable(): this;
|
|
178
189
|
/**
|
|
179
|
-
*
|
|
190
|
+
* Prints all component data for the specified entity id in a tabular format to the console
|
|
180
191
|
*/
|
|
181
192
|
printEntity(entityId: number): this;
|
|
182
193
|
/**
|
|
183
|
-
*
|
|
194
|
+
* Parse's the JSON and returns an EntityMap object
|
|
184
195
|
* @example
|
|
185
196
|
* const json = JSON.stringfy(ecs);
|
|
186
197
|
* const restoredMap = ecs.parse(json);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-map.d.ts","sourceRoot":"","sources":["../../../src/entity-map.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB
|
|
1
|
+
{"version":3,"file":"entity-map.d.ts","sourceRoot":"","sources":["../../../src/entity-map.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @category Errors
|
|
3
|
-
* @description
|
|
4
2
|
* Thrown when trying to register a component that is missing a 'name' parameter
|
|
3
|
+
* @category Errors
|
|
5
4
|
*/
|
|
6
5
|
export declare class ComponentTypeKeyMissing extends Error {
|
|
7
6
|
constructor();
|
|
8
7
|
}
|
|
9
8
|
/**
|
|
9
|
+
* Thrown when trying to access a component that has not been registered
|
|
10
10
|
* @category Errors
|
|
11
|
-
* @description
|
|
12
|
-
* Thrown when a trying to access a component that has not been registered
|
|
13
11
|
*/
|
|
14
12
|
export declare class ComponentNotRegistered extends Error {
|
|
15
13
|
componentName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/errors.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;;CAIjD;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC5B,aAAa,EAAE,MAAM;gBAArB,aAAa,EAAE,MAAM;CAGzC"}
|
|
@@ -21,15 +21,15 @@ export declare class ComponentIterator<TComponentKey extends ComponentClass<any>
|
|
|
21
21
|
private components;
|
|
22
22
|
private entries;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
25
25
|
*/
|
|
26
26
|
constructor(ecs: EntityMap, key: TComponentKey, ...components: TComponentClasses);
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* gets the next iterator value
|
|
29
29
|
*/
|
|
30
30
|
next(): IteratorResult<ComponentInstances<[ComponentClass<number>, TComponentKey, ...TComponentClasses]>>;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
32
|
+
* resets the iterator back to the first entry
|
|
33
33
|
*/
|
|
34
34
|
reset(): void;
|
|
35
35
|
[Symbol.iterator](): this;
|
|
@@ -39,9 +39,8 @@ export type Iterator<T> = {
|
|
|
39
39
|
[Symbol.iterator]: () => Iterator<T>;
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
|
-
* @category Types
|
|
43
|
-
* @description
|
|
44
42
|
* allow late bound assignment type for intellisense
|
|
43
|
+
* @category Types
|
|
45
44
|
* @example
|
|
46
45
|
*
|
|
47
46
|
* let someIterator: IComponentIterator<[Player, Position]>
|
|
@@ -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,QAAQ,SAAS,SAAS,EAAE,IACvD;KAAG,KAAK,IAAI,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC;CAAE,CAAA;AAEhD;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,QAAQ,SAAS,cAAc,CAAC,GAAG,CAAC,EAAE,IAEnE,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,GAEpF;KACC,KAAK,IAAI,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CACvF,CAAA;AAEH,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
|
|
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,QAAQ,SAAS,SAAS,EAAE,IACvD;KAAG,KAAK,IAAI,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC;CAAE,CAAA;AAEhD;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,QAAQ,SAAS,cAAc,CAAC,GAAG,CAAC,EAAE,IAEnE,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,GAEpF;KACC,KAAK,IAAI,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CACvF,CAAA;AAEH,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"}
|
package/package.json
CHANGED
package/src/component-map.ts
CHANGED
|
@@ -18,17 +18,13 @@
|
|
|
18
18
|
import { ComponentClassesMapKey, ComponentMapKey, type KeyCollection } from './types.js';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
+
* Component map for storing entity ids and related component data
|
|
21
22
|
* @category Maps
|
|
22
|
-
* @description Component map for storing entity ids and related component data
|
|
23
23
|
*/
|
|
24
24
|
export class ComponentMap<TComponentInstance> extends Map<number, TComponentInstance> {
|
|
25
25
|
|
|
26
|
-
constructor(entries: [number, TComponentInstance][] = []) {
|
|
27
|
-
super(entries);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
26
|
/**
|
|
31
|
-
*
|
|
27
|
+
* Returns the first entity entry
|
|
32
28
|
*/
|
|
33
29
|
firstEntry(): [entityId: number, value: TComponentInstance] | undefined {
|
|
34
30
|
if (this.size === 0) return undefined;
|
|
@@ -39,7 +35,7 @@ export class ComponentMap<TComponentInstance> extends Map<number, TComponentInst
|
|
|
39
35
|
}
|
|
40
36
|
|
|
41
37
|
/**
|
|
42
|
-
*
|
|
38
|
+
* Returns the first entity id
|
|
43
39
|
*/
|
|
44
40
|
firstKey(): number | undefined {
|
|
45
41
|
if (this.size === 0) return undefined;
|
|
@@ -50,7 +46,7 @@ export class ComponentMap<TComponentInstance> extends Map<number, TComponentInst
|
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
/**
|
|
53
|
-
*
|
|
49
|
+
* Returns the first entity value
|
|
54
50
|
*/
|
|
55
51
|
firstValue(): TComponentInstance | undefined {
|
|
56
52
|
if (this.size === 0) return undefined;
|
|
@@ -61,7 +57,7 @@ export class ComponentMap<TComponentInstance> extends Map<number, TComponentInst
|
|
|
61
57
|
}
|
|
62
58
|
|
|
63
59
|
/**
|
|
64
|
-
*
|
|
60
|
+
* Called when using JSON.stringify
|
|
65
61
|
*/
|
|
66
62
|
toJSON() {
|
|
67
63
|
return { [ComponentMapKey]: 1, iterable: [...this.entries()] };
|
|
@@ -80,41 +76,33 @@ export class ComponentMap<TComponentInstance> extends Map<number, TComponentInst
|
|
|
80
76
|
}
|
|
81
77
|
|
|
82
78
|
/**
|
|
83
|
-
*
|
|
79
|
+
* Prints entity data in a tabular format to the console
|
|
84
80
|
*/
|
|
85
81
|
printTable(excludeKeys = false): void {
|
|
86
82
|
console.table(this.toTable(excludeKeys));
|
|
87
83
|
}
|
|
88
84
|
|
|
89
|
-
|
|
90
|
-
return
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
keys(): MapIterator<number> {
|
|
94
|
-
return super.keys().filter(x => x !== undefined && x !== null);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
values(): MapIterator<TComponentInstance> {
|
|
98
|
-
return super.values().filter(x => x !== undefined && x !== null);
|
|
85
|
+
static get [Symbol.species]() {
|
|
86
|
+
return Map;
|
|
99
87
|
}
|
|
100
88
|
|
|
101
89
|
}
|
|
102
90
|
|
|
103
91
|
/**
|
|
92
|
+
* Component class map for storing registered component maps
|
|
104
93
|
* @category Maps
|
|
105
|
-
* @description Component class map for storing registered component maps
|
|
106
94
|
*/
|
|
107
95
|
export class ComponentClassesMap extends Map<string, ComponentMap<any>> {
|
|
108
96
|
|
|
109
|
-
constructor(entries: [string, ComponentMap<any>][] = []) {
|
|
110
|
-
super(entries);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
97
|
/**
|
|
114
|
-
*
|
|
98
|
+
* Called when using JSON.stringify
|
|
115
99
|
*/
|
|
116
100
|
toJSON() {
|
|
117
101
|
return { [ComponentClassesMapKey]: 1, iterable: [...this.entries()] };
|
|
118
102
|
}
|
|
119
103
|
|
|
104
|
+
static get [Symbol.species]() {
|
|
105
|
+
return Map;
|
|
106
|
+
}
|
|
107
|
+
|
|
120
108
|
}
|
package/src/ecs.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* An entity component system library for JavaScript
|
|
21
21
|
* @showCategories
|
|
22
22
|
* @module ecsjs
|
|
23
23
|
*/
|
|
@@ -29,14 +29,17 @@ export { ComponentIterator } from './iterators.js'
|
|
|
29
29
|
export type { ComponentClass, IComponentIterator } from './types.js'
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* @category Constants
|
|
33
|
-
* @description
|
|
34
32
|
* Global instance of an {@link EntityMap}
|
|
33
|
+
*
|
|
34
|
+
* See the [cheat sheet](https://gitlab.com/ecsjs/ecs/-/blob/master/docs/cheat-sheet.md) for more examples
|
|
35
|
+
* @category Constants
|
|
35
36
|
* @example
|
|
37
|
+
*
|
|
38
|
+
* // register component(s)
|
|
36
39
|
* ecs.register(Player, Position)
|
|
37
|
-
* ecs.set(1, new Player(), new Position(10, 40))
|
|
38
40
|
*
|
|
39
|
-
*
|
|
41
|
+
* // create an entity
|
|
42
|
+
* const [player, position] = ecs.set(ecs.getNextId(), new Player(), new Position(10, 40))
|
|
40
43
|
*/
|
|
41
44
|
export const ecs = new EntityMap()
|
|
42
45
|
|
package/src/entity-map.ts
CHANGED
|
@@ -27,20 +27,19 @@ import {
|
|
|
27
27
|
} from './types.js';
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* @category Maps
|
|
31
|
-
* @description
|
|
32
30
|
* Class for storing entities and their relationships
|
|
31
|
+
* @category Maps
|
|
33
32
|
*/
|
|
34
33
|
export class EntityMap {
|
|
35
34
|
/**
|
|
36
|
-
*
|
|
35
|
+
* Registered component classes that contain the component instance data
|
|
37
36
|
*/
|
|
38
37
|
public components = new ComponentClassesMap()
|
|
39
38
|
|
|
40
39
|
private nextId: number = 0
|
|
41
40
|
|
|
42
41
|
/**
|
|
43
|
-
*
|
|
42
|
+
* Registers component classes with the {@link EntityMap}
|
|
44
43
|
* @throwsError {@link ComponentTypeKeyMissing} when the specified component type is missing a 'name' parameter
|
|
45
44
|
* @example
|
|
46
45
|
* // component class
|
|
@@ -69,7 +68,7 @@ export class EntityMap {
|
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
/**
|
|
72
|
-
*
|
|
71
|
+
* Gets a component class map
|
|
73
72
|
* @throwsError {@link ComponentNotRegistered} when the specified component is not registered
|
|
74
73
|
* @example
|
|
75
74
|
* const positionMap = ecs.getMap(Position)
|
|
@@ -84,7 +83,7 @@ export class EntityMap {
|
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
/**
|
|
87
|
-
*
|
|
86
|
+
* Gets the first entity entry for a component class
|
|
88
87
|
* @throwsError {@link ComponentNotRegistered} when the specified component is not registered
|
|
89
88
|
* @example
|
|
90
89
|
* const [entityId, player] = ecs.firstEntry(Player) ?? []
|
|
@@ -94,7 +93,7 @@ export class EntityMap {
|
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
/**
|
|
97
|
-
*
|
|
96
|
+
* Gets the first entity id for a component class
|
|
98
97
|
* and optionally any related component data
|
|
99
98
|
* @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
100
99
|
* @example
|
|
@@ -124,7 +123,7 @@ export class EntityMap {
|
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
/**
|
|
127
|
-
*
|
|
126
|
+
* Gets the first entity component data for a component class
|
|
128
127
|
* and optionally any related component data
|
|
129
128
|
* @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
130
129
|
* @example
|
|
@@ -165,7 +164,7 @@ export class EntityMap {
|
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
/**
|
|
168
|
-
*
|
|
167
|
+
* Gets component values related to an entity id
|
|
169
168
|
* @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
170
169
|
* @example
|
|
171
170
|
* // get one
|
|
@@ -174,10 +173,7 @@ export class EntityMap {
|
|
|
174
173
|
* // or get multiple
|
|
175
174
|
* const [player, position] = ecs.get(entityId, Player, Position) ?? []
|
|
176
175
|
*/
|
|
177
|
-
get<T extends ComponentClass<any>[]>(
|
|
178
|
-
entityId: number,
|
|
179
|
-
...components: T
|
|
180
|
-
): ComponentInstances<T> | undefined;
|
|
176
|
+
get<T extends ComponentClass<any>[]>(entityId: number, ...components: T): ComponentInstances<T> | undefined;
|
|
181
177
|
get<T extends Component>(entityId: number, ...components: ComponentClass<T>[]): T | (T | undefined)[] | undefined {
|
|
182
178
|
if (components.length > 1) return components.map(x => this.getEntity(entityId, x))
|
|
183
179
|
|
|
@@ -186,7 +182,7 @@ export class EntityMap {
|
|
|
186
182
|
}
|
|
187
183
|
|
|
188
184
|
/**
|
|
189
|
-
*
|
|
185
|
+
* Check if a component exists for an entity
|
|
190
186
|
* @example
|
|
191
187
|
* const exists = ecs.has(entityId, Position)
|
|
192
188
|
*/
|
|
@@ -198,6 +194,36 @@ export class EntityMap {
|
|
|
198
194
|
return map.has(entityId);
|
|
199
195
|
}
|
|
200
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Checks if all of the specified components exist for an entity
|
|
199
|
+
* @example
|
|
200
|
+
* const hasAll = ecs.hasAll(entityId, Position, Velocity)
|
|
201
|
+
*/
|
|
202
|
+
hasAll<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean {
|
|
203
|
+
for (let index = 0; index < components.length; index++) {
|
|
204
|
+
const component = components[index];
|
|
205
|
+
const map = this.components.get(component.name);
|
|
206
|
+
if (map === undefined) return false;
|
|
207
|
+
if (map.has(entityId) === false) return false;
|
|
208
|
+
}
|
|
209
|
+
return true
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Checks if any of the specified components exist for an entity
|
|
214
|
+
* @example
|
|
215
|
+
* const hasAny = ecs.hasAny(entityId, Position, Velocity)
|
|
216
|
+
*/
|
|
217
|
+
hasAny<T extends ComponentClass<any>[]>(entityId: number, ...components: T): boolean {
|
|
218
|
+
for (let index = 0; index < components.length; index++) {
|
|
219
|
+
const component = components[index];
|
|
220
|
+
const map = this.components.get(component.name);
|
|
221
|
+
if (map === undefined) continue;
|
|
222
|
+
if (map.has(entityId)) return true;
|
|
223
|
+
}
|
|
224
|
+
return false
|
|
225
|
+
}
|
|
226
|
+
|
|
201
227
|
private setEntity<T extends Component>(entityId: number, componentData: T): T {
|
|
202
228
|
// get the component map
|
|
203
229
|
const map = this.components.get(componentData.constructor.name);
|
|
@@ -211,7 +237,7 @@ export class EntityMap {
|
|
|
211
237
|
}
|
|
212
238
|
|
|
213
239
|
/**
|
|
214
|
-
*
|
|
240
|
+
* Add or update multiple component values for an entity
|
|
215
241
|
* @example
|
|
216
242
|
* // set one
|
|
217
243
|
* const player = ecs.set(entityId, new Player());
|
|
@@ -233,7 +259,7 @@ export class EntityMap {
|
|
|
233
259
|
}
|
|
234
260
|
|
|
235
261
|
/**
|
|
236
|
-
*
|
|
262
|
+
* Removes the specified component(s) from an entity
|
|
237
263
|
* @example
|
|
238
264
|
* ecs.remove(entityId, Position);
|
|
239
265
|
*/
|
|
@@ -244,7 +270,7 @@ export class EntityMap {
|
|
|
244
270
|
}
|
|
245
271
|
|
|
246
272
|
/**
|
|
247
|
-
*
|
|
273
|
+
* Removes the specified component from an entity
|
|
248
274
|
* @throwsError {@link ComponentNotRegistered} when the specified component is not registered
|
|
249
275
|
* @example
|
|
250
276
|
* ecs.removeByKey(entityId, "Position");
|
|
@@ -265,7 +291,7 @@ export class EntityMap {
|
|
|
265
291
|
}
|
|
266
292
|
|
|
267
293
|
/**
|
|
268
|
-
*
|
|
294
|
+
* Deletes all components from an entity
|
|
269
295
|
* @example
|
|
270
296
|
* ecs.destroyEntity(entityId1)
|
|
271
297
|
*
|
|
@@ -283,7 +309,7 @@ export class EntityMap {
|
|
|
283
309
|
|
|
284
310
|
// TODO create id generator
|
|
285
311
|
/**
|
|
286
|
-
*
|
|
312
|
+
* Creates a new entity id for the EntityMap
|
|
287
313
|
* @example
|
|
288
314
|
* const newEntityId = ecs.getNextId()
|
|
289
315
|
* ecs.set(newEntityId, new Player())
|
|
@@ -294,7 +320,7 @@ export class EntityMap {
|
|
|
294
320
|
}
|
|
295
321
|
|
|
296
322
|
/**
|
|
297
|
-
*
|
|
323
|
+
* Clears all registered components
|
|
298
324
|
*/
|
|
299
325
|
clear() {
|
|
300
326
|
this.components.clear();
|
|
@@ -302,7 +328,7 @@ export class EntityMap {
|
|
|
302
328
|
}
|
|
303
329
|
|
|
304
330
|
/**
|
|
305
|
-
*
|
|
331
|
+
* Clears all component data
|
|
306
332
|
*/
|
|
307
333
|
clearComponents() {
|
|
308
334
|
this.components.forEach(x => x.clear())
|
|
@@ -310,7 +336,7 @@ export class EntityMap {
|
|
|
310
336
|
}
|
|
311
337
|
|
|
312
338
|
/**
|
|
313
|
-
*
|
|
339
|
+
* Iterates over each component value that is related to the key component
|
|
314
340
|
* @throwsError {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
315
341
|
* @example
|
|
316
342
|
* // iterate each component value that is related to the Player entity
|
|
@@ -337,7 +363,7 @@ export class EntityMap {
|
|
|
337
363
|
}
|
|
338
364
|
|
|
339
365
|
/**
|
|
340
|
-
*
|
|
366
|
+
* Prints all component maps in a tabular format to the console
|
|
341
367
|
*/
|
|
342
368
|
printTable() {
|
|
343
369
|
this.components.forEach(map => console.table(map.toTable(true)));
|
|
@@ -345,7 +371,7 @@ export class EntityMap {
|
|
|
345
371
|
}
|
|
346
372
|
|
|
347
373
|
/**
|
|
348
|
-
*
|
|
374
|
+
* Prints all component data for the specified entity id in a tabular format to the console
|
|
349
375
|
*/
|
|
350
376
|
printEntity(entityId: number) {
|
|
351
377
|
for (const map of this.components.values()) {
|
|
@@ -363,7 +389,7 @@ export class EntityMap {
|
|
|
363
389
|
}
|
|
364
390
|
|
|
365
391
|
/**
|
|
366
|
-
*
|
|
392
|
+
* Parse's the JSON and returns an EntityMap object
|
|
367
393
|
* @example
|
|
368
394
|
* const json = JSON.stringfy(ecs);
|
|
369
395
|
* const restoredMap = ecs.parse(json);
|
package/src/errors.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @category Errors
|
|
3
|
-
* @description
|
|
4
2
|
* Thrown when trying to register a component that is missing a 'name' parameter
|
|
3
|
+
* @category Errors
|
|
5
4
|
*/
|
|
6
5
|
export class ComponentTypeKeyMissing extends Error {
|
|
7
6
|
constructor() {
|
|
@@ -10,9 +9,8 @@ export class ComponentTypeKeyMissing extends Error {
|
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
/**
|
|
12
|
+
* Thrown when trying to access a component that has not been registered
|
|
13
13
|
* @category Errors
|
|
14
|
-
* @description
|
|
15
|
-
* Thrown when a trying to access a component that has not been registered
|
|
16
14
|
*/
|
|
17
15
|
export class ComponentNotRegistered extends Error {
|
|
18
16
|
constructor(public componentName: string) {
|
package/src/iterators.ts
CHANGED
|
@@ -27,7 +27,7 @@ export class ComponentIterator<
|
|
|
27
27
|
private entries: MapIterator<[number, TComponentKey]>
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* {@link ComponentNotRegistered} when any of specified component(s) are not registered
|
|
31
31
|
*/
|
|
32
32
|
constructor(public ecs: EntityMap, public key: TComponentKey, ...components: TComponentClasses) {
|
|
33
33
|
this.keyMap = this.ecs.getMap(key)!;
|
|
@@ -36,7 +36,7 @@ export class ComponentIterator<
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
39
|
+
* gets the next iterator value
|
|
40
40
|
*/
|
|
41
41
|
next(): IteratorResult<ComponentInstances<[ComponentClass<number>, TComponentKey, ...TComponentClasses]>> {
|
|
42
42
|
const entry = this.entries.next();
|
|
@@ -53,7 +53,7 @@ export class ComponentIterator<
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
56
|
+
* resets the iterator back to the first entry
|
|
57
57
|
*/
|
|
58
58
|
reset() {
|
|
59
59
|
this.entries = this.keyMap.entries();
|
package/src/types.ts
CHANGED