@typeonce/ecs
Version:
Entity Component System (ECS) implementation in TypeScript, extensible, working with any renderer, type safe and composable
2 lines • 3.91 kB
JavaScript
var y=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var I=(n,e,t)=>e in n?y(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var f=(n,e)=>{for(var t in e)y(n,t,{get:e[t],enumerable:!0})},h=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of u(e))!C.call(n,a)&&a!==t&&y(n,a,{get:()=>e[a],enumerable:!(s=v(e,a))||s.enumerable});return n};var S=n=>h(y({},"__esModule",{value:!0}),n);var d=(n,e,t)=>I(n,typeof e!="symbol"?e+"":e,t);var k={};f(k,{Component:()=>w,ECS:()=>g,System:()=>A,query:()=>M,queryRequired:()=>q});module.exports=S(k);var E=class{constructor(){d(this,"systems",new Map);d(this,"dependencies",new Map)}registerSystem(e){this.systems.set(e._tag,e),this.dependencies.set(e._tag,new Set(e.dependencies))}resolveExecutionOrder(){let e=[],t=new Set,s=new Set,a=o=>{if(s.has(o))throw new Error(`Circular dependency detected: ${o}`);if(t.has(o))return;if(s.add(o),!this.systems.get(o))throw new Error(`System not found: ${o}`);let i=this.dependencies.get(o)??new Set;for(let r of i)a(r);t.add(o),s.delete(o),e.push(o)};for(let o of this.systems.keys())a(o);return e}execute(e){let t=this.resolveExecutionOrder();for(let s of t){let a=this.systems.get(s);a&&a.execute(e)}}};var w=n=>{class e{constructor(s){d(this,"_tag",n);s&&Object.assign(this,s)}}return e.prototype.name=n,e._tag=n,e},A=()=>(n,{execute:e,dependencies:t=[]})=>{class s{constructor(o){d(this,"_tag",n);d(this,"dependencies",t);d(this,"execute",o=>e({...o,input:this.input}));o&&(Object.assign(this,o),Object.defineProperty(this,"input",{get(){return o}}))}}return s.prototype.name=n,s._tag=n,s},l=n=>e=>t=>{let s=n.components.get(t);if(s){let a={},o=!0;for(let[p,i]of Object.entries(e)){let r=s.get(i._tag);if(r)a[p]=r;else{o=!1;break}}if(o)return{entityId:t,...a};throw new Error(`Entity ${t} does not have all required components.`)}throw new Error(`Components for entity ${t} not found`)},m=n=>e=>t=>{try{return l(n)(e)(t)}catch{return}},c=(n,e)=>(t,...s)=>{n.components.has(t)||n.components.set(t,new Map);for(let a=0;a<s.length;a++){let o=s[a];e.push({type:"addComponent",entityId:t,component:o})}},_=(n,e)=>(t,s)=>{n.components.get(t)&&e.push({type:"removeComponent",entityId:t,component:s})},T=n=>()=>{let e=n.nextEntityId++;return n.entities.add(e),e},R=(n,e)=>t=>{n.entities.delete(t)&&e.push({type:"destroyEntity",entityId:t})},b=n=>e=>{n.push(e)},W=n=>e=>n.filter(t=>t.type===e),x=n=>(...e)=>{for(let t of e)n.registry.registerSystem(t)},M=(n,e)=>t=>{let s=new Map,a=m(t)(n);for(let o of t.entities){let p=a(o);p&&s.set(o,p)}if(e){let o=m(t)(Object.fromEntries(e.map(p=>[p._tag,p])));for(let p of t.entities)o(p)&&s.delete(p)}return Array.from(s.values())},q=n=>e=>{let t=M(n)(e);if(t.length===0)throw new Error(`Missing at least one required entity with the following components: ${Object.keys(n).join(", ")}`);return t},g=class n{constructor(){d(this,"registry",new E);d(this,"entities",new Set);d(this,"components",new Map);d(this,"nextEntityId",0)}static create(e){let t=new n,s=[];return e({addComponent:c(t,s),createEntity:T(t),addSystem:x(t)}),t.applyMutations(s),t}update(e){let t=[],s=[];this.registry.execute({world:this,deltaTime:e,getComponentRequired:l(this),getComponent:m(this),createEntity:T(this),addComponent:c(this,s),removeComponent:_(this,s),destroyEntity:R(this,s),addSystem:x(this),poll:W(t),emit:b(t)}),this.applyMutations(s)}applyMutations(e){for(let t=0;t<e.length;t++){let s=e[t];switch(s.type){case"addComponent":this.components.get(s.entityId).set(s.component._tag,s.component);break;case"removeComponent":this.components.get(s.entityId).delete(s.component._tag);break;case"destroyEntity":this.entities.delete(s.entityId);break}}}};var G=Symbol.for("ecs/EntityId");0&&(module.exports={Component,ECS,System,query,queryRequired});
//# sourceMappingURL=index.js.map
;