ecspresso 0.9.0 → 0.10.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/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var m=((j)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(j,{get:(J,X)=>(typeof require<"u"?require:J)[X]}):j)(function(j){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+j+'" is not supported')});class V{parentMap=new Map;childrenMap=new Map;setParent(j,J){if(j===J)throw Error(`Cannot set entity ${j} as its own parent`);if(this.wouldCreateCycle(j,J))throw Error("Cannot set parent: would create circular reference");let X=this.parentMap.get(j);if(X!==void 0){let Z=this.childrenMap.get(X);if(Z){let $=Z.indexOf(j);if($!==-1)Z.splice($,1)}}this.parentMap.set(j,J);let Y=this.childrenMap.get(J);if(Y)Y.push(j);else this.childrenMap.set(J,[j]);return this}removeParent(j){let J=this.parentMap.get(j);if(J===void 0)return!1;let X=this.childrenMap.get(J);if(X){let Y=X.indexOf(j);if(Y!==-1)X.splice(Y,1)}return this.parentMap.delete(j),!0}getParent(j){return this.parentMap.get(j)??null}getChildren(j){let J=this.childrenMap.get(j);return J?[...J]:[]}getChildAt(j,J){if(J<0)return null;let X=this.childrenMap.get(j);if(!X||J>=X.length)return null;return X[J]??null}getChildIndex(j,J){let X=this.childrenMap.get(j);if(!X)return-1;return X.indexOf(J)}removeEntity(j){let J=this.parentMap.get(j)??null;if(J!==null){let Z=this.childrenMap.get(J);if(Z){let $=Z.indexOf(j);if($!==-1)Z.splice($,1)}}this.parentMap.delete(j);let X=this.childrenMap.get(j)??[],Y=[...X];for(let Z of X)this.parentMap.delete(Z);return this.childrenMap.delete(j),{oldParent:J,orphanedChildren:Y}}getAncestors(j){let J=[],X=this.parentMap.get(j);while(X!==void 0)J.push(X),X=this.parentMap.get(X);return J}getDescendants(j){let J=[],X=[...this.childrenMap.get(j)??[]];while(X.length>0){let Y=X.shift();if(Y===void 0)continue;J.push(Y);let Z=this.childrenMap.get(Y);if(Z)X.unshift(...Z)}return J}getRoot(j){let J=j,X=this.parentMap.get(J);while(X!==void 0)J=X,X=this.parentMap.get(J);return J}getSiblings(j){let J=this.parentMap.get(j);if(J===void 0)return[];let X=this.childrenMap.get(J);if(!X)return[];return X.filter((Y)=>Y!==j)}isDescendantOf(j,J){if(j===J)return!1;let X=this.parentMap.get(j);while(X!==void 0){if(X===J)return!0;X=this.parentMap.get(X)}return!1}isAncestorOf(j,J){return this.isDescendantOf(J,j)}getRootEntities(){let j=[];for(let J of this.childrenMap.keys())if(!this.parentMap.has(J))j.push(J);return j}wouldCreateCycle(j,J){let X=J;while(X!==void 0){if(X===j)return!0;X=this.parentMap.get(X)}return!1}forEachInHierarchy(j,J){let X=J?.roots??this.getRootEntities(),Y=[];for(let Z of X)Y.push({entityId:Z,parentId:null,depth:0});while(Y.length>0){let Z=Y.shift();if(!Z)break;j(Z.entityId,Z.parentId,Z.depth);let $=this.childrenMap.get(Z.entityId);if($)for(let F of $)Y.push({entityId:F,parentId:Z.entityId,depth:Z.depth+1})}}*hierarchyIterator(j){let J=j?.roots??this.getRootEntities(),X=[];for(let Y of J)X.push({entityId:Y,parentId:null,depth:0});while(X.length>0){let Y=X.shift();if(!Y)break;yield Y;let Z=this.childrenMap.get(Y.entityId);if(Z)for(let $ of Z)X.push({entityId:$,parentId:Y.entityId,depth:Y.depth+1})}}}class L{nextId=1;entities=new Map;componentIndices=new Map;addedCallbacks=new Map;removedCallbacks=new Map;hierarchyManager=new V;changeSeqs=new Map;_changeSeq=0;createEntity(){let j=this.nextId++,J={id:j,components:{}};return this.entities.set(j,J),J}addComponent(j,J,X){let Y=typeof j==="number"?this.entities.get(j):j;if(!Y){let $=typeof j==="number"?j:j.id;throw Error(`Cannot add component '${String(J)}': Entity with ID ${$} does not exist`)}if(Y.components[J]=X,!this.componentIndices.has(J))this.componentIndices.set(J,new Set);this.componentIndices.get(J)?.add(Y.id);let Z=this.addedCallbacks.get(J);if(Z)for(let $ of[...Z])$(X,Y);return this}addComponents(j,J){let X=typeof j==="number"?this.entities.get(j):j;if(!X){let Y=typeof j==="number"?j:j.id;throw Error(`Cannot add components: Entity with ID ${Y} does not exist`)}for(let Y in J)this.addComponent(X,Y,J[Y]);return this}removeComponent(j,J){let X=typeof j==="number"?this.entities.get(j):j;if(!X){let $=typeof j==="number"?j:j.id;throw Error(`Cannot remove component '${String(J)}': Entity with ID ${$} does not exist`)}let Y=X.components[J];delete X.components[J];let Z=this.removedCallbacks.get(J);if(Z&&Y!==void 0)for(let $ of[...Z])$(Y,X);return this.componentIndices.get(J)?.delete(X.id),this}getComponent(j,J){let X=this.entities.get(j);if(!X)throw Error(`Cannot get component '${String(J)}': Entity with ID ${j} does not exist`);return X.components[J]||null}getEntitiesWithQuery(j=[],J=[],X,Y){let Z=X!==void 0&&X.length>0&&Y!==void 0;if(j.length===0){if(J.length===0&&!Z)return Array.from(this.entities.values());return Array.from(this.entities.values()).filter((G)=>{if(J.length>0&&!J.every((H)=>!(H in G.components)))return!1;if(Z){let H=this.changeSeqs.get(G.id);if(!H)return!1;return X.some((W)=>(H.get(W)??-1)>Y)}return!0})}let $=j.reduce((G,H)=>{let W=this.componentIndices.get(H)?.size??0,Q=this.componentIndices.get(G)?.size??1/0;return W<Q?H:G},j[0]),F=this.componentIndices.get($);if(!F||F.size===0)return[];let _=[],U=J.length>0;for(let G of F){let H=this.entities.get(G);if(H&&j.every((W)=>(W in H.components))&&(!U||J.every((W)=>!(W in H.components)))){if(Z){let W=this.changeSeqs.get(G);if(!W||!X.some((Q)=>(W.get(Q)??-1)>Y))continue}_.push(H)}}return _}removeEntity(j,J){let X=typeof j==="number"?this.entities.get(j):j;if(!X)return!1;if(J?.cascade??!0){let Z=this.hierarchyManager.getDescendants(X.id);for(let $ of[...Z].reverse())this.removeEntityInternal($)}return this.removeEntityInternal(X.id)}removeEntityInternal(j){let J=this.entities.get(j);if(!J)return!1;this.hierarchyManager.removeEntity(j);for(let X of Object.keys(J.components)){let Y=J.components[X];if(Y!==void 0){let Z=this.removedCallbacks.get(X);if(Z)for(let $ of[...Z])$(Y,J)}this.componentIndices.get(X)?.delete(J.id)}return this.changeSeqs.delete(J.id),this.entities.delete(J.id)}getEntity(j){return this.entities.get(j)}onComponentAdded(j,J){if(!this.addedCallbacks.has(j))this.addedCallbacks.set(j,new Set);return this.addedCallbacks.get(j).add(J),()=>{this.addedCallbacks.get(j)?.delete(J)}}onComponentRemoved(j,J){if(!this.removedCallbacks.has(j))this.removedCallbacks.set(j,new Set);return this.removedCallbacks.get(j).add(J),()=>{this.removedCallbacks.get(j)?.delete(J)}}get changeSeq(){return this._changeSeq}markChanged(j,J){let X=++this._changeSeq,Y=this.changeSeqs.get(j);if(!Y)Y=new Map,this.changeSeqs.set(j,Y);Y.set(J,X)}getChangeSeq(j,J){return this.changeSeqs.get(j)?.get(J)??-1}clearChangeSeqs(j){this.changeSeqs.delete(j)}spawnChild(j,J){let X=this.createEntity();return this.addComponents(X,J),this.setParent(X.id,j),X}setParent(j,J){return this.hierarchyManager.setParent(j,J),this}removeParent(j){return this.hierarchyManager.removeParent(j)}getParent(j){return this.hierarchyManager.getParent(j)}getChildren(j){return this.hierarchyManager.getChildren(j)}getChildAt(j,J){return this.hierarchyManager.getChildAt(j,J)}getChildIndex(j,J){return this.hierarchyManager.getChildIndex(j,J)}getAncestors(j){return this.hierarchyManager.getAncestors(j)}getDescendants(j){return this.hierarchyManager.getDescendants(j)}getRoot(j){return this.hierarchyManager.getRoot(j)}getSiblings(j){return this.hierarchyManager.getSiblings(j)}isDescendantOf(j,J){return this.hierarchyManager.isDescendantOf(j,J)}isAncestorOf(j,J){return this.hierarchyManager.isAncestorOf(j,J)}getRootEntities(){return this.hierarchyManager.getRootEntities()}forEachInHierarchy(j,J){this.hierarchyManager.forEachInHierarchy(j,J)}hierarchyIterator(j){return this.hierarchyManager.hierarchyIterator(j)}}class D{handlers=new Map;subscribe(j,J){return this.addHandler(j,J,!1)}once(j,J){return this.addHandler(j,J,!0)}unsubscribe(j,J){let X=this.handlers.get(j);if(!X)return!1;let Y=X.findIndex((Z)=>Z.callback===J);if(Y===-1)return!1;return X.splice(Y,1),!0}addHandler(j,J,X){if(!this.handlers.has(j))this.handlers.set(j,[]);let Y={callback:J,once:X};return this.handlers.get(j).push(Y),()=>{let Z=this.handlers.get(j);if(Z){let $=Z.indexOf(Y);if($!==-1)Z.splice($,1)}}}publish(j,J){let X=this.handlers.get(j);if(!X)return;let Y=[...X],Z=[];for(let $ of Y)if($.callback(J),$.once)Z.push($);if(Z.length>0)for(let $ of Z){let F=X.indexOf($);if(F!==-1)X.splice(F,1)}}clear(){this.handlers.clear()}clearEvent(j){this.handlers.delete(j)}}function g(j){return typeof j==="object"&&j!==null&&"factory"in j&&typeof j.factory==="function"}function T(j,J){let X=[],Y=new Set,Z=new Set;function $(F,_=[]){if(Y.has(F))return;if(Z.has(F))throw Error(`Circular resource dependency: ${[..._,F].join(" -> ")}`);Z.add(F);for(let U of J(F))if(j.includes(U))$(U,[..._,F]);Z.delete(F),Y.add(F),X.push(F)}for(let F of j)$(F);return X}class z{resources=new Map;resourceFactories=new Map;resourceDependencies=new Map;resourceDisposers=new Map;initializedResourceKeys=new Set;add(j,J){if(g(J)){if(this.resourceFactories.set(j,J.factory),this.resourceDependencies.set(j,J.dependsOn??[]),J.onDispose)this.resourceDisposers.set(j,J.onDispose)}else if(this._isFactoryFunction(J))this.resourceFactories.set(j,J),this.resourceDependencies.set(j,[]);else this.resources.set(j,J),this.initializedResourceKeys.add(j),this.resourceDependencies.set(j,[]);return this}_isFactoryFunction(j){if(typeof j!=="function")return!1;let J=j.toString();if(J.startsWith("class "))return!1;if(J.includes("[native code]"))return!1;if(j.prototype){let X=Object.getOwnPropertyNames(j.prototype);if(X.length>1||X.length===1&&X[0]!=="constructor")return!1}if(j.name&&j.name[0]===j.name[0].toUpperCase()&&j.name.length>1){if(J.includes("this.")||J.includes("new "))return!1}return!0}get(j,J){let X=this.resources.get(j);if(X!==void 0)return X;let Y=this.resourceFactories.get(j);if(Y===void 0)throw Error(`Resource ${String(j)} not found`);let Z=Y(J);if(!(Z instanceof Promise))this.resources.set(j,Z),this.initializedResourceKeys.add(j);return Z}has(j){return this.resources.has(j)||this.resourceFactories.has(j)}remove(j){let J=this.resources.delete(j),X=this.resourceFactories.delete(j);return this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),J||X}getKeys(){let j=new Set([...this.resources.keys(),...this.resourceFactories.keys()]);return Array.from(j)}needsInitialization(j){return this.resourceFactories.has(j)&&!this.initializedResourceKeys.has(j)}getPendingInitializationKeys(){return Array.from(this.resourceFactories.keys()).filter((j)=>!this.initializedResourceKeys.has(j))}async initializeResource(j,J){if(!this.resourceFactories.has(j)||this.initializedResourceKeys.has(j))return;let Y=await this.resourceFactories.get(j)(J);this.resources.set(j,Y),this.initializedResourceKeys.add(j),this.resourceFactories.delete(j)}async initializeResources(j,...J){let X=J.length===0?this.getPendingInitializationKeys():J.map((Z)=>Z);if(X.length===0)return;let Y=T(X,(Z)=>this.resourceDependencies.get(Z)??[]);for(let Z of Y)await this.initializeResource(Z,j)}getDependencies(j){return this.resourceDependencies.get(j)??[]}async disposeResource(j,J){let X=j;if(!this.resources.has(X)&&!this.resourceFactories.has(X))return!1;if(this.initializedResourceKeys.has(X)){let Y=this.resourceDisposers.get(X),Z=this.resources.get(X);if(Y&&Z!==void 0)await Y(Z,J)}return this.resources.delete(X),this.resourceFactories.delete(X),this.resourceDependencies.delete(X),this.resourceDisposers.delete(X),this.initializedResourceKeys.delete(X),!0}async disposeResources(j){let J=Array.from(this.initializedResourceKeys);if(J.length===0)return;let X=T(J,(Y)=>this.resourceDependencies.get(Y)??[]).reverse();for(let Y of X)await this.disposeResource(Y,j)}}class w{assets=new Map;groups=new Map;eventBus=null;setEventBus(j){this.eventBus=j}register(j,J){if(this.assets.set(j,{definition:J,status:"pending"}),J.group){let X=this.groups.get(J.group)??new Set;X.add(j),this.groups.set(J.group,X)}}async loadEagerAssets(){let j=[];for(let[J,X]of this.assets)if(X.definition.eager&&X.status==="pending")j.push(J);await Promise.all(j.map((J)=>this.loadAsset(J)))}async loadAsset(j){let J=j,X=this.assets.get(J);if(!X)throw Error(`Asset '${J}' not found`);if(X.status==="loaded"&&X.value!==void 0)return X.value;if(X.status==="loading"&&X.loadPromise)return X.loadPromise;if(X.status==="failed")X.status="pending";X.status="loading",X.loadPromise=X.definition.loader();try{let Y=await X.loadPromise;return X.value=Y,X.status="loaded",X.loadPromise=void 0,this.eventBus?.publish("assetLoaded",{key:J}),this.checkGroupProgress(X.definition.group),Y}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));throw X.status="failed",X.error=Z,X.loadPromise=void 0,this.eventBus?.publish("assetFailed",{key:J,error:Z}),Z}}async loadAssetGroup(j){let J=this.groups.get(j);if(!J||J.size===0)throw Error(`Asset group '${j}' not found or empty`);await Promise.all(Array.from(J).map((X)=>this.loadAsset(X)))}get(j){let J=j,X=this.assets.get(J);if(!X)throw Error(`Asset '${J}' not found`);if(X.status!=="loaded"||X.value===void 0)throw Error(`Asset '${J}' is not loaded (status: ${X.status})`);return X.value}getOrUndefined(j){let J=j,X=this.assets.get(J);if(!X||X.status!=="loaded")return;return X.value}getHandle(j){let J=j,X=this.assets.get(J);if(!X)throw Error(`Asset '${J}' not found`);let Y=this;return{get status(){return X.status},get isLoaded(){return X.status==="loaded"},get(){return Y.get(j)},getOrUndefined(){return Y.getOrUndefined(j)}}}getStatus(j){let J=j,X=this.assets.get(J);if(!X)throw Error(`Asset '${J}' not found`);return X.status}isLoaded(j){let J=j;return this.assets.get(J)?.status==="loaded"}isGroupLoaded(j){let J=this.groups.get(j);if(!J||J.size===0)return!1;for(let X of J){let Y=this.assets.get(X);if(!Y||Y.status!=="loaded")return!1}return!0}getGroupProgress(j){let J=this.groups.get(j);if(!J||J.size===0)return 0;let X=0;for(let Y of J)if(this.assets.get(Y)?.status==="loaded")X++;return X/J.size}getGroupProgressDetails(j){let J=this.groups.get(j);if(!J||J.size===0)return{loaded:0,total:0,progress:0};let X=0;for(let Z of J)if(this.assets.get(Z)?.status==="loaded")X++;let Y=J.size;return{loaded:X,total:Y,progress:X/Y}}checkGroupProgress(j){if(!j||!this.eventBus)return;let J=this.getGroupProgressDetails(j);if(this.eventBus.publish("assetGroupProgress",{group:j,...J}),J.loaded===J.total)this.eventBus.publish("assetGroupLoaded",{group:j})}createResource(){let j=this;return{getStatus(J){return j.getStatus(J)},isLoaded(J){return j.isLoaded(J)},isGroupLoaded(J){return j.isGroupLoaded(J)},getGroupProgress(J){return j.getGroupProgress(J)},get(J){return j.get(J)},getOrUndefined(J){return j.getOrUndefined(J)},getHandle(J){return j.getHandle(J)}}}getKeys(){return Array.from(this.assets.keys())}getGroupNames(){return Array.from(this.groups.keys())}getGroupKeys(j){let J=this.groups.get(j);return J?Array.from(J):[]}}class q{manager;constructor(j){this.manager=j}add(j,J){return this.manager.register(j,{loader:J,eager:!0}),this}addWithConfig(j,J){return this.manager.register(j,J),this}addGroup(j,J){for(let[X,Y]of Object.entries(J))this.manager.register(X,{loader:Y,eager:!1,group:j});return this}getManager(){return this.manager}}function R(j){return new q(j??new w)}class M{screens=new Map;currentScreen=null;screenStack=[];eventBus=null;assetManager=null;ecs=null;setDependencies(j,J,X){this.eventBus=j,this.assetManager=J,this.ecs=X}register(j,J){this.screens.set(j,{definition:J})}async setScreen(j,J){let X=j,Y=this.screens.get(X);if(!Y)throw Error(`Screen '${X}' not found`);await this.verifyRequiredAssets(Y.definition);while(this.screenStack.length>0){let $=this.screenStack.pop();if($)await this.exitScreen($.name)}if(this.currentScreen)await this.exitScreen(this.currentScreen.name);let Z=Y.definition.initialState(J);this.currentScreen={name:j,config:J,state:Z},await Y.definition.onEnter?.(J,this.ecs),this.eventBus?.publish("screenEnter",{screen:X,config:J})}async pushScreen(j,J){let X=j,Y=this.screens.get(X);if(!Y)throw Error(`Screen '${X}' not found`);if(await this.verifyRequiredAssets(Y.definition),this.currentScreen)this.screenStack.push(this.currentScreen);let Z=Y.definition.initialState(J);this.currentScreen={name:j,config:J,state:Z},await Y.definition.onEnter?.(J,this.ecs),this.eventBus?.publish("screenPush",{screen:X,config:J})}async popScreen(){if(this.screenStack.length===0)throw Error("Cannot pop screen: stack is empty");if(this.currentScreen){let j=this.currentScreen.name;await this.exitScreen(j),this.eventBus?.publish("screenPop",{screen:j})}this.currentScreen=this.screenStack.pop()??null}async exitScreen(j){let J=this.screens.get(j);if(J?.definition.onExit)await J.definition.onExit(this.ecs);this.eventBus?.publish("screenExit",{screen:j})}async verifyRequiredAssets(j){if(!this.assetManager)return;if(j.requiredAssets){for(let J of j.requiredAssets)if(!this.assetManager.isLoaded(J))await this.assetManager.loadAsset(J)}if(j.requiredAssetGroups){for(let J of j.requiredAssetGroups)if(!this.assetManager.isGroupLoaded(J))await this.assetManager.loadAssetGroup(J)}}getCurrentScreen(){return this.currentScreen?.name??null}getConfig(){if(!this.currentScreen)throw Error("No current screen");return this.currentScreen.config}getConfigOrNull(){return this.currentScreen?.config??null}getState(){if(!this.currentScreen)throw Error("No current screen");return this.currentScreen.state}getStateOrNull(){return this.currentScreen?.state??null}updateState(j){if(!this.currentScreen)throw Error("No current screen");let J=typeof j==="function"?j(this.currentScreen.state):j;this.currentScreen.state={...this.currentScreen.state,...J}}getStackDepth(){return this.screenStack.length}isOverlay(){return this.screenStack.length>0}isActive(j){if(this.currentScreen?.name===j)return!0;return this.screenStack.some((J)=>J.name===j)}isCurrent(j){return this.currentScreen?.name===j}createResource(){let j=this;return{get current(){return j.getCurrentScreen()},get config(){return j.getConfigOrNull()},get state(){return j.getStateOrNull()},set state(J){if(j.currentScreen)j.currentScreen.state=J},get stack(){return j.screenStack},get isOverlay(){return j.isOverlay()},get stackDepth(){return j.getStackDepth()},isActive(J){return j.isActive(J)},isCurrent(J){return j.isCurrent(J)}}}getScreenNames(){return Array.from(this.screens.keys())}hasScreen(j){return this.screens.has(j)}}class v{manager;constructor(j){this.manager=j}add(j,J){return this.manager.register(j,J),this}getManager(){return this.manager}}function x(j){return new v(j??new M)}class K{queries=new Map;entityManager;constructor(j){this.entityManager=j}addQuery(j,J){let X={definition:J,matchingEntities:new Set};this.queries.set(j,X);let Y=this.entityManager.getEntitiesWithQuery(J.with,J.without??[]);for(let Z of Y)X.matchingEntities.add(Z.id),J.onEnter?.(Z)}removeQuery(j){return this.queries.delete(j)}entityMatchesQuery(j,J){for(let X of J.with)if(!(X in j.components))return!1;if(J.without){for(let X of J.without)if(X in j.components)return!1}return!0}onComponentAdded(j,J){for(let[X,Y]of this.queries){let Z=Y.matchingEntities.has(j.id),$=this.entityMatchesQuery(j,Y.definition);if(!Z&&$)Y.matchingEntities.add(j.id),Y.definition.onEnter?.(j);else if(Z&&!$)Y.matchingEntities.delete(j.id),Y.definition.onExit?.(j.id)}}onComponentRemoved(j,J){for(let[X,Y]of this.queries){let Z=Y.matchingEntities.has(j.id),$=this.entityMatchesQuery(j,Y.definition);if(Z&&!$)Y.matchingEntities.delete(j.id),Y.definition.onExit?.(j.id);else if(!Z&&$)Y.matchingEntities.add(j.id),Y.definition.onEnter?.(j)}}onEntityRemoved(j){for(let[J,X]of this.queries)if(X.matchingEntities.has(j))X.matchingEntities.delete(j),X.definition.onExit?.(j)}recheckEntity(j){for(let[J,X]of this.queries){let Y=X.matchingEntities.has(j.id),Z=this.entityMatchesQuery(j,X.definition);if(!Y&&Z)X.matchingEntities.add(j.id),X.definition.onEnter?.(j);else if(Y&&!Z)X.matchingEntities.delete(j.id),X.definition.onExit?.(j.id)}}}class P{commands=[];removeEntity(j,J){this.commands.push((X)=>{X.removeEntity(j,J)})}addComponent(j,J,X){this.commands.push((Y)=>{Y.entityManager.addComponent(j,J,X)})}removeComponent(j,J){this.commands.push((X)=>{X.entityManager.removeComponent(j,J)})}spawn(j){this.commands.push((J)=>{J.spawn(j)})}spawnChild(j,J){this.commands.push((X)=>{X.spawnChild(j,J)})}addComponents(j,J){this.commands.push((X)=>{X.entityManager.addComponents(j,J)})}setParent(j,J){this.commands.push((X)=>{X.setParent(j,J)})}markChanged(j,J){this.commands.push((X)=>{X.markChanged(j,J)})}removeParent(j){this.commands.push((J)=>{J.removeParent(j)})}playback(j){for(let J of this.commands)try{J(j)}catch(X){console.warn("CommandBuffer: Command failed during playback:",X)}this.commands=[]}clear(){this.commands=[]}get length(){return this.commands.length}}class B{_label;_ecspresso;_bundle;queries={};processFunction;detachFunction;initializeFunction;eventHandlers;_priority=0;_phase="update";_isRegistered=!1;_groups=[];_inScreens;_excludeScreens;_requiredAssets;constructor(j,J=null,X=null){this._label=j;this._ecspresso=J;this._bundle=X}get label(){return this._label}get bundle(){return this._bundle}get ecspresso(){return this._ecspresso}_autoRegister(){if(this._isRegistered||!this._ecspresso)return;let j=this._buildSystemObject();C(j,this._ecspresso),this._isRegistered=!0}_buildSystemObject(){return this._createSystemObject()}_createSystemObject(){let j={label:this._label,entityQueries:this.queries,priority:this._priority,phase:this._phase};if(this.processFunction)j.process=this.processFunction;if(this.detachFunction)j.onDetach=this.detachFunction;if(this.initializeFunction)j.onInitialize=this.initializeFunction;if(this.eventHandlers)j.eventHandlers=this.eventHandlers;if(this._groups.length>0)j.groups=[...this._groups];if(this._inScreens)j.inScreens=this._inScreens;if(this._excludeScreens)j.excludeScreens=this._excludeScreens;if(this._requiredAssets)j.requiredAssets=this._requiredAssets;return j}setPriority(j){return this._priority=j,this}inPhase(j){return this._phase=j,this}inGroup(j){if(!this._groups.includes(j))this._groups.push(j);return this}inScreens(j){return this._inScreens=[...j],this}excludeScreens(j){return this._excludeScreens=[...j],this}requiresAssets(j){return this._requiredAssets=[...j],this}addQuery(j,J){let X=this;return X.queries={...this.queries,[j]:J},X}setProcess(j){return this.processFunction=j,this}registerAndContinue(){if(!this._ecspresso)throw Error(`Cannot register system '${this._label}': SystemBuilder is not attached to an ECSpresso instance. Use Bundle.addSystem() or ECSpresso.addSystem() instead.`);return this._autoRegister(),this._ecspresso}and(){if(this._ecspresso)return this._autoRegister(),this._ecspresso;if(this._bundle)return this._bundle;throw Error(`Cannot use and() on system '${this._label}': not attached to ECSpresso or Bundle.`)}setOnDetach(j){return this.detachFunction=j,this}setOnInitialize(j){return this.initializeFunction=j,this}setEventHandlers(j){return this.eventHandlers=j,this}build(j){let J=this._createSystemObject();if(this._ecspresso)C(J,this._ecspresso);if(j)C(J,j);return this}}function C(j,J){J._registerSystem(j)}function O(j,J){return new B(j,J)}function S(j,J){return new B(j,null,J)}var f="0.9.0";var N=["preUpdate","fixedUpdate","update","postUpdate","render"],I={};class A{static VERSION=f;_entityManager;_eventBus;_resourceManager;_commandBuffer;_systems=[];_phaseSystems={preUpdate:[],fixedUpdate:[],update:[],postUpdate:[],render:[]};_installedBundles=new Set;_disabledGroups=new Set;_assetManager=null;_screenManager=null;_reactiveQueryManager;_postUpdateHooks=[];_currentTick=0;_systemLastSeqs=new Map;_changeThreshold=0;_fixedDt=0.016666666666666666;_fixedAccumulator=0;_interpolationAlpha=0;_maxFixedSteps=8;constructor(){this._entityManager=new L,this._eventBus=new D,this._resourceManager=new z,this._reactiveQueryManager=new K(this._entityManager),this._commandBuffer=new P,this._setupReactiveQueryHooks()}_setupReactiveQueryHooks(){let j=0,J=new Set,X=()=>{for(let _ of J){let U=this._entityManager.getEntity(_);if(U)this._reactiveQueryManager.recheckEntity(U)}J.clear()},Y=this._entityManager.addComponent.bind(this._entityManager);this._entityManager.addComponent=(_,U,G)=>{let H=Y(_,U,G),W=typeof _==="number"?_:_.id;if(this._entityManager.markChanged(W,U),j>0)J.add(W);else{let Q=this._entityManager.getEntity(W);if(Q)this._reactiveQueryManager.onComponentAdded(Q,U)}return H};let Z=this._entityManager.addComponents.bind(this._entityManager);this._entityManager.addComponents=(_,U)=>{j++;let G=Z(_,U);if(j--,j===0)X();return G};let $=this._entityManager.removeComponent.bind(this._entityManager);this._entityManager.removeComponent=(_,U)=>{let G=typeof _==="number"?_:_.id,H=this._entityManager.getEntity(G),W=$(_,U);if(H)this._reactiveQueryManager.onComponentRemoved(H,U);return W};let F=this._entityManager.removeEntity.bind(this._entityManager);this._entityManager.removeEntity=(_,U)=>{let G=typeof _==="number"?_:_.id;if(this._entityManager.getEntity(G)){if(U?.cascade??!0){let Q=this._entityManager.getDescendants(G);for(let k of Q)this._reactiveQueryManager.onEntityRemoved(k)}this._reactiveQueryManager.onEntityRemoved(G)}return F(_,U)}}static create(){return new b}addSystem(j){return O(j,this)}update(j){let J=this._screenManager?.getCurrentScreen()??null;this._executePhase(this._phaseSystems.preUpdate,j,J),this._commandBuffer.playback(this),this._fixedAccumulator+=j;let X=0;while(this._fixedAccumulator>=this._fixedDt&&X<this._maxFixedSteps)this._executePhase(this._phaseSystems.fixedUpdate,this._fixedDt,J),this._commandBuffer.playback(this),this._fixedAccumulator-=this._fixedDt,X++;if(this._fixedAccumulator>=this._fixedDt)this._fixedAccumulator=0;this._interpolationAlpha=this._fixedAccumulator/this._fixedDt,this._executePhase(this._phaseSystems.update,j,J),this._commandBuffer.playback(this),this._executePhase(this._phaseSystems.postUpdate,j,J),this._commandBuffer.playback(this);for(let Y of this._postUpdateHooks)Y(this,j);this._executePhase(this._phaseSystems.render,j,J),this._commandBuffer.playback(this),this._changeThreshold=this._entityManager.changeSeq,this._currentTick++}_executePhase(j,J,X){for(let Y of j){if(!Y.process)continue;if(Y.groups?.length){let U=!1;for(let G of Y.groups)if(this._disabledGroups.has(G)){U=!0;break}if(U)continue}if(Y.inScreens?.length){if(X===null||!Y.inScreens.includes(X))continue}if(Y.excludeScreens?.length){if(X!==null&&Y.excludeScreens.includes(X))continue}if(Y.requiredAssets?.length&&this._assetManager){let U=!0;for(let G of Y.requiredAssets)if(!this._assetManager.isLoaded(G)){U=!1;break}if(!U)continue}let Z=this._systemLastSeqs.get(Y)??0;this._changeThreshold=Z;let $={},F=!1,_=!1;if(Y.entityQueries)for(let U in Y.entityQueries){_=!0;let G=Y.entityQueries[U];if(G){if($[U]=this._entityManager.getEntitiesWithQuery(G.with,G.without||[],G.changed,G.changed?this._changeThreshold:void 0),$[U].length)F=!0}}if(F)Y.process($,J,this);else if(!_)Y.process(I,J,this);this._systemLastSeqs.set(Y,this._entityManager.changeSeq)}}async initialize(){if(await this.initializeResources(),this._assetManager)this._assetManager.setEventBus(this._eventBus),await this._assetManager.loadEagerAssets(),this._resourceManager.add("$assets",this._assetManager.createResource());if(this._screenManager)this._screenManager.setDependencies(this._eventBus,this._assetManager,this),this._resourceManager.add("$screen",this._screenManager.createResource());for(let j of this._systems)await j.onInitialize?.(this)}async initializeResources(...j){await this._resourceManager.initializeResources(this,...j)}_rebuildPhaseSystems(){for(let j of N)this._phaseSystems[j]=[];for(let j of this._systems){let J=j.phase??"update";this._phaseSystems[J].push(j)}for(let j of N)this._phaseSystems[j].sort((J,X)=>{let Y=J.priority??0;return(X.priority??0)-Y})}updateSystemPriority(j,J){let X=this._systems.find((Y)=>Y.label===j);if(!X)return!1;return X.priority=J,this._rebuildPhaseSystems(),!0}updateSystemPhase(j,J){let X=this._systems.find((Y)=>Y.label===j);if(!X)return!1;return X.phase=J,this._rebuildPhaseSystems(),!0}get interpolationAlpha(){return this._interpolationAlpha}get fixedDt(){return this._fixedDt}disableSystemGroup(j){this._disabledGroups.add(j)}enableSystemGroup(j){this._disabledGroups.delete(j)}isSystemGroupEnabled(j){return!this._disabledGroups.has(j)}getSystemsInGroup(j){return this._systems.filter((J)=>J.groups?.includes(j)).map((J)=>J.label)}removeSystem(j){let J=this._systems.findIndex((Y)=>Y.label===j);if(J===-1)return!1;let X=this._systems[J];if(!X)return!1;if(X.onDetach)X.onDetach(this);return this._systems.splice(J,1),this._systemLastSeqs.delete(X),this._rebuildPhaseSystems(),!0}_registerSystem(j){if(this._systems.push(j),this._systemLastSeqs.set(j,this._changeThreshold),this._rebuildPhaseSystems(),!j.eventHandlers)return;for(let J in j.eventHandlers){let X=j.eventHandlers[J]?.handler;if(X)this._eventBus.subscribe(J,(Y)=>{X(Y,this)})}}hasResource(j){return this._resourceManager.has(j)}getResource(j){let J=this._resourceManager.get(j,this);if(!J)throw Error(`Resource '${String(j)}' not found. Available resources: [${this.getResourceKeys().map((X)=>String(X)).join(", ")}]`);return J}addResource(j,J){return this._resourceManager.add(j,J),this}removeResource(j){return this._resourceManager.remove(j)}async disposeResource(j){return this._resourceManager.disposeResource(j,this)}async disposeResources(){return this._resourceManager.disposeResources(this)}updateResource(j,J){let X=this.getResource(j),Y=J(X);return this._resourceManager.add(j,Y),this}getResourceKeys(){return this._resourceManager.getKeys()}resourceNeedsInitialization(j){return this._resourceManager.needsInitialization(j)}hasComponent(j,J){return this._entityManager.getComponent(j,J)!==null}spawn(j){let J=this._entityManager.createEntity();return this._entityManager.addComponents(J,j),J}getEntitiesWithQuery(j,J=[],X){return this._entityManager.getEntitiesWithQuery(j,J,X,X?this._changeThreshold:void 0)}removeEntity(j,J){return this._entityManager.removeEntity(j,J)}spawnChild(j,J){let X=this._entityManager.spawnChild(j,J);return this._emitHierarchyChanged(X.id,null,j),X}setParent(j,J){let X=this._entityManager.getParent(j);return this._entityManager.setParent(j,J),this._emitHierarchyChanged(j,X,J),this}removeParent(j){let J=this._entityManager.getParent(j),X=this._entityManager.removeParent(j);if(X)this._emitHierarchyChanged(j,J,null);return X}getParent(j){return this._entityManager.getParent(j)}getChildren(j){return this._entityManager.getChildren(j)}getChildAt(j,J){return this._entityManager.getChildAt(j,J)}getChildIndex(j,J){return this._entityManager.getChildIndex(j,J)}getAncestors(j){return this._entityManager.getAncestors(j)}getDescendants(j){return this._entityManager.getDescendants(j)}getRoot(j){return this._entityManager.getRoot(j)}getSiblings(j){return this._entityManager.getSiblings(j)}isDescendantOf(j,J){return this._entityManager.isDescendantOf(j,J)}isAncestorOf(j,J){return this._entityManager.isAncestorOf(j,J)}getRootEntities(){return this._entityManager.getRootEntities()}forEachInHierarchy(j,J){this._entityManager.forEachInHierarchy(j,J)}hierarchyIterator(j){return this._entityManager.hierarchyIterator(j)}_emitHierarchyChanged(j,J,X){this._eventBus.publish("hierarchyChanged",{entityId:j,oldParent:J,newParent:X})}get installedBundles(){return Array.from(this._installedBundles)}get entityManager(){return this._entityManager}get eventBus(){return this._eventBus}get commands(){return this._commandBuffer}get currentTick(){return this._currentTick}get changeThreshold(){return this._changeThreshold}markChanged(j,J){this._entityManager.markChanged(j,J)}onComponentAdded(j,J){return this._entityManager.onComponentAdded(j,J)}onComponentRemoved(j,J){return this._entityManager.onComponentRemoved(j,J)}addReactiveQuery(j,J){this._reactiveQueryManager.addQuery(j,J)}removeReactiveQuery(j){return this._reactiveQueryManager.removeQuery(j)}on(j,J){return this._eventBus.subscribe(j,J)}off(j,J){return this._eventBus.unsubscribe(j,J)}onPostUpdate(j){return this._postUpdateHooks.push(j),()=>{let J=this._postUpdateHooks.indexOf(j);if(J!==-1)this._postUpdateHooks.splice(J,1)}}getAsset(j){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager.get(j)}getAssetOrUndefined(j){return this._assetManager?.getOrUndefined(j)}getAssetHandle(j){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager.getHandle(j)}isAssetLoaded(j){return this._assetManager?.isLoaded(j)??!1}async loadAsset(j){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager.loadAsset(j)}async loadAssetGroup(j){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager.loadAssetGroup(j)}isAssetGroupLoaded(j){return this._assetManager?.isGroupLoaded(j)??!1}getAssetGroupProgress(j){return this._assetManager?.getGroupProgress(j)??0}async setScreen(j,J){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.setScreen(j,J)}async pushScreen(j,J){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.pushScreen(j,J)}async popScreen(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.popScreen()}getCurrentScreen(){return this._screenManager?.getCurrentScreen()??null}getScreenConfig(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.getConfig()}getScreenConfigOrNull(){return this._screenManager?.getConfigOrNull()??null}getScreenState(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.getState()}getScreenStateOrNull(){return this._screenManager?.getStateOrNull()??null}updateScreenState(j){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");this._screenManager.updateState(j)}isCurrentScreen(j){return this._screenManager?.isCurrent(j)??!1}isScreenActive(j){return this._screenManager?.isActive(j)??!1}getScreenStackDepth(){return this._screenManager?.getStackDepth()??0}_setAssetManager(j){this._assetManager=j}_setScreenManager(j){this._screenManager=j}_setFixedDt(j){this._fixedDt=j}_installBundle(j){if(this._installedBundles.has(j.id))return this;this._installedBundles.add(j.id),j.registerSystemsWithEcspresso(this);let J=j.getResources();for(let[X,Y]of J.entries())this._resourceManager.add(X,Y);if(this._assetManager){let X=j.getAssets();for(let[Y,Z]of X.entries())this._assetManager.register(Y,Z)}if(this._screenManager){let X=j.getScreens();for(let[Y,Z]of X.entries())this._screenManager.register(Y,Z)}return this}}class b{ecspresso;assetConfigurator=null;screenConfigurator=null;pendingResources=[];_fixedDt=null;constructor(){this.ecspresso=new A}withBundle(j){return this.ecspresso._installBundle(j),this}withResource(j,J){return this.pendingResources.push({key:j,value:J}),this}withAssets(j){let J=R();return j(J),this.assetConfigurator=J,this}withScreens(j){let J=x();return j(J),this.screenConfigurator=J,this}withFixedTimestep(j){return this._fixedDt=j,this}build(){for(let{key:j,value:J}of this.pendingResources)this.ecspresso.addResource(j,J);if(this.assetConfigurator)this.ecspresso._setAssetManager(this.assetConfigurator.getManager());if(this.screenConfigurator)this.ecspresso._setScreenManager(this.screenConfigurator.getManager());if(this._fixedDt!==null)this.ecspresso._setFixedDt(this._fixedDt);return this.ecspresso}}function p(){return`bundle_${Date.now().toString(36)}_${Math.random().toString(36).substring(2,9)}`}class E{_systems=[];_resources=new Map;_assets=new Map;_assetGroups=new Map;_screens=new Map;_id;constructor(j){this._id=j||p()}get id(){return this._id}set id(j){this._id=j}addSystem(j){if(typeof j==="string"){let J=S(j,this);return this._systems.push(J),J}else return this._systems.push(j),j}addResource(j,J){return this._resources.set(j,J),this}addAsset(j,J,X){return this._assets.set(j,{loader:J,eager:X?.eager??!0,group:X?.group}),this}addAssetGroup(j,J){let X=new Map;for(let[Y,Z]of Object.entries(J))X.set(Y,Z),this._assets.set(Y,{loader:Z,eager:!1,group:j});return this._assetGroups.set(j,X),this}addScreen(j,J){return this._screens.set(j,J),this}getAssets(){return new Map(this._assets)}getScreens(){return new Map(this._screens)}_setResource(j,J){this._resources.set(j,J)}_setAsset(j,J){this._assets.set(j,J)}_setScreen(j,J){this._screens.set(j,J)}getSystems(){return this._systems.map((j)=>j.build())}registerSystemsWithEcspresso(j){for(let J of this._systems)J.build(j)}getResources(){return new Map(this._resources)}getResource(j){return this._resources.get(j)}getSystemBuilders(){return[...this._systems]}hasResource(j){return this._resources.has(j)}}function u(j,...J){if(J.length===0)return new E(j);let X=new E(j);for(let Y of J){for(let Z of Y.getSystemBuilders())X.addSystem(Z);for(let[Z,$]of Y.getResources().entries())X._setResource(Z,$);for(let[Z,$]of Y.getAssets().entries())X._setAsset(Z,$);for(let[Z,$]of Y.getScreens().entries())X._setScreen(Z,$)}return X}function Pj(j){return j}var Nj=A;export{u as mergeBundles,Nj as default,x as createScreenConfigurator,Pj as createQueryDefinition,R as createAssetConfigurator,B as SystemBuilder,M as ScreenManager,z as ResourceManager,V as HierarchyManager,D as EventBus,L as EntityManager,P as CommandBuffer,E as Bundle,w as AssetManager};
1
+ var c=((j)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(j,{get:(J,X)=>(typeof require<"u"?require:J)[X]}):j)(function(j){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+j+'" is not supported')});class z{parentMap=new Map;childrenMap=new Map;setParent(j,J){if(j===J)throw Error(`Cannot set entity ${j} as its own parent`);if(this.wouldCreateCycle(j,J))throw Error("Cannot set parent: would create circular reference");let X=this.parentMap.get(j);if(X!==void 0){let Z=this.childrenMap.get(X);if(Z){let $=Z.indexOf(j);if($!==-1)Z.splice($,1)}}this.parentMap.set(j,J);let Y=this.childrenMap.get(J);if(Y)Y.push(j);else this.childrenMap.set(J,[j]);return this}removeParent(j){let J=this.parentMap.get(j);if(J===void 0)return!1;let X=this.childrenMap.get(J);if(X){let Y=X.indexOf(j);if(Y!==-1)X.splice(Y,1)}return this.parentMap.delete(j),!0}getParent(j){return this.parentMap.get(j)??null}getChildren(j){let J=this.childrenMap.get(j);return J?[...J]:[]}getChildAt(j,J){if(J<0)return null;let X=this.childrenMap.get(j);if(!X||J>=X.length)return null;return X[J]??null}getChildIndex(j,J){let X=this.childrenMap.get(j);if(!X)return-1;return X.indexOf(J)}removeEntity(j){let J=this.parentMap.get(j)??null;if(J!==null){let Z=this.childrenMap.get(J);if(Z){let $=Z.indexOf(j);if($!==-1)Z.splice($,1)}}this.parentMap.delete(j);let X=this.childrenMap.get(j)??[],Y=[...X];for(let Z of X)this.parentMap.delete(Z);return this.childrenMap.delete(j),{oldParent:J,orphanedChildren:Y}}getAncestors(j){let J=[],X=this.parentMap.get(j);while(X!==void 0)J.push(X),X=this.parentMap.get(X);return J}getDescendants(j){let J=[],X=[...this.childrenMap.get(j)??[]];while(X.length>0){let Y=X.shift();if(Y===void 0)continue;J.push(Y);let Z=this.childrenMap.get(Y);if(Z)X.unshift(...Z)}return J}getRoot(j){let J=j,X=this.parentMap.get(J);while(X!==void 0)J=X,X=this.parentMap.get(J);return J}getSiblings(j){let J=this.parentMap.get(j);if(J===void 0)return[];let X=this.childrenMap.get(J);if(!X)return[];return X.filter((Y)=>Y!==j)}isDescendantOf(j,J){if(j===J)return!1;let X=this.parentMap.get(j);while(X!==void 0){if(X===J)return!0;X=this.parentMap.get(X)}return!1}isAncestorOf(j,J){return this.isDescendantOf(J,j)}getRootEntities(){let j=[];for(let J of this.childrenMap.keys())if(!this.parentMap.has(J))j.push(J);return j}wouldCreateCycle(j,J){let X=J;while(X!==void 0){if(X===j)return!0;X=this.parentMap.get(X)}return!1}forEachInHierarchy(j,J){let X=J?.roots??this.getRootEntities(),Y=[];for(let Z of X)Y.push({entityId:Z,parentId:null,depth:0});while(Y.length>0){let Z=Y.shift();if(!Z)break;j(Z.entityId,Z.parentId,Z.depth);let $=this.childrenMap.get(Z.entityId);if($)for(let G of $)Y.push({entityId:G,parentId:Z.entityId,depth:Z.depth+1})}}*hierarchyIterator(j){let J=j?.roots??this.getRootEntities(),X=[];for(let Y of J)X.push({entityId:Y,parentId:null,depth:0});while(X.length>0){let Y=X.shift();if(!Y)break;yield Y;let Z=this.childrenMap.get(Y.entityId);if(Z)for(let $ of Z)X.push({entityId:$,parentId:Y.entityId,depth:Y.depth+1})}}}class A{nextId=1;entities=new Map;componentIndices=new Map;addedCallbacks=new Map;removedCallbacks=new Map;hierarchyManager=new z;changeSeqs=new Map;_changeSeq=0;createEntity(){let j=this.nextId++,J={id:j,components:{}};return this.entities.set(j,J),J}addComponent(j,J,X){let Y=typeof j==="number"?this.entities.get(j):j;if(!Y){let $=typeof j==="number"?j:j.id;throw Error(`Cannot add component '${String(J)}': Entity with ID ${$} does not exist`)}if(Y.components[J]=X,!this.componentIndices.has(J))this.componentIndices.set(J,new Set);this.componentIndices.get(J)?.add(Y.id);let Z=this.addedCallbacks.get(J);if(Z)for(let $ of[...Z])$(X,Y);return this}addComponents(j,J){let X=typeof j==="number"?this.entities.get(j):j;if(!X){let Y=typeof j==="number"?j:j.id;throw Error(`Cannot add components: Entity with ID ${Y} does not exist`)}for(let Y in J)this.addComponent(X,Y,J[Y]);return this}removeComponent(j,J){let X=typeof j==="number"?this.entities.get(j):j;if(!X){let $=typeof j==="number"?j:j.id;throw Error(`Cannot remove component '${String(J)}': Entity with ID ${$} does not exist`)}let Y=X.components[J];delete X.components[J];let Z=this.removedCallbacks.get(J);if(Z&&Y!==void 0)for(let $ of[...Z])$(Y,X);return this.componentIndices.get(J)?.delete(X.id),this}getComponent(j,J){let X=this.entities.get(j);if(!X)throw Error(`Cannot get component '${String(J)}': Entity with ID ${j} does not exist`);return X.components[J]||null}getEntitiesWithQuery(j=[],J=[],X,Y,Z){let $=X!==void 0&&X.length>0&&Y!==void 0,G=Z!==void 0&&Z.length>0;if(j.length===0){if(J.length===0&&!$&&!G)return Array.from(this.entities.values());return Array.from(this.entities.values()).filter((_)=>{if(J.length>0&&!J.every((W)=>!(W in _.components)))return!1;if($){let W=this.changeSeqs.get(_.id);if(!W)return!1;if(!X.some((L)=>(W.get(L)??-1)>Y))return!1}if(G&&!this.parentHasComponents(_.id,Z))return!1;return!0})}let Q=j.reduce((_,W)=>{let L=this.componentIndices.get(W)?.size??0,D=this.componentIndices.get(_)?.size??1/0;return L<D?W:_},j[0]),F=this.componentIndices.get(Q);if(!F||F.size===0)return[];let U=[],V=J.length>0;for(let _ of F){let W=this.entities.get(_);if(W&&j.every((L)=>(L in W.components))&&(!V||J.every((L)=>!(L in W.components)))){if($){let L=this.changeSeqs.get(_);if(!L||!X.some((D)=>(L.get(D)??-1)>Y))continue}if(G&&!this.parentHasComponents(_,Z))continue;U.push(W)}}return U}parentHasComponents(j,J){let X=this.hierarchyManager.getParent(j);if(X===null)return!1;let Y=this.entities.get(X);if(!Y)return!1;for(let Z of J)if(!(Z in Y.components))return!1;return!0}removeEntity(j,J){let X=typeof j==="number"?this.entities.get(j):j;if(!X)return!1;if(J?.cascade??!0){let Z=this.hierarchyManager.getDescendants(X.id);for(let $ of[...Z].reverse())this.removeEntityInternal($)}return this.removeEntityInternal(X.id)}removeEntityInternal(j){let J=this.entities.get(j);if(!J)return!1;this.hierarchyManager.removeEntity(j);for(let X of Object.keys(J.components)){let Y=J.components[X];if(Y!==void 0){let Z=this.removedCallbacks.get(X);if(Z)for(let $ of[...Z])$(Y,J)}this.componentIndices.get(X)?.delete(J.id)}return this.changeSeqs.delete(J.id),this.entities.delete(J.id)}getEntity(j){return this.entities.get(j)}onComponentAdded(j,J){if(!this.addedCallbacks.has(j))this.addedCallbacks.set(j,new Set);return this.addedCallbacks.get(j).add(J),()=>{this.addedCallbacks.get(j)?.delete(J)}}onComponentRemoved(j,J){if(!this.removedCallbacks.has(j))this.removedCallbacks.set(j,new Set);return this.removedCallbacks.get(j).add(J),()=>{this.removedCallbacks.get(j)?.delete(J)}}get changeSeq(){return this._changeSeq}markChanged(j,J){let X=++this._changeSeq,Y=this.changeSeqs.get(j);if(!Y)Y=new Map,this.changeSeqs.set(j,Y);Y.set(J,X)}getChangeSeq(j,J){return this.changeSeqs.get(j)?.get(J)??-1}clearChangeSeqs(j){this.changeSeqs.delete(j)}spawnChild(j,J){let X=this.createEntity();return this.addComponents(X,J),this.setParent(X.id,j),X}setParent(j,J){return this.hierarchyManager.setParent(j,J),this}removeParent(j){return this.hierarchyManager.removeParent(j)}getParent(j){return this.hierarchyManager.getParent(j)}getChildren(j){return this.hierarchyManager.getChildren(j)}getChildAt(j,J){return this.hierarchyManager.getChildAt(j,J)}getChildIndex(j,J){return this.hierarchyManager.getChildIndex(j,J)}getAncestors(j){return this.hierarchyManager.getAncestors(j)}getDescendants(j){return this.hierarchyManager.getDescendants(j)}getRoot(j){return this.hierarchyManager.getRoot(j)}getSiblings(j){return this.hierarchyManager.getSiblings(j)}isDescendantOf(j,J){return this.hierarchyManager.isDescendantOf(j,J)}isAncestorOf(j,J){return this.hierarchyManager.isAncestorOf(j,J)}getRootEntities(){return this.hierarchyManager.getRootEntities()}forEachInHierarchy(j,J){this.hierarchyManager.forEachInHierarchy(j,J)}hierarchyIterator(j){return this.hierarchyManager.hierarchyIterator(j)}}class H{handlers=new Map;subscribe(j,J){return this.addHandler(j,J,!1)}once(j,J){return this.addHandler(j,J,!0)}unsubscribe(j,J){let X=this.handlers.get(j);if(!X)return!1;let Y=X.findIndex((Z)=>Z.callback===J);if(Y===-1)return!1;return X.splice(Y,1),!0}addHandler(j,J,X){if(!this.handlers.has(j))this.handlers.set(j,[]);let Y={callback:J,once:X};return this.handlers.get(j).push(Y),()=>{let Z=this.handlers.get(j);if(Z){let $=Z.indexOf(Y);if($!==-1)Z.splice($,1)}}}publish(j,J){let X=this.handlers.get(j);if(!X)return;let Y=[...X],Z=[];for(let $ of Y)if($.callback(J),$.once)Z.push($);if(Z.length>0)for(let $ of Z){let G=X.indexOf($);if(G!==-1)X.splice(G,1)}}clear(){this.handlers.clear()}clearEvent(j){this.handlers.delete(j)}}function I(j){return typeof j==="object"&&j!==null&&"factory"in j&&typeof j.factory==="function"}function v(j,J){let X=[],Y=new Set,Z=new Set;function $(G,Q=[]){if(Y.has(G))return;if(Z.has(G))throw Error(`Circular resource dependency: ${[...Q,G].join(" -> ")}`);Z.add(G);for(let F of J(G))if(j.includes(F))$(F,[...Q,G]);Z.delete(G),Y.add(G),X.push(G)}for(let G of j)$(G);return X}class P{resources=new Map;resourceFactories=new Map;resourceDependencies=new Map;resourceDisposers=new Map;initializedResourceKeys=new Set;add(j,J){if(I(J)){if(this.resourceFactories.set(j,J.factory),this.resourceDependencies.set(j,J.dependsOn??[]),J.onDispose)this.resourceDisposers.set(j,J.onDispose)}else if(this._isFactoryFunction(J))this.resourceFactories.set(j,J),this.resourceDependencies.set(j,[]);else this.resources.set(j,J),this.initializedResourceKeys.add(j),this.resourceDependencies.set(j,[]);return this}_isFactoryFunction(j){if(typeof j!=="function")return!1;let J=j.toString();if(J.startsWith("class "))return!1;if(J.includes("[native code]"))return!1;if(j.prototype){let X=Object.getOwnPropertyNames(j.prototype);if(X.length>1||X.length===1&&X[0]!=="constructor")return!1}if(j.name&&j.name[0]===j.name[0].toUpperCase()&&j.name.length>1){if(J.includes("this.")||J.includes("new "))return!1}return!0}get(j,J){let X=this.resources.get(j);if(X!==void 0)return X;let Y=this.resourceFactories.get(j);if(Y===void 0)throw Error(`Resource ${String(j)} not found`);let Z=Y(J);if(!(Z instanceof Promise))this.resources.set(j,Z),this.initializedResourceKeys.add(j);return Z}has(j){return this.resources.has(j)||this.resourceFactories.has(j)}remove(j){let J=this.resources.delete(j),X=this.resourceFactories.delete(j);return this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),J||X}getKeys(){let j=new Set([...this.resources.keys(),...this.resourceFactories.keys()]);return Array.from(j)}needsInitialization(j){return this.resourceFactories.has(j)&&!this.initializedResourceKeys.has(j)}getPendingInitializationKeys(){return Array.from(this.resourceFactories.keys()).filter((j)=>!this.initializedResourceKeys.has(j))}async initializeResource(j,J){if(!this.resourceFactories.has(j)||this.initializedResourceKeys.has(j))return;let Y=await this.resourceFactories.get(j)(J);this.resources.set(j,Y),this.initializedResourceKeys.add(j),this.resourceFactories.delete(j)}async initializeResources(j,...J){let X=J.length===0?this.getPendingInitializationKeys():J.map((Z)=>Z);if(X.length===0)return;let Y=v(X,(Z)=>this.resourceDependencies.get(Z)??[]);for(let Z of Y)await this.initializeResource(Z,j)}getDependencies(j){return this.resourceDependencies.get(j)??[]}async disposeResource(j,J){let X=j;if(!this.resources.has(X)&&!this.resourceFactories.has(X))return!1;if(this.initializedResourceKeys.has(X)){let Y=this.resourceDisposers.get(X),Z=this.resources.get(X);if(Y&&Z!==void 0)await Y(Z,J)}return this.resources.delete(X),this.resourceFactories.delete(X),this.resourceDependencies.delete(X),this.resourceDisposers.delete(X),this.initializedResourceKeys.delete(X),!0}async disposeResources(j){let J=Array.from(this.initializedResourceKeys);if(J.length===0)return;let X=v(J,(Y)=>this.resourceDependencies.get(Y)??[]).reverse();for(let Y of X)await this.disposeResource(Y,j)}}class E{assets=new Map;groups=new Map;eventBus=null;setEventBus(j){this.eventBus=j}register(j,J){if(this.assets.set(j,{definition:J,status:"pending"}),J.group){let X=this.groups.get(J.group)??new Set;X.add(j),this.groups.set(J.group,X)}}async loadEagerAssets(){let j=[];for(let[J,X]of this.assets)if(X.definition.eager&&X.status==="pending")j.push(J);await Promise.all(j.map((J)=>this.loadAsset(J)))}async loadAsset(j){let J=j,X=this.assets.get(J);if(!X)throw Error(`Asset '${J}' not found`);if(X.status==="loaded"&&X.value!==void 0)return X.value;if(X.status==="loading"&&X.loadPromise)return X.loadPromise;if(X.status==="failed")X.status="pending";X.status="loading",X.loadPromise=X.definition.loader();try{let Y=await X.loadPromise;return X.value=Y,X.status="loaded",X.loadPromise=void 0,this.eventBus?.publish("assetLoaded",{key:J}),this.checkGroupProgress(X.definition.group),Y}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));throw X.status="failed",X.error=Z,X.loadPromise=void 0,this.eventBus?.publish("assetFailed",{key:J,error:Z}),Z}}async loadAssetGroup(j){let J=this.groups.get(j);if(!J||J.size===0)throw Error(`Asset group '${j}' not found or empty`);await Promise.all(Array.from(J).map((X)=>this.loadAsset(X)))}get(j){let J=j,X=this.assets.get(J);if(!X)throw Error(`Asset '${J}' not found`);if(X.status!=="loaded"||X.value===void 0)throw Error(`Asset '${J}' is not loaded (status: ${X.status})`);return X.value}getOrUndefined(j){let J=j,X=this.assets.get(J);if(!X||X.status!=="loaded")return;return X.value}getHandle(j){let J=j,X=this.assets.get(J);if(!X)throw Error(`Asset '${J}' not found`);let Y=this;return{get status(){return X.status},get isLoaded(){return X.status==="loaded"},get(){return Y.get(j)},getOrUndefined(){return Y.getOrUndefined(j)}}}getStatus(j){let J=j,X=this.assets.get(J);if(!X)throw Error(`Asset '${J}' not found`);return X.status}isLoaded(j){let J=j;return this.assets.get(J)?.status==="loaded"}isGroupLoaded(j){let J=this.groups.get(j);if(!J||J.size===0)return!1;for(let X of J){let Y=this.assets.get(X);if(!Y||Y.status!=="loaded")return!1}return!0}getGroupProgress(j){let J=this.groups.get(j);if(!J||J.size===0)return 0;let X=0;for(let Y of J)if(this.assets.get(Y)?.status==="loaded")X++;return X/J.size}getGroupProgressDetails(j){let J=this.groups.get(j);if(!J||J.size===0)return{loaded:0,total:0,progress:0};let X=0;for(let Z of J)if(this.assets.get(Z)?.status==="loaded")X++;let Y=J.size;return{loaded:X,total:Y,progress:X/Y}}checkGroupProgress(j){if(!j||!this.eventBus)return;let J=this.getGroupProgressDetails(j);if(this.eventBus.publish("assetGroupProgress",{group:j,...J}),J.loaded===J.total)this.eventBus.publish("assetGroupLoaded",{group:j})}createResource(){let j=this;return{getStatus(J){return j.getStatus(J)},isLoaded(J){return j.isLoaded(J)},isGroupLoaded(J){return j.isGroupLoaded(J)},getGroupProgress(J){return j.getGroupProgress(J)},get(J){return j.get(J)},getOrUndefined(J){return j.getOrUndefined(J)},getHandle(J){return j.getHandle(J)}}}getKeys(){return Array.from(this.assets.keys())}getGroupNames(){return Array.from(this.groups.keys())}getGroupKeys(j){let J=this.groups.get(j);return J?Array.from(J):[]}}class O{manager;constructor(j){this.manager=j}add(j,J){return this.manager.register(j,{loader:J,eager:!0}),this}addWithConfig(j,J){return this.manager.register(j,J),this}addGroup(j,J){for(let[X,Y]of Object.entries(J))this.manager.register(X,{loader:Y,eager:!1,group:j});return this}getManager(){return this.manager}}function T(j){return new O(j??new E)}class R{screens=new Map;currentScreen=null;screenStack=[];eventBus=null;assetManager=null;ecs=null;setDependencies(j,J,X){this.eventBus=j,this.assetManager=J,this.ecs=X}register(j,J){this.screens.set(j,{definition:J})}async setScreen(j,J){let X=j,Y=this.screens.get(X);if(!Y)throw Error(`Screen '${X}' not found`);await this.verifyRequiredAssets(Y.definition);while(this.screenStack.length>0){let $=this.screenStack.pop();if($)await this.exitScreen($.name)}if(this.currentScreen)await this.exitScreen(this.currentScreen.name);let Z=Y.definition.initialState(J);this.currentScreen={name:j,config:J,state:Z},await Y.definition.onEnter?.(J,this.ecs),this.eventBus?.publish("screenEnter",{screen:X,config:J})}async pushScreen(j,J){let X=j,Y=this.screens.get(X);if(!Y)throw Error(`Screen '${X}' not found`);if(await this.verifyRequiredAssets(Y.definition),this.currentScreen)this.screenStack.push(this.currentScreen);let Z=Y.definition.initialState(J);this.currentScreen={name:j,config:J,state:Z},await Y.definition.onEnter?.(J,this.ecs),this.eventBus?.publish("screenPush",{screen:X,config:J})}async popScreen(){if(this.screenStack.length===0)throw Error("Cannot pop screen: stack is empty");if(this.currentScreen){let j=this.currentScreen.name;await this.exitScreen(j),this.eventBus?.publish("screenPop",{screen:j})}this.currentScreen=this.screenStack.pop()??null}async exitScreen(j){let J=this.screens.get(j);if(J?.definition.onExit)await J.definition.onExit(this.ecs);this.eventBus?.publish("screenExit",{screen:j})}async verifyRequiredAssets(j){if(!this.assetManager)return;if(j.requiredAssets){for(let J of j.requiredAssets)if(!this.assetManager.isLoaded(J))await this.assetManager.loadAsset(J)}if(j.requiredAssetGroups){for(let J of j.requiredAssetGroups)if(!this.assetManager.isGroupLoaded(J))await this.assetManager.loadAssetGroup(J)}}getCurrentScreen(){return this.currentScreen?.name??null}getConfig(){if(!this.currentScreen)throw Error("No current screen");return this.currentScreen.config}getConfigOrNull(){return this.currentScreen?.config??null}getState(){if(!this.currentScreen)throw Error("No current screen");return this.currentScreen.state}getStateOrNull(){return this.currentScreen?.state??null}updateState(j){if(!this.currentScreen)throw Error("No current screen");let J=typeof j==="function"?j(this.currentScreen.state):j;this.currentScreen.state={...this.currentScreen.state,...J}}getStackDepth(){return this.screenStack.length}isOverlay(){return this.screenStack.length>0}isActive(j){if(this.currentScreen?.name===j)return!0;return this.screenStack.some((J)=>J.name===j)}isCurrent(j){return this.currentScreen?.name===j}createResource(){let j=this;return{get current(){return j.getCurrentScreen()},get config(){return j.getConfigOrNull()},get state(){return j.getStateOrNull()},set state(J){if(j.currentScreen)j.currentScreen.state=J},get stack(){return j.screenStack},get isOverlay(){return j.isOverlay()},get stackDepth(){return j.getStackDepth()},isActive(J){return j.isActive(J)},isCurrent(J){return j.isCurrent(J)}}}getScreenNames(){return Array.from(this.screens.keys())}hasScreen(j){return this.screens.has(j)}}class S{manager;constructor(j){this.manager=j}add(j,J){return this.manager.register(j,J),this}getManager(){return this.manager}}function q(j){return new S(j??new R)}class x{queries=new Map;entityManager;_hasParentHasQueries=!1;constructor(j){this.entityManager=j}get hasParentHasQueries(){return this._hasParentHasQueries}addQuery(j,J){let X={definition:J,matchingEntities:new Set};if(this.queries.set(j,X),J.parentHas?.length)this._hasParentHasQueries=!0;let Y=this.entityManager.getEntitiesWithQuery(J.with,J.without??[]);for(let Z of Y)if(this.entityMatchesQuery(Z,X.definition))X.matchingEntities.add(Z.id),X.definition.onEnter?.(Z)}removeQuery(j){let J=this.queries.delete(j);if(J)this._recalcParentHasFlag();return J}entityMatchesQuery(j,J){for(let X of J.with)if(!(X in j.components))return!1;if(J.without){for(let X of J.without)if(X in j.components)return!1}if(J.parentHas?.length){let X=this.entityManager.getParent(j.id);if(X===null)return!1;let Y=this.entityManager.getEntity(X);if(!Y)return!1;for(let Z of J.parentHas)if(!(Z in Y.components))return!1}return!0}onComponentAdded(j,J){for(let[X,Y]of this.queries){let Z=Y.matchingEntities.has(j.id),$=this.entityMatchesQuery(j,Y.definition);if(!Z&&$)Y.matchingEntities.add(j.id),Y.definition.onEnter?.(j);else if(Z&&!$)Y.matchingEntities.delete(j.id),Y.definition.onExit?.(j.id)}if(this._hasParentHasQueries)this._recheckChildren(j.id)}onComponentRemoved(j,J){for(let[X,Y]of this.queries){let Z=Y.matchingEntities.has(j.id),$=this.entityMatchesQuery(j,Y.definition);if(Z&&!$)Y.matchingEntities.delete(j.id),Y.definition.onExit?.(j.id);else if(!Z&&$)Y.matchingEntities.add(j.id),Y.definition.onEnter?.(j)}if(this._hasParentHasQueries)this._recheckChildren(j.id)}onEntityRemoved(j){for(let[J,X]of this.queries)if(X.matchingEntities.has(j))X.matchingEntities.delete(j),X.definition.onExit?.(j)}recheckEntity(j){for(let[J,X]of this.queries){let Y=X.matchingEntities.has(j.id),Z=this.entityMatchesQuery(j,X.definition);if(!Y&&Z)X.matchingEntities.add(j.id),X.definition.onEnter?.(j);else if(Y&&!Z)X.matchingEntities.delete(j.id),X.definition.onExit?.(j.id)}}_recheckChildren(j){let J=this.entityManager.getChildren(j);for(let X of J){let Y=this.entityManager.getEntity(X);if(Y)this.recheckEntity(Y)}}_recalcParentHasFlag(){this._hasParentHasQueries=!1;for(let[,j]of this.queries)if(j.definition.parentHas?.length){this._hasParentHasQueries=!0;return}}}class M{commands=[];removeEntity(j,J){this.commands.push((X)=>{X.removeEntity(j,J)})}addComponent(j,J,X){this.commands.push((Y)=>{Y.entityManager.addComponent(j,J,X)})}removeComponent(j,J){this.commands.push((X)=>{X.entityManager.removeComponent(j,J)})}spawn(j){this.commands.push((J)=>{J.spawn(j)})}spawnChild(j,J){this.commands.push((X)=>{X.spawnChild(j,J)})}addComponents(j,J){this.commands.push((X)=>{X.entityManager.addComponents(j,J)})}setParent(j,J){this.commands.push((X)=>{X.setParent(j,J)})}markChanged(j,J){this.commands.push((X)=>{X.markChanged(j,J)})}removeParent(j){this.commands.push((J)=>{J.removeParent(j)})}playback(j){for(let J of this.commands)try{J(j)}catch(X){console.warn("CommandBuffer: Command failed during playback:",X)}this.commands=[]}clear(){this.commands=[]}get length(){return this.commands.length}}class w{_label;_ecspresso;_bundle;queries={};processFunction;detachFunction;initializeFunction;eventHandlers;_priority=0;_phase="update";_isRegistered=!1;_groups=[];_inScreens;_excludeScreens;_requiredAssets;constructor(j,J=null,X=null){this._label=j;this._ecspresso=J;this._bundle=X}get label(){return this._label}get bundle(){return this._bundle}get ecspresso(){return this._ecspresso}_autoRegister(){if(this._isRegistered||!this._ecspresso)return;let j=this._buildSystemObject();C(j,this._ecspresso),this._isRegistered=!0}_buildSystemObject(){return this._createSystemObject()}_createSystemObject(){let j={label:this._label,entityQueries:this.queries,priority:this._priority,phase:this._phase};if(this.processFunction)j.process=this.processFunction;if(this.detachFunction)j.onDetach=this.detachFunction;if(this.initializeFunction)j.onInitialize=this.initializeFunction;if(this.eventHandlers)j.eventHandlers=this.eventHandlers;if(this._groups.length>0)j.groups=[...this._groups];if(this._inScreens)j.inScreens=this._inScreens;if(this._excludeScreens)j.excludeScreens=this._excludeScreens;if(this._requiredAssets)j.requiredAssets=this._requiredAssets;return j}setPriority(j){return this._priority=j,this}inPhase(j){return this._phase=j,this}inGroup(j){if(!this._groups.includes(j))this._groups.push(j);return this}inScreens(j){return this._inScreens=[...j],this}excludeScreens(j){return this._excludeScreens=[...j],this}requiresAssets(j){return this._requiredAssets=[...j],this}addQuery(j,J){let X=this;return X.queries={...this.queries,[j]:J},X}setProcess(j){return this.processFunction=j,this}registerAndContinue(){if(!this._ecspresso)throw Error(`Cannot register system '${this._label}': SystemBuilder is not attached to an ECSpresso instance. Use Bundle.addSystem() or ECSpresso.addSystem() instead.`);return this._autoRegister(),this._ecspresso}and(){if(this._ecspresso)return this._autoRegister(),this._ecspresso;if(this._bundle)return this._bundle;throw Error(`Cannot use and() on system '${this._label}': not attached to ECSpresso or Bundle.`)}setOnDetach(j){return this.detachFunction=j,this}setOnInitialize(j){return this.initializeFunction=j,this}setEventHandlers(j){return this.eventHandlers=j,this}build(j){let J=this._createSystemObject();if(this._ecspresso)C(J,this._ecspresso);if(j)C(J,j);return this}}function C(j,J){J._registerSystem(j)}function f(j,J){return new w(j,J)}function b(j,J){return new w(j,null,J)}var N="0.10.0";var k=["preUpdate","fixedUpdate","update","postUpdate","render"],p={};class K{static VERSION=N;_entityManager;_eventBus;_resourceManager;_commandBuffer;_systems=[];_phaseSystems={preUpdate:[],fixedUpdate:[],update:[],postUpdate:[],render:[]};_installedBundles=new Set;_disabledGroups=new Set;_assetManager=null;_screenManager=null;_reactiveQueryManager;_postUpdateHooks=[];_currentTick=0;_systemLastSeqs=new Map;_changeThreshold=0;_fixedDt=0.016666666666666666;_fixedAccumulator=0;_interpolationAlpha=0;_maxFixedSteps=8;constructor(){this._entityManager=new A,this._eventBus=new H,this._resourceManager=new P,this._reactiveQueryManager=new x(this._entityManager),this._commandBuffer=new M,this._setupReactiveQueryHooks()}_setupReactiveQueryHooks(){let j=0,J=new Set,X=()=>{for(let U of J){let V=this._entityManager.getEntity(U);if(V)this._reactiveQueryManager.recheckEntity(V)}J.clear()},Y=this._entityManager.addComponent.bind(this._entityManager);this._entityManager.addComponent=(U,V,_)=>{let W=Y(U,V,_),L=typeof U==="number"?U:U.id;if(this._entityManager.markChanged(L,V),j>0)J.add(L);else{let D=this._entityManager.getEntity(L);if(D)this._reactiveQueryManager.onComponentAdded(D,V)}return W};let Z=this._entityManager.addComponents.bind(this._entityManager);this._entityManager.addComponents=(U,V)=>{j++;let _=Z(U,V);if(j--,j===0)X();return _};let $=this._entityManager.removeComponent.bind(this._entityManager);this._entityManager.removeComponent=(U,V)=>{let _=typeof U==="number"?U:U.id,W=this._entityManager.getEntity(_),L=$(U,V);if(W)this._reactiveQueryManager.onComponentRemoved(W,V);return L};let G=this._entityManager.setParent.bind(this._entityManager);this._entityManager.setParent=(U,V)=>{let _=G(U,V);if(this._reactiveQueryManager.hasParentHasQueries){let W=this._entityManager.getEntity(U);if(W)this._reactiveQueryManager.recheckEntity(W)}return _};let Q=this._entityManager.removeParent.bind(this._entityManager);this._entityManager.removeParent=(U)=>{let V=Q(U);if(this._reactiveQueryManager.hasParentHasQueries){let _=this._entityManager.getEntity(U);if(_)this._reactiveQueryManager.recheckEntity(_)}return V};let F=this._entityManager.removeEntity.bind(this._entityManager);this._entityManager.removeEntity=(U,V)=>{let _=typeof U==="number"?U:U.id;if(this._entityManager.getEntity(_)){if(V?.cascade??!0){let D=this._entityManager.getDescendants(_);for(let h of D)this._reactiveQueryManager.onEntityRemoved(h)}this._reactiveQueryManager.onEntityRemoved(_)}return F(U,V)}}static create(){return new g}addSystem(j){return f(j,this)}update(j){let J=this._screenManager?.getCurrentScreen()??null;this._executePhase(this._phaseSystems.preUpdate,j,J),this._commandBuffer.playback(this),this._fixedAccumulator+=j;let X=0;while(this._fixedAccumulator>=this._fixedDt&&X<this._maxFixedSteps)this._executePhase(this._phaseSystems.fixedUpdate,this._fixedDt,J),this._commandBuffer.playback(this),this._fixedAccumulator-=this._fixedDt,X++;if(this._fixedAccumulator>=this._fixedDt)this._fixedAccumulator=0;this._interpolationAlpha=this._fixedAccumulator/this._fixedDt,this._executePhase(this._phaseSystems.update,j,J),this._commandBuffer.playback(this),this._executePhase(this._phaseSystems.postUpdate,j,J),this._commandBuffer.playback(this);for(let Y of this._postUpdateHooks)Y(this,j);this._executePhase(this._phaseSystems.render,j,J),this._commandBuffer.playback(this),this._changeThreshold=this._entityManager.changeSeq,this._currentTick++}_executePhase(j,J,X){for(let Y of j){if(!Y.process)continue;if(Y.groups?.length){let F=!1;for(let U of Y.groups)if(this._disabledGroups.has(U)){F=!0;break}if(F)continue}if(Y.inScreens?.length){if(X===null||!Y.inScreens.includes(X))continue}if(Y.excludeScreens?.length){if(X!==null&&Y.excludeScreens.includes(X))continue}if(Y.requiredAssets?.length&&this._assetManager){let F=!0;for(let U of Y.requiredAssets)if(!this._assetManager.isLoaded(U)){F=!1;break}if(!F)continue}let Z=this._systemLastSeqs.get(Y)??0;this._changeThreshold=Z;let $={},G=!1,Q=!1;if(Y.entityQueries)for(let F in Y.entityQueries){Q=!0;let U=Y.entityQueries[F];if(U){if($[F]=this._entityManager.getEntitiesWithQuery(U.with,U.without||[],U.changed,U.changed?this._changeThreshold:void 0,U.parentHas),$[F].length)G=!0}}if(G)Y.process($,J,this);else if(!Q)Y.process(p,J,this);this._systemLastSeqs.set(Y,this._entityManager.changeSeq)}}async initialize(){if(await this.initializeResources(),this._assetManager)this._assetManager.setEventBus(this._eventBus),await this._assetManager.loadEagerAssets(),this._resourceManager.add("$assets",this._assetManager.createResource());if(this._screenManager)this._screenManager.setDependencies(this._eventBus,this._assetManager,this),this._resourceManager.add("$screen",this._screenManager.createResource());for(let j of this._systems)await j.onInitialize?.(this)}async initializeResources(...j){await this._resourceManager.initializeResources(this,...j)}_rebuildPhaseSystems(){for(let j of k)this._phaseSystems[j]=[];for(let j of this._systems){let J=j.phase??"update";this._phaseSystems[J].push(j)}for(let j of k)this._phaseSystems[j].sort((J,X)=>{let Y=J.priority??0;return(X.priority??0)-Y})}updateSystemPriority(j,J){let X=this._systems.find((Y)=>Y.label===j);if(!X)return!1;return X.priority=J,this._rebuildPhaseSystems(),!0}updateSystemPhase(j,J){let X=this._systems.find((Y)=>Y.label===j);if(!X)return!1;return X.phase=J,this._rebuildPhaseSystems(),!0}get interpolationAlpha(){return this._interpolationAlpha}get fixedDt(){return this._fixedDt}disableSystemGroup(j){this._disabledGroups.add(j)}enableSystemGroup(j){this._disabledGroups.delete(j)}isSystemGroupEnabled(j){return!this._disabledGroups.has(j)}getSystemsInGroup(j){return this._systems.filter((J)=>J.groups?.includes(j)).map((J)=>J.label)}removeSystem(j){let J=this._systems.findIndex((Y)=>Y.label===j);if(J===-1)return!1;let X=this._systems[J];if(!X)return!1;if(X.onDetach)X.onDetach(this);return this._systems.splice(J,1),this._systemLastSeqs.delete(X),this._rebuildPhaseSystems(),!0}_registerSystem(j){if(this._systems.push(j),this._systemLastSeqs.set(j,this._changeThreshold),this._rebuildPhaseSystems(),!j.eventHandlers)return;for(let J in j.eventHandlers){let X=j.eventHandlers[J]?.handler;if(X)this._eventBus.subscribe(J,(Y)=>{X(Y,this)})}}hasResource(j){return this._resourceManager.has(j)}getResource(j){let J=this._resourceManager.get(j,this);if(!J)throw Error(`Resource '${String(j)}' not found. Available resources: [${this.getResourceKeys().map((X)=>String(X)).join(", ")}]`);return J}addResource(j,J){return this._resourceManager.add(j,J),this}removeResource(j){return this._resourceManager.remove(j)}async disposeResource(j){return this._resourceManager.disposeResource(j,this)}async disposeResources(){return this._resourceManager.disposeResources(this)}updateResource(j,J){let X=this.getResource(j),Y=J(X);return this._resourceManager.add(j,Y),this}getResourceKeys(){return this._resourceManager.getKeys()}resourceNeedsInitialization(j){return this._resourceManager.needsInitialization(j)}hasComponent(j,J){return this._entityManager.getComponent(j,J)!==null}spawn(j){let J=this._entityManager.createEntity();return this._entityManager.addComponents(J,j),J}getEntitiesWithQuery(j,J=[],X,Y){return this._entityManager.getEntitiesWithQuery(j,J,X,X?this._changeThreshold:void 0,Y)}getSingleton(j,J=[]){let X=this._entityManager.getEntitiesWithQuery(j,J);if(X.length===0)throw Error(`getSingleton: no entity matches query with=[${String(j)}] without=[${String(J)}]`);if(X.length>1)throw Error(`getSingleton: expected 1 entity but found ${X.length} matching query with=[${String(j)}] without=[${String(J)}]`);return X[0]}tryGetSingleton(j,J=[]){let X=this._entityManager.getEntitiesWithQuery(j,J);if(X.length===0)return;if(X.length>1)throw Error(`tryGetSingleton: expected 0 or 1 entity but found ${X.length} matching query with=[${String(j)}] without=[${String(J)}]`);return X[0]}removeEntity(j,J){return this._entityManager.removeEntity(j,J)}spawnChild(j,J){let X=this._entityManager.spawnChild(j,J);return this._emitHierarchyChanged(X.id,null,j),X}setParent(j,J){let X=this._entityManager.getParent(j);return this._entityManager.setParent(j,J),this._emitHierarchyChanged(j,X,J),this}removeParent(j){let J=this._entityManager.getParent(j),X=this._entityManager.removeParent(j);if(X)this._emitHierarchyChanged(j,J,null);return X}getParent(j){return this._entityManager.getParent(j)}getChildren(j){return this._entityManager.getChildren(j)}getChildAt(j,J){return this._entityManager.getChildAt(j,J)}getChildIndex(j,J){return this._entityManager.getChildIndex(j,J)}getAncestors(j){return this._entityManager.getAncestors(j)}getDescendants(j){return this._entityManager.getDescendants(j)}getRoot(j){return this._entityManager.getRoot(j)}getSiblings(j){return this._entityManager.getSiblings(j)}isDescendantOf(j,J){return this._entityManager.isDescendantOf(j,J)}isAncestorOf(j,J){return this._entityManager.isAncestorOf(j,J)}getRootEntities(){return this._entityManager.getRootEntities()}forEachInHierarchy(j,J){this._entityManager.forEachInHierarchy(j,J)}hierarchyIterator(j){return this._entityManager.hierarchyIterator(j)}_emitHierarchyChanged(j,J,X){this._eventBus.publish("hierarchyChanged",{entityId:j,oldParent:J,newParent:X})}get installedBundles(){return Array.from(this._installedBundles)}get entityManager(){return this._entityManager}get eventBus(){return this._eventBus}get commands(){return this._commandBuffer}get currentTick(){return this._currentTick}get changeThreshold(){return this._changeThreshold}markChanged(j,J){this._entityManager.markChanged(j,J)}onComponentAdded(j,J){return this._entityManager.onComponentAdded(j,J)}onComponentRemoved(j,J){return this._entityManager.onComponentRemoved(j,J)}addReactiveQuery(j,J){this._reactiveQueryManager.addQuery(j,J)}removeReactiveQuery(j){return this._reactiveQueryManager.removeQuery(j)}on(j,J){return this._eventBus.subscribe(j,J)}off(j,J){return this._eventBus.unsubscribe(j,J)}onPostUpdate(j){return this._postUpdateHooks.push(j),()=>{let J=this._postUpdateHooks.indexOf(j);if(J!==-1)this._postUpdateHooks.splice(J,1)}}getAsset(j){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager.get(j)}getAssetOrUndefined(j){return this._assetManager?.getOrUndefined(j)}getAssetHandle(j){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager.getHandle(j)}isAssetLoaded(j){return this._assetManager?.isLoaded(j)??!1}async loadAsset(j){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager.loadAsset(j)}async loadAssetGroup(j){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager.loadAssetGroup(j)}isAssetGroupLoaded(j){return this._assetManager?.isGroupLoaded(j)??!1}getAssetGroupProgress(j){return this._assetManager?.getGroupProgress(j)??0}async setScreen(j,J){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.setScreen(j,J)}async pushScreen(j,J){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.pushScreen(j,J)}async popScreen(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.popScreen()}getCurrentScreen(){return this._screenManager?.getCurrentScreen()??null}getScreenConfig(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.getConfig()}getScreenConfigOrNull(){return this._screenManager?.getConfigOrNull()??null}getScreenState(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager.getState()}getScreenStateOrNull(){return this._screenManager?.getStateOrNull()??null}updateScreenState(j){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");this._screenManager.updateState(j)}isCurrentScreen(j){return this._screenManager?.isCurrent(j)??!1}isScreenActive(j){return this._screenManager?.isActive(j)??!1}getScreenStackDepth(){return this._screenManager?.getStackDepth()??0}_setAssetManager(j){this._assetManager=j}_setScreenManager(j){this._screenManager=j}_setFixedDt(j){this._fixedDt=j}_installBundle(j){if(this._installedBundles.has(j.id))return this;this._installedBundles.add(j.id),j.registerSystemsWithEcspresso(this);let J=j.getResources();for(let[X,Y]of J.entries())this._resourceManager.add(X,Y);if(this._assetManager){let X=j.getAssets();for(let[Y,Z]of X.entries())this._assetManager.register(Y,Z)}if(this._screenManager){let X=j.getScreens();for(let[Y,Z]of X.entries())this._screenManager.register(Y,Z)}return this}}class g{ecspresso;assetConfigurator=null;screenConfigurator=null;pendingResources=[];_fixedDt=null;constructor(){this.ecspresso=new K}withBundle(j){return this.ecspresso._installBundle(j),this}withResource(j,J){return this.pendingResources.push({key:j,value:J}),this}withAssets(j){let J=T();return j(J),this.assetConfigurator=J,this}withScreens(j){let J=q();return j(J),this.screenConfigurator=J,this}withFixedTimestep(j){return this._fixedDt=j,this}build(){for(let{key:j,value:J}of this.pendingResources)this.ecspresso.addResource(j,J);if(this.assetConfigurator)this.ecspresso._setAssetManager(this.assetConfigurator.getManager());if(this.screenConfigurator)this.ecspresso._setScreenManager(this.screenConfigurator.getManager());if(this._fixedDt!==null)this.ecspresso._setFixedDt(this._fixedDt);return this.ecspresso}}function m(){return`bundle_${Date.now().toString(36)}_${Math.random().toString(36).substring(2,9)}`}class B{_systems=[];_resources=new Map;_assets=new Map;_assetGroups=new Map;_screens=new Map;_id;constructor(j){this._id=j||m()}get id(){return this._id}set id(j){this._id=j}addSystem(j){if(typeof j==="string"){let J=b(j,this);return this._systems.push(J),J}else return this._systems.push(j),j}addResource(j,J){return this._resources.set(j,J),this}addAsset(j,J,X){return this._assets.set(j,{loader:J,eager:X?.eager??!0,group:X?.group}),this}addAssetGroup(j,J){let X=new Map;for(let[Y,Z]of Object.entries(J))X.set(Y,Z),this._assets.set(Y,{loader:Z,eager:!1,group:j});return this._assetGroups.set(j,X),this}addScreen(j,J){return this._screens.set(j,J),this}getAssets(){return new Map(this._assets)}getScreens(){return new Map(this._screens)}_setResource(j,J){this._resources.set(j,J)}_setAsset(j,J){this._assets.set(j,J)}_setScreen(j,J){this._screens.set(j,J)}getSystems(){return this._systems.map((j)=>j.build())}registerSystemsWithEcspresso(j){for(let J of this._systems)J.build(j)}getResources(){return new Map(this._resources)}getResource(j){return this._resources.get(j)}getSystemBuilders(){return[...this._systems]}hasResource(j){return this._resources.has(j)}}function l(j,...J){if(J.length===0)return new B(j);let X=new B(j);for(let Y of J){for(let Z of Y.getSystemBuilders())X.addSystem(Z);for(let[Z,$]of Y.getResources().entries())X._setResource(Z,$);for(let[Z,$]of Y.getAssets().entries())X._setAsset(Z,$);for(let[Z,$]of Y.getScreens().entries())X._setScreen(Z,$)}return X}function Mj(j){return j}var kj=K;export{l as mergeBundles,kj as default,q as createScreenConfigurator,Mj as createQueryDefinition,T as createAssetConfigurator,w as SystemBuilder,R as ScreenManager,P as ResourceManager,z as HierarchyManager,H as EventBus,A as EntityManager,M as CommandBuffer,B as Bundle,E as AssetManager};
2
2
 
3
- //# debugId=92E5E4E30405F52564756E2164756E21
3
+ //# debugId=D54EBCF6A31F22DB64756E2164756E21
4
4
  //# sourceMappingURL=index.js.map