UNPKG

@esengine/ecs-framework

Version:

用于Laya、Cocos Creator等JavaScript游戏引擎的高性能ECS框架

1 lines 100 kB
class t{constructor(){this._enabled=!1}get enabled(){return this._enabled}set enabled(t){this.setEnabled(t)}setEnabled(t){this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled())}onEnabled(){}onDisabled(){}update(){}}class e{static update(t){this.unscaledDeltaTime=t,this.deltaTime=t*this.timeScale,this.unscaledTotalTime+=this.unscaledDeltaTime,this.totalTime+=this.deltaTime,this.frameCount++}static sceneChanged(){this.frameCount=0,this.totalTime=0,this.unscaledTotalTime=0,this.deltaTime=0,this.unscaledDeltaTime=0}static checkEvery(t,e){return this.totalTime-e>=t}}e.deltaTime=0,e.unscaledDeltaTime=0,e.totalTime=0,e.unscaledTotalTime=0,e.timeScale=1,e.frameCount=0;class s{constructor(){this._timeInSeconds=0,this._repeats=!1,this._isDone=!1,this._elapsedTime=0}getContext(){return this.context}get isDone(){return this._isDone}get elapsedTime(){return this._elapsedTime}reset(){this._elapsedTime=0}stop(){this._isDone=!0}tick(){return!this._isDone&&this._elapsedTime>this._timeInSeconds&&(this._elapsedTime-=this._timeInSeconds,this._onTime(this),this._isDone||this._repeats||(this._isDone=!0)),this._elapsedTime+=e.deltaTime,this._isDone}initialize(t,e,s,n){this._timeInSeconds=t,this._repeats=e,this.context=s,this._onTime=n.bind(s)}unload(){this.context=null,this._onTime=null}}class n extends t{constructor(){super(...arguments),this._timers=[]}update(){for(let t=this._timers.length-1;t>=0;t--)this._timers[t].tick()&&(this._timers[t].unload(),this._timers.splice(t,1))}schedule(t,e,n,i){let o=new s;return o.initialize(t,e,n,i),this._timers.push(o),o}}var i,o,r,a,c,h,m;!function(t){t.HIGH_EXECUTION_TIME="high_execution_time",t.HIGH_MEMORY_USAGE="high_memory_usage",t.HIGH_CPU_USAGE="high_cpu_usage",t.FREQUENT_GC="frequent_gc",t.LOW_FPS="low_fps",t.HIGH_ENTITY_COUNT="high_entity_count"}(i||(i={}));class l{static get instance(){return l._instance||(l._instance=new l),l._instance}constructor(){this._systemData=new Map,this._systemStats=new Map,this._warnings=[],this._isEnabled=!1,this._maxRecentSamples=60,this._maxWarnings=100,this._thresholds={executionTime:{warning:16.67,critical:33.33},memoryUsage:{warning:100,critical:200},cpuUsage:{warning:70,critical:90},fps:{warning:45,critical:30},entityCount:{warning:1e3,critical:5e3}},this._fpsHistory=[],this._lastFrameTime=0,this._frameCount=0,this._fpsUpdateInterval=1e3,this._lastFpsUpdate=0,this._currentFps=60,this._memoryCheckInterval=5e3,this._lastMemoryCheck=0,this._memoryHistory=[],this._gcCount=0,this._lastGcCheck=0,this._gcCheckInterval=1e3}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}get isEnabled(){return this._isEnabled}startMonitoring(t){return this._isEnabled?performance.now():0}endMonitoring(t,e,s=0){if(!this._isEnabled||0===e)return;const n=performance.now(),i=n-e,o={name:t,executionTime:i,entityCount:s,averageTimePerEntity:s>0?i/s:0,lastUpdateTime:n};this._systemData.set(t,o),this.updateStats(t,i)}updateStats(t,e){let s=this._systemStats.get(t);s||(s={totalTime:0,averageTime:0,minTime:Number.MAX_VALUE,maxTime:0,executionCount:0,recentTimes:[],standardDeviation:0,percentile95:0,percentile99:0},this._systemStats.set(t,s)),s.totalTime+=e,s.executionCount++,s.averageTime=s.totalTime/s.executionCount,s.minTime=Math.min(s.minTime,e),s.maxTime=Math.max(s.maxTime,e),s.recentTimes.push(e),s.recentTimes.length>this._maxRecentSamples&&s.recentTimes.shift(),this.calculateAdvancedStats(s)}calculateAdvancedStats(t){if(0===t.recentTimes.length)return;const e=t.recentTimes.reduce(((t,e)=>t+e),0)/t.recentTimes.length,s=t.recentTimes.reduce(((t,s)=>t+Math.pow(s-e,2)),0)/t.recentTimes.length;t.standardDeviation=Math.sqrt(s);const n=[...t.recentTimes].sort(((t,e)=>t-e)),i=n.length;t.percentile95=n[Math.floor(.95*i)]||0,t.percentile99=n[Math.floor(.99*i)]||0}getSystemData(t){return this._systemData.get(t)}getSystemStats(t){return this._systemStats.get(t)}getAllSystemData(){return new Map(this._systemData)}getAllSystemStats(){return new Map(this._systemStats)}getPerformanceReport(){if(!this._isEnabled)return"Performance monitoring is disabled.";const t=[];t.push("=== ECS Performance Report ==="),t.push("");const e=Array.from(this._systemStats.entries()).sort(((t,e)=>e[1].averageTime-t[1].averageTime));for(const[s,n]of e){const e=this._systemData.get(s);t.push(`System: ${s}`),t.push(` Current: ${e?.executionTime.toFixed(2)}ms (${e?.entityCount} entities)`),t.push(` Average: ${n.averageTime.toFixed(2)}ms`),t.push(` Min/Max: ${n.minTime.toFixed(2)}ms / ${n.maxTime.toFixed(2)}ms`),t.push(` Total: ${n.totalTime.toFixed(2)}ms (${n.executionCount} calls)`),e?.averageTimePerEntity&&e.averageTimePerEntity>0&&t.push(` Per Entity: ${e.averageTimePerEntity.toFixed(4)}ms`),t.push("")}const s=Array.from(this._systemData.values()).reduce(((t,e)=>t+e.executionTime),0);return t.push(`Total Frame Time: ${s.toFixed(2)}ms`),t.push(`Systems Count: ${this._systemData.size}`),t.join("\n")}reset(){this._systemData.clear(),this._systemStats.clear()}resetSystem(t){this._systemData.delete(t),this._systemStats.delete(t)}getPerformanceWarnings(t=16.67){const e=[];for(const[s,n]of this._systemData.entries())n.executionTime>t&&e.push(`${s}: ${n.executionTime.toFixed(2)}ms (>${t}ms)`);return e}setMaxRecentSamples(t){this._maxRecentSamples=t;for(const e of this._systemStats.values())for(;e.recentTimes.length>t;)e.recentTimes.shift()}}class u{constructor(t,e=100,s=1024){this._objects=[],this._createFn=t,this._maxSize=e,this._objectSize=s,this._stats={size:0,maxSize:e,totalCreated:0,totalObtained:0,totalReleased:0,hitRate:0,estimatedMemoryUsage:0}}static getPool(t,e=100,s=1024){let n=this._pools.get(t);return n||(n=new u((()=>new t),e,s),this._pools.set(t,n)),n}obtain(){if(this._stats.totalObtained++,this._objects.length>0){const t=this._objects.pop();return this._stats.size--,this._updateHitRate(),this._updateMemoryUsage(),t}const t=this._createFn();return this._stats.totalCreated++,this._updateHitRate(),t}free(t){this._objects.length<this._maxSize&&(t.reset(),this._objects.push(t),this._stats.size++,this._stats.totalReleased++,this._updateMemoryUsage())}warmUp(t){const e=Math.min(t,this._maxSize);for(;this._objects.length<e;){const t=this._createFn();this._stats.totalCreated++,this._objects.push(t),this._stats.size++}this._updateMemoryUsage()}clear(){this._objects.length=0,this._stats.size=0,this._updateMemoryUsage()}get size(){return this._objects.length}get maxSize(){return this._maxSize}set maxSize(t){for(this._maxSize=t,this._stats.maxSize=t;this._objects.length>this._maxSize;)this._objects.pop(),this._stats.size--;this._updateMemoryUsage()}getStats(){return{...this._stats}}resetStats(){this._stats.totalCreated=0,this._stats.totalObtained=0,this._stats.totalReleased=0,this._stats.hitRate=0}_updateHitRate(){if(this._stats.totalObtained>0){const t=this._stats.totalObtained-this._stats.totalCreated;this._stats.hitRate=t/this._stats.totalObtained}}_updateMemoryUsage(){this._stats.estimatedMemoryUsage=this._stats.size*this._objectSize}static obtain(t){return this.getPool(t).obtain()}static free(t,e){this.getPool(t).free(e)}static warmUp(t,e){this.getPool(t).warmUp(e)}static clearPool(t){const e=this._pools.get(t);e&&e.clear()}static clearAllPools(){for(const t of this._pools.values())t.clear();this._pools.clear()}static getStats(){const t={};for(const[e,s]of this._pools.entries()){t[e.name||"Unknown"]=s.getStats()}return t}static getTotalMemoryUsage(){let t=0;for(const e of this._pools.values())t+=e.getStats().estimatedMemoryUsage;return t}static getPerformanceReport(){const t=this.getStats(),e=[];e.push("=== Object Pool Performance Report ==="),e.push(`Total Memory Usage: ${(this.getTotalMemoryUsage()/1024/1024).toFixed(2)} MB`),e.push("");for(const[s,n]of Object.entries(t))e.push(`${s}:`),e.push(` Size: ${n.size}/${n.maxSize}`),e.push(` Hit Rate: ${(100*n.hitRate).toFixed(1)}%`),e.push(` Total Created: ${n.totalCreated}`),e.push(` Total Obtained: ${n.totalObtained}`),e.push(` Memory: ${(n.estimatedMemoryUsage/1024).toFixed(1)} KB`),e.push("");return e.join("\n")}}u._pools=new Map;class d{constructor(t,e,s=[10,50,200],n=1024){this.pools=[],this.totalObtained=0,this.totalReleased=0,this.createFn=t,this.resetFn=e,this.tierSizes=s;for(const e of s)this.pools.push(new u(t,e,n))}obtain(){this.totalObtained++;for(const t of this.pools)if(t.size>0)return t.obtain();return this.createFn()}release(t){this.totalReleased++,this.resetFn(t);for(const e of this.pools)if(e.size<e.maxSize)return void e.free(t)}warmUp(t){let e=t;for(const t of this.pools){const s=Math.min(e,t.maxSize);if(t.warmUp(s),e-=s,e<=0)break}}clear(){for(const t of this.pools)t.clear()}getStats(){let t=0,e=0,s=0;const n=[];for(const i of this.pools){const o=i.getStats();n.push(o),t+=o.size,e+=o.maxSize,s+=o.estimatedMemoryUsage}return{totalSize:t,totalMaxSize:e,totalMemoryUsage:s,tierStats:n,hitRate:this.totalObtained>0?(this.totalObtained-this.getTotalCreated())/this.totalObtained:0}}getTotalCreated(){return this.pools.reduce(((t,e)=>t+e.getStats().totalCreated),0)}}class p{constructor(){this.pools=new Map,this.autoCompactInterval=6e4,this.lastCompactTime=0}static getInstance(){return p.instance||(p.instance=new p),p.instance}registerPool(t,e){this.pools.set(t,e)}getPool(t){return this.pools.get(t)||null}update(){const t=Date.now();t-this.lastCompactTime>this.autoCompactInterval&&(this.compactAllPools(),this.lastCompactTime=t)}compactAllPools(){for(const t of this.pools.values())t instanceof u&&t.resetStats()}getAllStats(){const t=new Map;for(const[e,s]of this.pools.entries())(s instanceof u||s instanceof d)&&t.set(e,s.getStats());return t}generateReport(){const t=[];t.push("=== Pool Manager Report ===");let e=0;for(const[s,n]of this.pools.entries())if(t.push(`\n${s}:`),n instanceof u){const s=n.getStats();t.push(" Type: Standard Pool"),t.push(` Size: ${s.size}/${s.maxSize}`),t.push(` Hit Rate: ${(100*s.hitRate).toFixed(1)}%`),t.push(` Memory: ${(s.estimatedMemoryUsage/1024).toFixed(1)} KB`),e+=s.estimatedMemoryUsage}else if(n instanceof d){const s=n.getStats();t.push(" Type: Tiered Pool"),t.push(` Total Size: ${s.totalSize}/${s.totalMaxSize}`),t.push(` Hit Rate: ${(100*s.hitRate).toFixed(1)}%`),t.push(` Memory: ${(s.totalMemoryUsage/1024).toFixed(1)} KB`),e+=s.totalMemoryUsage}return t.push(`\nTotal Memory Usage: ${(e/1024/1024).toFixed(2)} MB`),t.join("\n")}}class y{static register(t){if(this.componentTypes.has(t))return this.componentTypes.get(t);if(this.nextBitIndex>=this.maxComponents)throw new Error(`Maximum number of component types (${this.maxComponents}) exceeded`);const e=this.nextBitIndex++;return this.componentTypes.set(t,e),e}static getBitMask(t){const e=this.componentTypes.get(t);if(void 0===e)throw new Error(`Component type ${t.name} is not registered`);return BigInt(1)<<BigInt(e)}static getBitIndex(t){const e=this.componentTypes.get(t);if(void 0===e)throw new Error(`Component type ${t.name} is not registered`);return e}static isRegistered(t){return this.componentTypes.has(t)}static getAllRegisteredTypes(){return new Map(this.componentTypes)}}y.componentTypes=new Map,y.nextBitIndex=0,y.maxComponents=64;class g{constructor(t){this.components=[],this.entityToIndex=new Map,this.indexToEntity=[],this.freeIndices=[],this._size=0,this.componentType=t,y.isRegistered(t)||y.register(t)}addComponent(t,e){if(this.entityToIndex.has(t))throw new Error(`Entity ${t} already has component ${this.componentType.name}`);let s;this.freeIndices.length>0?(s=this.freeIndices.pop(),this.components[s]=e,this.indexToEntity[s]=t):(s=this.components.length,this.components.push(e),this.indexToEntity.push(t)),this.entityToIndex.set(t,s),this._size++}getComponent(t){const e=this.entityToIndex.get(t);return void 0!==e?this.components[e]:null}hasComponent(t){return this.entityToIndex.has(t)}removeComponent(t){const e=this.entityToIndex.get(t);if(void 0===e)return null;const s=this.components[e];return this.entityToIndex.delete(t),this.components[e]=null,this.freeIndices.push(e),this._size--,s}forEach(t){for(let e=0;e<this.components.length;e++){const s=this.components[e];s&&t(s,this.indexToEntity[e],e)}}getDenseArray(){const t=[],e=[];for(let s=0;s<this.components.length;s++){const n=this.components[s];n&&(t.push(n),e.push(this.indexToEntity[s]))}return{components:t,entityIds:e}}clear(){this.components.length=0,this.entityToIndex.clear(),this.indexToEntity.length=0,this.freeIndices.length=0,this._size=0}get size(){return this._size}get type(){return this.componentType}compact(){if(0===this.freeIndices.length)return;const t=[],e=[],s=new Map;let n=0;for(let i=0;i<this.components.length;i++){const o=this.components[i];o&&(t[n]=o,e[n]=this.indexToEntity[i],s.set(this.indexToEntity[i],n),n++)}this.components=t,this.indexToEntity=e,this.entityToIndex=s,this.freeIndices.length=0}getStats(){const t=this.components.length,e=this._size,s=this.freeIndices.length;return{totalSlots:t,usedSlots:e,freeSlots:s,fragmentation:t>0?s/t:0}}}class f{constructor(){this.storages=new Map}getStorage(t){let e=this.storages.get(t);return e||(e=new g(t),this.storages.set(t,e)),e}addComponent(t,e){const s=e.constructor;this.getStorage(s).addComponent(t,e)}getComponent(t,e){const s=this.storages.get(e);return s?s.getComponent(t):null}hasComponent(t,e){const s=this.storages.get(e);return!!s&&s.hasComponent(t)}removeComponent(t,e){const s=this.storages.get(e);return s?s.removeComponent(t):null}removeAllComponents(t){for(const e of this.storages.values())e.removeComponent(t)}getComponentMask(t){let e=BigInt(0);for(const[s,n]of this.storages.entries())n.hasComponent(t)&&(e|=y.getBitMask(s));return e}compactAll(){for(const t of this.storages.values())t.compact()}getAllStats(){const t=new Map;for(const[e,s]of this.storages.entries()){const n=e.name||"Unknown";t.set(n,s.getStats())}return t}clear(){for(const t of this.storages.values())t.clear();this.storages.clear()}}class _{compare(t,e){let s=t.updateOrder-e.updateOrder;return 0==s&&(s=t.id-e.id),s}}class T{constructor(t={maxSize:16,ttl:5e3,enableLRU:!0}){this.cache=new Map,this.accessOrder=[],this.config=t}get(t){const e=this.cache.get(t);return e?Date.now()-e.lastAccessed>this.config.ttl?(this.cache.delete(t),this.removeFromAccessOrder(t),null):(e.lastAccessed=Date.now(),e.accessCount++,this.config.enableLRU&&this.updateAccessOrder(t),e.component):null}set(t,e){this.cache.size>=this.config.maxSize&&!this.cache.has(t)&&this.evictLeastRecentlyUsed();const s={component:e,lastAccessed:Date.now(),accessCount:1};this.cache.set(t,s),this.config.enableLRU&&this.updateAccessOrder(t)}delete(t){const e=this.cache.delete(t);return e&&this.removeFromAccessOrder(t),e}clear(){this.cache.clear(),this.accessOrder.length=0}has(t){return this.cache.has(t)}evictLeastRecentlyUsed(){if(this.accessOrder.length>0){const t=this.accessOrder[0];this.cache.delete(t),this.accessOrder.shift()}}updateAccessOrder(t){this.removeFromAccessOrder(t),this.accessOrder.push(t)}removeFromAccessOrder(t){const e=this.accessOrder.indexOf(t);-1!==e&&this.accessOrder.splice(e,1)}getStats(){let t=0,e=0;for(const s of this.cache.values())t+=s.accessCount,e++;return{size:this.cache.size,maxSize:this.config.maxSize,hitRate:t>0?e/t:0,averageAccessCount:this.cache.size>0?t/this.cache.size:0}}}class E{constructor(t,e){this.components=[],this.updateInterval=1,this._isDestroyed=!1,this._parent=null,this._children=[],this._active=!0,this._tag=0,this._enabled=!0,this._updateOrder=0,this._componentMask=BigInt(0),this._componentTypeToIndex=new Map,this._componentAccessStats=new Map,this.name=t,this.id=e,this._componentCache=new T}get isDestroyed(){return this._isDestroyed}get parent(){return this._parent}get children(){return[...this._children]}get childCount(){return this._children.length}get active(){return this._active}set active(t){this._active!==t&&(this._active=t,this.onActiveChanged())}get activeInHierarchy(){return!!this._active&&(!this._parent||this._parent.activeInHierarchy)}get tag(){return this._tag}set tag(t){this._tag=t}get enabled(){return this._enabled}set enabled(t){this._enabled=t}get updateOrder(){return this._updateOrder}set updateOrder(t){this._updateOrder=t}get componentMask(){return this._componentMask}createComponent(t,...e){const s=new t(...e);return this.addComponent(s)}addComponentInternal(t){const e=t.constructor;y.isRegistered(e)||y.register(e),t.entity=this;const s=this.components.length;return this.components.push(t),this._componentTypeToIndex.set(e,s),this._componentMask|=y.getBitMask(e),this._componentCache.set(e,t),this._componentAccessStats.set(e,{accessCount:0,lastAccessed:Date.now(),cacheHits:0,cacheMisses:0}),t}addComponent(t){const e=t.constructor;if(this.hasComponent(e))throw new Error(`Entity ${this.name} already has component ${e.name}`);if(this.addComponentInternal(t),this.scene&&this.scene.componentStorageManager&&this.scene.componentStorageManager.addComponent(this.id,t),t.onAddedToEntity(),E.eventBus&&E.eventBus.emitComponentAdded({timestamp:Date.now(),source:"Entity",entityId:this.id,entityName:this.name,entityTag:this.tag?.toString(),componentType:e.name,component:t}),this.scene&&this.scene.entityProcessors)for(const t of this.scene.entityProcessors.processors)t.onChanged(this);return t}getComponent(t){if(this.updateComponentAccessStats(t),!y.isRegistered(t))return this.recordCacheMiss(t),null;const e=y.getBitMask(t);if((this._componentMask&e)===BigInt(0))return this.recordCacheMiss(t),null;const s=this._componentCache.get(t);if(s)return this.recordCacheHit(t),s;const n=this._componentTypeToIndex.get(t);if(void 0!==n&&n<this.components.length){const e=this.components[n];if(e&&e.constructor===t)return this._componentCache.set(t,e),this.recordCacheHit(t),e}if(this.scene&&this.scene.componentStorageManager){const e=this.scene.componentStorageManager.getComponent(this.id,t);if(e)return this._componentCache.set(t,e),this.rebuildComponentIndex(),this.recordCacheHit(t),e}for(let e=0;e<this.components.length;e++){const s=this.components[e];if(s instanceof t)return this._componentTypeToIndex.set(t,e),this._componentCache.set(t,s),this.recordCacheHit(t),s}return this.recordCacheMiss(t),null}updateComponentAccessStats(t){let e=this._componentAccessStats.get(t);e||(e={accessCount:0,lastAccessed:Date.now(),cacheHits:0,cacheMisses:0},this._componentAccessStats.set(t,e)),e.accessCount++,e.lastAccessed=Date.now()}recordCacheHit(t){const e=this._componentAccessStats.get(t);e&&e.cacheHits++}recordCacheMiss(t){const e=this._componentAccessStats.get(t);e&&e.cacheMisses++}rebuildComponentIndex(){this._componentTypeToIndex.clear();for(let t=0;t<this.components.length;t++){const e=this.components[t].constructor;this._componentTypeToIndex.set(e,t)}}hasComponent(t){if(!y.isRegistered(t))return!1;const e=y.getBitMask(t);return(this._componentMask&e)!==BigInt(0)}getOrCreateComponent(t,...e){let s=this.getComponent(t);return s||(s=this.createComponent(t,...e)),s}removeComponent(t){const e=t.constructor,s=this.components.indexOf(t);if(-1!==s&&(this.components.splice(s,1),this.rebuildComponentIndex()),this._componentCache.delete(e),this._componentAccessStats.delete(e),y.isRegistered(e)&&(this._componentMask&=~y.getBitMask(e)),this.scene&&this.scene.componentStorageManager&&this.scene.componentStorageManager.removeComponent(this.id,e),t.onRemovedFromEntity(),E.eventBus&&E.eventBus.emitComponentRemoved({timestamp:Date.now(),source:"Entity",entityId:this.id,entityName:this.name,entityTag:this.tag?.toString(),componentType:e.name,component:t}),t.entity=null,this.scene&&this.scene.entityProcessors)for(const t of this.scene.entityProcessors.processors)t.onChanged(this)}removeComponentByType(t){const e=this.getComponent(t);return e?(this.removeComponent(e),e):null}removeAllComponents(){const t=[...this.components];this._componentCache.clear(),this._componentTypeToIndex.clear(),this._componentAccessStats.clear(),this._componentMask=BigInt(0);for(const e of t){const t=e.constructor;this.scene&&this.scene.componentStorageManager&&this.scene.componentStorageManager.removeComponent(this.id,t),e.onRemovedFromEntity(),e.entity=null}if(this.components.length=0,this.scene&&this.scene.entityProcessors)for(const t of this.scene.entityProcessors.processors)t.onChanged(this)}addComponents(t){const e=[];for(const s of t)try{e.push(this.addComponent(s))}catch(t){console.warn(`Failed to add component ${s.constructor.name}:`,t)}return e}removeComponentsByTypes(t){const e=[];for(const s of t)e.push(this.removeComponentByType(s));return e}getComponentCacheStats(){const t=new Map;for(const[e,s]of this._componentAccessStats){const n=s.cacheHits+s.cacheMisses;t.set(e.name,{...s,hitRate:n>0?s.cacheHits/n:0})}return{cacheStats:this._componentCache.getStats(),accessStats:t,indexMappingSize:this._componentTypeToIndex.size,totalComponents:this.components.length}}warmUpComponentCache(){for(let t=0;t<this.components.length;t++){const e=this.components[t],s=e.constructor;this._componentTypeToIndex.set(s,t),this._componentCache.set(s,e)}}cleanupComponentCache(){const t=Date.now();for(const[e,s]of this._componentAccessStats)t-s.lastAccessed>3e4&&s.accessCount<5&&this._componentCache.delete(e)}getComponents(t){const e=[];for(const s of this.components)s instanceof t&&e.push(s);return e}addChild(t){if(t===this)throw new Error("Entity cannot be its own child");return t._parent===this||(t._parent&&t._parent.removeChild(t),t._parent=this,this._children.push(t),!t.scene&&this.scene&&(t.scene=this.scene,this.scene.addEntity(t))),t}removeChild(t){const e=this._children.indexOf(t);return-1!==e&&(this._children.splice(e,1),t._parent=null,!0)}removeAllChildren(){const t=[...this._children];for(const e of t)this.removeChild(e)}findChild(t,e=!1){for(const e of this._children)if(e.name===t)return e;if(e)for(const e of this._children){const s=e.findChild(t,!0);if(s)return s}return null}findChildrenByTag(t,e=!1){const s=[];for(const e of this._children)e.tag===t&&s.push(e);if(e)for(const e of this._children)s.push(...e.findChildrenByTag(t,!0));return s}getRoot(){let t=this;for(;t._parent;)t=t._parent;return t}isAncestorOf(t){let e=t._parent;for(;e;){if(e===this)return!0;e=e._parent}return!1}isDescendantOf(t){return t.isAncestorOf(this)}getDepth(){let t=0,e=this._parent;for(;e;)t++,e=e._parent;return t}forEachChild(t,e=!1){this._children.forEach(((s,n)=>{t(s,n),e&&s.forEachChild(t,!0)}))}onActiveChanged(){for(const t of this.components)"onActiveChanged"in t&&"function"==typeof t.onActiveChanged&&t.onActiveChanged();this.scene&&this.scene.eventSystem&&this.scene.eventSystem.emitSync("entity:activeChanged",{entity:this,active:this._active,activeInHierarchy:this.activeInHierarchy})}update(){if(this.activeInHierarchy&&!this._isDestroyed){for(const t of this.components)t.enabled&&t.update();for(const t of this._children)t.update()}}destroy(){if(this._isDestroyed)return;this._isDestroyed=!0;const t=[...this._children];for(const e of t)e.destroy();this._parent&&this._parent.removeChild(this),this.removeAllComponents(),this.scene&&this.scene.entities&&this.scene.entities.remove(this)}compareTo(t){return _.prototype.compare(this,t)}toString(){return`Entity[${this.name}:${this.id}]`}getDebugInfo(){const t=this.getComponentCacheStats(),e=Array.from(t.accessStats.entries()).map((([t,e])=>({componentType:t,accessCount:e.accessCount,cacheHits:e.cacheHits,cacheMisses:e.cacheMisses,hitRate:e.hitRate,lastAccessed:new Date(e.lastAccessed).toISOString()})));return{name:this.name,id:this.id,enabled:this._enabled,active:this._active,activeInHierarchy:this.activeInHierarchy,destroyed:this._isDestroyed,componentCount:this.components.length,componentTypes:this.components.map((t=>t.constructor.name)),componentMask:this._componentMask.toString(2),parentId:this._parent?.id||null,childCount:this._children.length,childIds:this._children.map((t=>t.id)),depth:this.getDepth(),componentCache:t.cacheStats,componentAccessStats:e,indexMappingSize:t.indexMappingSize}}}E.entityComparer=new _,E.eventBus=null;class S{get count(){return this.buffer.length}constructor(t){this.buffer=[],this._idToEntity=new Map,this._nameToEntities=new Map,this._entitiesToAdd=[],this._entitiesToRemove=[],this._isUpdating=!1,this._scene=t}add(t){this._isUpdating?this._entitiesToAdd.push(t):this.addImmediate(t)}addImmediate(t){this._idToEntity.has(t.id)||(this.buffer.push(t),this._idToEntity.set(t.id,t),this.updateNameIndex(t,!0))}remove(t){this._isUpdating?this._entitiesToRemove.push(t):this.removeImmediate(t)}removeImmediate(t){const e=this.buffer.indexOf(t);-1!==e&&(this.buffer.splice(e,1),this._idToEntity.delete(t.id),this.updateNameIndex(t,!1))}removeAllEntities(){for(let t=this.buffer.length-1;t>=0;t--)this.buffer[t].destroy();this.buffer.length=0,this._idToEntity.clear(),this._nameToEntities.clear(),this._entitiesToAdd.length=0,this._entitiesToRemove.length=0}updateLists(){if(this._entitiesToAdd.length>0){for(const t of this._entitiesToAdd)this.addImmediate(t);this._entitiesToAdd.length=0}if(this._entitiesToRemove.length>0){for(const t of this._entitiesToRemove)this.removeImmediate(t);this._entitiesToRemove.length=0}}update(){this._isUpdating=!0;try{for(let t=0;t<this.buffer.length;t++){const e=this.buffer[t];e.enabled&&!e.isDestroyed&&e.update()}}finally{this._isUpdating=!1}this.updateLists()}findEntity(t){const e=this._nameToEntities.get(t);return e&&e.length>0?e[0]:null}findEntitiesByName(t){return this._nameToEntities.get(t)||[]}findEntityById(t){return this._idToEntity.get(t)||null}findEntitiesByTag(t){const e=[];for(const s of this.buffer)s.tag===t&&e.push(s);return e}findEntitiesWithComponent(t){const e=[];for(const s of this.buffer)s.hasComponent(t)&&e.push(s);return e}forEach(t){for(const e of this.buffer)t(e)}forEachWhere(t,e){for(const s of this.buffer)t(s)&&e(s)}updateNameIndex(t,e){if(t.name)if(e){let e=this._nameToEntities.get(t.name);e||(e=[],this._nameToEntities.set(t.name,e)),e.push(t)}else{const e=this._nameToEntities.get(t.name);if(e){const s=e.indexOf(t);-1!==s&&(e.splice(s,1),0===e.length&&this._nameToEntities.delete(t.name))}}}getStats(){let t=0;for(const e of this.buffer)e.enabled&&!e.isDestroyed&&t++;return{totalEntities:this.buffer.length,activeEntities:t,pendingAdd:this._entitiesToAdd.length,pendingRemove:this._entitiesToRemove.length,nameIndexSize:this._nameToEntities.size}}}class C{constructor(){this._processors=[],this._isDirty=!1}setDirty(){this._isDirty=!0}add(t){this._processors.push(t),this.setDirty()}remove(t){const e=this._processors.indexOf(t);-1!==e&&this._processors.splice(e,1)}getProcessor(t){for(const e of this._processors)if(e instanceof t)return e;return null}begin(){this.sortProcessors();for(const t of this._processors)t.initialize()}end(){}update(){this.sortProcessors();for(const t of this._processors)t.update()}lateUpdate(){for(const t of this._processors)t.lateUpdate()}sortProcessors(){this._isDirty&&(this._processors.sort(((t,e)=>t.updateOrder-e.updateOrder)),this._isDirty=!1)}get processors(){return this._processors}get count(){return this._processors.length}}class M{constructor(){this._nextAvailableId=0,this._ids=[]}checkOut(){return this._ids.length>0?this._ids.pop():this._nextAvailableId++}checkIn(t){this._ids.push(t)}}class b{constructor(t,e,s=1e3){this.pool=[],this.createFn=t,this.resetFn=e,this.maxSize=s}acquire(){return this.pool.length>0?this.pool.pop():this.createFn()}release(t){this.pool.length<this.maxSize&&(this.resetFn&&this.resetFn(t),this.pool.push(t))}prewarm(t){for(let e=0;e<t&&this.pool.length<this.maxSize;e++)this.pool.push(this.createFn())}clear(){this.pool.length=0}getAvailableCount(){return this.pool.length}getMaxSize(){return this.maxSize}}class v{constructor(){this.pools=new Map}static getInstance(){return v.instance||(v.instance=new v),v.instance}registerPool(t,e,s,n){this.pools.set(t,new b(e,s,n))}acquireComponent(t){const e=this.pools.get(t);return e?e.acquire():null}releaseComponent(t,e){const s=this.pools.get(t);s&&s.release(e)}prewarmAll(t=100){for(const e of this.pools.values())e.prewarm(t)}clearAll(){for(const t of this.pools.values())t.clear()}getPoolStats(){const t=new Map;for(const[e,s]of this.pools)t.set(e,{available:s.getAvailableCount(),maxSize:s.getMaxSize()});return t}getPoolUtilization(){const t=new Map;for(const[e,s]of this.pools){const n=s.getAvailableCount(),i=s.getMaxSize(),o=i-n,r=i>0?o/i*100:0;t.set(e,{used:o,total:i,utilization:r})}return t}getComponentUtilization(t){const e=this.pools.get(t);if(!e)return 0;const s=e.getAvailableCount(),n=e.getMaxSize();return n>0?(n-s)/n*100:0}}class D{constructor(){this.maskCache=new Map,this.componentTypeMap=new Map,this.nextComponentId=0}static getInstance(){return D.instance||(D.instance=new D),D.instance}registerComponentType(t){return this.componentTypeMap.has(t)||this.componentTypeMap.set(t,this.nextComponentId++),this.componentTypeMap.get(t)}getComponentTypeId(t){return this.componentTypeMap.get(t)}createSingleComponentMask(t){const e=`single:${t}`;if(this.maskCache.has(e))return this.maskCache.get(e);const s=this.getComponentTypeId(t);if(void 0===s)throw new Error(`Component type not registered: ${t}`);const n=1n<<BigInt(s);return this.maskCache.set(e,n),n}createCombinedMask(t){const e=`combined:${[...t].sort().join(",")}`;if(this.maskCache.has(e))return this.maskCache.get(e);let s=0n;for(const e of t){const t=this.getComponentTypeId(e);if(void 0===t)throw new Error(`Component type not registered: ${e}`);s|=1n<<BigInt(t)}return this.maskCache.set(e,s),s}maskContainsComponent(t,e){return 0n!==(t&this.createSingleComponentMask(e))}maskContainsAllComponents(t,e){const s=this.createCombinedMask(e);return(t&s)===s}maskContainsAnyComponent(t,e){return 0n!==(t&this.createCombinedMask(e))}addComponentToMask(t,e){return t|this.createSingleComponentMask(e)}removeComponentFromMask(t,e){return t&~this.createSingleComponentMask(e)}precomputeCommonMasks(t){for(const e of t)this.createCombinedMask(e)}getCacheStats(){return{size:this.maskCache.size,componentTypes:this.componentTypeMap.size}}clearCache(){this.maskCache.clear()}reset(){this.maskCache.clear(),this.componentTypeMap.clear(),this.nextComponentId=0}maskToComponentNames(t){const e=[];for(const[s,n]of this.componentTypeMap){0n!==(t&1n<<BigInt(n))&&e.push(s)}return e}getComponentCount(t){let e=0,s=t;for(;0n!==s;)0n!=(1n&s)&&e++,s>>=1n;return e}}!function(t){t.ADD_ENTITY="add_entity",t.REMOVE_ENTITY="remove_entity",t.UPDATE_ENTITY="update_entity"}(o||(o={}));class x{constructor(){this.pendingOperations=[],this.isProcessing=!1,this.batchSize=1e3,this.flushTimeout=null,this.flushDelay=16}addOperation(t){this.pendingOperations.push(t),this.pendingOperations.length>=this.batchSize?this.flush():this.scheduleFlush()}addEntities(t){for(const e of t)this.pendingOperations.push({type:o.ADD_ENTITY,entity:e});this.pendingOperations.length>=this.batchSize?this.flush():this.scheduleFlush()}removeEntities(t){for(const e of t)this.pendingOperations.push({type:o.REMOVE_ENTITY,entity:e});this.pendingOperations.length>=this.batchSize?this.flush():this.scheduleFlush()}updateEntities(t){for(const e of t)this.pendingOperations.push({type:o.UPDATE_ENTITY,entity:e.entity,oldMask:e.oldMask,newMask:e.newMask});this.pendingOperations.length>=this.batchSize?this.flush():this.scheduleFlush()}scheduleFlush(){this.flushTimeout||(this.flushTimeout=setTimeout((()=>{this.flush()}),this.flushDelay))}flush(){if(!this.isProcessing&&0!==this.pendingOperations.length){this.isProcessing=!0,this.flushTimeout&&(clearTimeout(this.flushTimeout),this.flushTimeout=null);try{this.processBatch()}finally{this.isProcessing=!1}}}processBatch(){const t=this.pendingOperations;this.pendingOperations=[];const e=[],s=[],n=[];for(const i of t)switch(i.type){case o.ADD_ENTITY:e.push(i.entity);break;case o.REMOVE_ENTITY:s.push(i.entity);break;case o.UPDATE_ENTITY:void 0!==i.oldMask&&void 0!==i.newMask&&n.push({entity:i.entity,oldMask:i.oldMask,newMask:i.newMask})}e.length>0&&this.processBatchAdd(e),s.length>0&&this.processBatchRemove(s),n.length>0&&this.processBatchUpdate(n)}processBatchAdd(t){this.onBatchAdd&&this.onBatchAdd(t)}processBatchRemove(t){this.onBatchRemove&&this.onBatchRemove(t)}processBatchUpdate(t){this.onBatchUpdate&&this.onBatchUpdate(t)}setBatchSize(t){this.batchSize=Math.max(1,t)}setFlushDelay(t){this.flushDelay=Math.max(0,t)}getPendingCount(){return this.pendingOperations.length}clear(){this.pendingOperations.length=0,this.flushTimeout&&(clearTimeout(this.flushTimeout),this.flushTimeout=null)}hasPendingOperations(){return this.pendingOperations.length>0}}!function(t){t.HASH="hash",t.BITMAP="bitmap",t.SORTED="sorted"}(r||(r={}));class w{constructor(){this.type=r.HASH,this._componentToEntities=new Map,this._entityToComponents=new Map,this._queryCount=0,this._totalQueryTime=0,this._lastUpdated=Date.now()}addEntity(t){const e=t.components,s=new Set;for(const n of e){const e=n.constructor;s.add(e);let i=this._componentToEntities.get(e);i||(i=new Set,this._componentToEntities.set(e,i)),i.add(t)}this._entityToComponents.set(t,s),this._lastUpdated=Date.now()}removeEntity(t){const e=this._entityToComponents.get(t);if(e){for(const s of e){const e=this._componentToEntities.get(s);e&&(e.delete(t),0===e.size&&this._componentToEntities.delete(s))}this._entityToComponents.delete(t),this._lastUpdated=Date.now()}}query(t){const e=performance.now(),s=new Set(this._componentToEntities.get(t)||[]);return this._queryCount++,this._totalQueryTime+=performance.now()-e,s}queryMultiple(t,e){const s=performance.now();if(0===t.length)return new Set;if(1===t.length)return this.query(t[0]);let n;if("AND"===e){let e,i=1/0;for(const n of t){const t=this._componentToEntities.get(n);if(!t||0===t.size)return this._queryCount++,this._totalQueryTime+=performance.now()-s,new Set;t.size<i&&(i=t.size,e=t)}if(n=new Set,e)for(const s of e){let e=!0;for(const n of t){const t=this._componentToEntities.get(n);if(!t||!t.has(s)){e=!1;break}}e&&n.add(s)}}else{n=new Set;for(const e of t){const t=this._componentToEntities.get(e);if(t)for(const e of t)n.add(e)}}return this._queryCount++,this._totalQueryTime+=performance.now()-s,n}clear(){this._componentToEntities.clear(),this._entityToComponents.clear(),this._lastUpdated=Date.now()}getStats(){let t=0;t+=64*this._componentToEntities.size,t+=64*this._entityToComponents.size;for(const e of this._componentToEntities.values())t+=8*e.size;for(const e of this._entityToComponents.values())t+=8*e.size;return{type:this.type,size:this._componentToEntities.size,memoryUsage:t,queryCount:this._queryCount,avgQueryTime:this._queryCount>0?this._totalQueryTime/this._queryCount:0,lastUpdated:this._lastUpdated}}}class I{constructor(){this.type=r.BITMAP,this._componentTypeToBit=new Map,this._entityToBitmap=new Map,this._bitToEntities=new Map,this._nextBit=0,this._queryCount=0,this._totalQueryTime=0,this._lastUpdated=Date.now()}addEntity(t){let e=0;for(const s of t.components){const n=s.constructor;let i=this._componentTypeToBit.get(n);void 0===i&&(i=this._nextBit++,this._componentTypeToBit.set(n,i)),e|=1<<i;let o=this._bitToEntities.get(1<<i);o||(o=new Set,this._bitToEntities.set(1<<i,o)),o.add(t)}this._entityToBitmap.set(t,e),this._lastUpdated=Date.now()}removeEntity(t){const e=this._entityToBitmap.get(t);if(void 0!==e){for(const[s,n]of this._bitToEntities)0!==(e&s)&&(n.delete(t),0===n.size&&this._bitToEntities.delete(s));this._entityToBitmap.delete(t),this._lastUpdated=Date.now()}}query(t){const e=performance.now(),s=this._componentTypeToBit.get(t);if(void 0===s)return this._queryCount++,this._totalQueryTime+=performance.now()-e,new Set;const n=new Set(this._bitToEntities.get(1<<s)||[]);return this._queryCount++,this._totalQueryTime+=performance.now()-e,n}queryMultiple(t,e){const s=performance.now();if(0===t.length)return new Set;let n=0;const i=[];for(const e of t){const t=this._componentTypeToBit.get(e);void 0!==t&&(n|=1<<t,i.push(1<<t))}const o=new Set;if("AND"===e)for(const[t,e]of this._entityToBitmap)(e&n)===n&&o.add(t);else for(const t of i){const e=this._bitToEntities.get(t);if(e)for(const t of e)o.add(t)}return this._queryCount++,this._totalQueryTime+=performance.now()-s,o}clear(){this._componentTypeToBit.clear(),this._entityToBitmap.clear(),this._bitToEntities.clear(),this._nextBit=0,this._lastUpdated=Date.now()}getStats(){let t=0;t+=12*this._componentTypeToBit.size,t+=12*this._entityToBitmap.size,t+=64*this._bitToEntities.size;for(const e of this._bitToEntities.values())t+=8*e.size;return{type:this.type,size:this._componentTypeToBit.size,memoryUsage:t,queryCount:this._queryCount,avgQueryTime:this._queryCount>0?this._totalQueryTime/this._queryCount:0,lastUpdated:this._lastUpdated}}}class A{constructor(t=r.HASH){this._indexHistory=new Map,this._autoOptimize=!0,this._optimizationThreshold=1e3,this._activeIndex=this.createIndex(t)}addEntity(t){this._activeIndex.addEntity(t),this.checkOptimization()}removeEntity(t){this._activeIndex.removeEntity(t)}query(t){return this._activeIndex.query(t)}queryMultiple(t,e){return this._activeIndex.queryMultiple(t,e)}switchIndexType(t){if(t===this._activeIndex.type)return;this._indexHistory.set(this._activeIndex.type,this._activeIndex.getStats());const e=this._activeIndex;this._activeIndex=this.createIndex(t),e.clear()}setAutoOptimize(t){this._autoOptimize=t}getStats(){return this._activeIndex.getStats()}getAllStats(){const t=this._activeIndex.getStats();return new Map([...this._indexHistory,[t.type,t]])}clear(){this._activeIndex.clear()}createIndex(t){switch(t){case r.HASH:return new w;case r.BITMAP:return new I;case r.SORTED:default:return new w}}checkOptimization(){if(!this._autoOptimize)return;const t=this._activeIndex.getStats();t.queryCount<this._optimizationThreshold||(t.avgQueryTime>1&&t.type!==r.HASH?this.switchIndexType(r.HASH):t.memoryUsage>10485760&&t.type!==r.BITMAP&&this.switchIndexType(r.BITMAP))}}class O{constructor(){this._archetypes=new Map,this._entityToArchetype=new Map,this._componentToArchetypes=new Map,this._queryCache=new Map,this._cacheTimeout=5e3,this._maxCacheSize=100}addEntity(t){const e=this.getEntityComponentTypes(t),s=this.generateArchetypeId(e);let n=this._archetypes.get(s);n||(n=this.createArchetype(e)),n.entities.push(t),n.updatedAt=Date.now(),this._entityToArchetype.set(t,n),this.updateComponentIndexes(n,e,!0),this.invalidateQueryCache()}removeEntity(t){const e=this._entityToArchetype.get(t);if(!e)return;const s=e.entities.indexOf(t);-1!==s&&(e.entities.splice(s,1),e.updatedAt=Date.now()),this._entityToArchetype.delete(t),this.invalidateQueryCache()}queryArchetypes(t,e="AND"){const s=performance.now(),n=`${e}:${t.map((t=>t.name)).sort().join(",")}`,i=this._queryCache.get(n);if(i&&Date.now()-i.timestamp<this._cacheTimeout)return{...i.result,executionTime:performance.now()-s,fromCache:!0};const o=[];let r=0;if("AND"===e)for(const e of this._archetypes.values())this.archetypeContainsAllComponents(e,t)&&(o.push(e),r+=e.entities.length);else{const e=new Set;for(const s of t){const t=this._componentToArchetypes.get(s);if(t)for(const s of t)e.add(s)}for(const t of e)o.push(t),r+=t.entities.length}const a={archetypes:o,totalEntities:r,executionTime:performance.now()-s,fromCache:!1};return this._queryCache.set(n,{result:a,timestamp:Date.now()}),a}getEntityArchetype(t){return this._entityToArchetype.get(t)}getAllArchetypes(){return Array.from(this._archetypes.values())}clear(){this._archetypes.clear(),this._entityToArchetype.clear(),this._componentToArchetypes.clear(),this._queryCache.clear()}getEntityComponentTypes(t){return t.components.map((t=>t.constructor))}generateArchetypeId(t){return t.map((t=>t.name)).sort().join("|")}createArchetype(t){const e=this.generateArchetypeId(t),s={id:e,componentTypes:[...t],entities:[],createdAt:Date.now(),updatedAt:Date.now()};return this._archetypes.set(e,s),s}archetypeContainsAllComponents(t,e){for(const s of e)if(!t.componentTypes.includes(s))return!1;return!0}updateComponentIndexes(t,e,s){for(const n of e){let e=this._componentToArchetypes.get(n);e||(e=new Set,this._componentToArchetypes.set(n,e)),s?e.add(t):(e.delete(t),0===e.size&&this._componentToArchetypes.delete(n))}}invalidateQueryCache(){this._queryCache.clear()}}!function(t){t[t.COMPONENT_MODIFIED=1]="COMPONENT_MODIFIED",t[t.COMPONENT_ADDED=2]="COMPONENT_ADDED",t[t.COMPONENT_REMOVED=4]="COMPONENT_REMOVED",t[t.TRANSFORM_CHANGED=8]="TRANSFORM_CHANGED",t[t.STATE_CHANGED=16]="STATE_CHANGED",t[t.CUSTOM_1=256]="CUSTOM_1",t[t.CUSTOM_2=512]="CUSTOM_2",t[t.CUSTOM_3=1024]="CUSTOM_3",t[t.ALL=4294967295]="ALL"}(a||(a={}));class N{constructor(){this._dirtyEntities=new Map,this._listeners=[],this._stats={totalMarkings:0,totalCleanups:0,frameCount:0,totalDirtyPerFrame:0},this._currentFrame=0,this._batchSize=100,this._maxProcessingTime=16,this._processingQueue=[],this._isProcessing=!1}markDirty(t,e,s=[]){this._stats.totalMarkings++;let n=this._dirtyEntities.get(t);n||(n={entity:t,flags:0,modifiedComponents:new Set,timestamp:performance.now(),frameNumber:this._currentFrame},this._dirtyEntities.set(t,n)),n.flags|=e,n.timestamp=performance.now(),n.frameNumber=this._currentFrame;for(const t of s)n.modifiedComponents.add(t);this.notifyListeners(n,e)}isDirty(t,e=a.ALL){const s=this._dirtyEntities.get(t);return!!s&&0!==(s.flags&e)}clearDirty(t,e=a.ALL){const s=this._dirtyEntities.get(t);s&&(e===a.ALL?this._dirtyEntities.delete(t):(s.flags&=~e,0===s.flags&&this._dirtyEntities.delete(t)),this._stats.totalCleanups++)}getDirtyEntities(t=a.ALL){const e=[];for(const s of this._dirtyEntities.values())0!==(s.flags&t)&&e.push(s);return e}processDirtyEntities(){if(this._isProcessing)return;this._isProcessing=!0;const t=performance.now();0===this._processingQueue.length&&this._processingQueue.push(...this._dirtyEntities.values());let e=0;for(;this._processingQueue.length>0&&e<this._batchSize;){if(performance.now()-t>this._maxProcessingTime)break;const s=this._processingQueue.shift();this.processEntity(s),e++}0===this._processingQueue.length&&(this._isProcessing=!1,this.onFrameEnd())}addListener(t){this._listeners.push(t),this._listeners.sort(((t,e)=>(t.priority||100)-(e.priority||100)))}removeListener(t){const e=this._listeners.findIndex((e=>e.callback===t));-1!==e&&this._listeners.splice(e,1)}beginFrame(){this._currentFrame++}endFrame(){this._isProcessing||this.processDirtyEntities()}getStats(){return{dirtyEntityCount:this._dirtyEntities.size,totalMarkings:this._stats.totalMarkings,totalCleanups:this._stats.totalCleanups,listenerCount:this._listeners.length,avgDirtyPerFrame:this._stats.frameCount>0?this._stats.totalDirtyPerFrame/this._stats.frameCount:0,estimatedMemoryUsage:this.estimateMemoryUsage()}}clear(){this._dirtyEntities.clear(),this._processingQueue.length=0,this._isProcessing=!1,this._stats={totalMarkings:0,totalCleanups:0,frameCount:0,totalDirtyPerFrame:0}}configureBatchProcessing(t,e){this._batchSize=t,this._maxProcessingTime=e}processEntity(t){for(const e of this._listeners)if(0!==(t.flags&e.flags))try{e.callback(t)}catch(t){console.error("Dirty listener error:",t)}this.clearDirty(t.entity)}notifyListeners(t,e){for(const s of this._listeners)if(0!==(e&s.flags))try{s.callback(t)}catch(t){console.error("Dirty listener notification error:",t)}}onFrameEnd(){this._stats.frameCount++,this._stats.totalDirtyPerFrame+=this._dirtyEntities.size}estimateMemoryUsage(){let t=0;return t+=100*this._dirtyEntities.size,t+=50*this._listeners.length,t+=8*this._processingQueue.length,t}}!function(t){t.ALL="all",t.ANY="any",t.NONE="none"}(c||(c={}));class B{constructor(){this.entities=[],this.indexDirty=!0,this.queryCache=new Map,this.cacheMaxSize=1e3,this.cacheTimeout=5e3,this.queryStats={totalQueries:0,cacheHits:0,indexHits:0,linearScans:0,archetypeHits:0,dirtyChecks:0},this.entityIndex={byMask:new Map,byComponentType:new Map,byTag:new Map,byName:new Map},this.componentPoolManager=v.getInstance(),this.bitMaskOptimizer=D.getInstance(),this.indexUpdateBatcher=new x,this.componentIndexManager=new A(r.HASH),this.archetypeSystem=new O,this.dirtyTrackingSystem=new N,this.indexUpdateBatcher.onBatchAdd=t=>{for(const e of t)this.addEntityToIndexes(e)},this.indexUpdateBatcher.onBatchRemove=t=>{for(const e of t)this.removeEntityFromIndexes(e)},this.indexUpdateBatcher.onBatchUpdate=t=>{for(const e of t)this.removeEntityFromIndexes(e.entity),this.addEntityToIndexes(e.entity)}}setEntities(t){this.entities=t,this.clearQueryCache(),this.rebuildIndexes()}addEntity(t,e=!1){this.entities.includes(t)||(this.entities.push(t),this.addEntityToIndexes(t),this.componentIndexManager.addEntity(t),this.archetypeSystem.addEntity(t),this.dirtyTrackingSystem.markDirty(t,a.COMPONENT_ADDED),e||this.clearQueryCache())}addEntities(t){if(0===t.length)return;const e=new Set(this.entities.map((t=>t.id)));let s=0;for(const n of t)e.has(n.id)||(this.entities.push(n),this.addEntityToIndexes(n),e.add(n.id),s++);s>0&&this.clearQueryCache()}addEntitiesUnchecked(t){if(0!==t.length){for(const e of t)this.entities.push(e);for(const e of t)this.addEntityToIndexes(e);this.clearQueryCache()}}removeEntity(t){const e=this.entities.indexOf(t);-1!==e&&(this.entities.splice(e,1),this.removeEntityFromIndexes(t),this.componentIndexManager.removeEntity(t),this.archetypeSystem.removeEntity(t),this.dirtyTrackingSystem.markDirty(t,a.COMPONENT_REMOVED),this.clearQueryCache())}addEntityToIndexes(t){const e=t.componentMask;let s=this.entityIndex.byMask.get(e);s||(s=new Set,this.entityIndex.byMask.set(e,s)),s.add(t);const n=t.components;for(let e=0;e<n.length;e++){const s=n[e].constructor;let i=this.entityIndex.byComponentType.get(s);i||(i=new Set,this.entityIndex.byComponentType.set(s,i)),i.add(t)}const i=t.tag;if(void 0!==i){let e=this.entityIndex.byTag.get(i);e||(e=new Set,this.entityIndex.byTag.set(i,e)),e.add(t)}const o=t.name;if(o){let e=this.entityIndex.byName.get(o);e||(e=new Set,this.entityIndex.byName.set(o,e)),e.add(t)}}removeEntityFromIndexes(t){const e=t.componentMask,s=this.entityIndex.byMask.get(e);s&&(s.delete(t),0===s.size&&this.entityIndex.byMask.delete(e));for(const e of t.components){const s=e.constructor,n=this.entityIndex.byComponentType.get(s);n&&(n.delete(t),0===n.size&&this.entityIndex.byComponentType.delete(s))}if(void 0!==t.tag){const e=this.entityIndex.byTag.get(t.tag);e&&(e.delete(t),0===e.size&&this.entityIndex.byTag.delete(t.tag))}if(t.name){const e=this.entityIndex.byName.get(t.name);e&&(e.delete(t),0===e.size&&this.entityIndex.byName.delete(t.name))}}rebuildIndexes(){this.entityIndex.byMask.clear(),this.entityIndex.byComponentType.clear(),this.entityIndex.byTag.clear(),this.entityIndex.byName.clear();for(const t of this.entities)this.addEntityToIndexes(t);this.indexDirty=!1}queryAll(...t){const e=performance.now();this.queryStats.totalQueries++;const s=`all:${t.map((t=>t.name)).sort().join(",")}`,n=this.getFromCache(s);if(n)return this.queryStats.cacheHits++,{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!0};let i;const o=this.archetypeSystem.queryArchetypes(t,"AND");if(o.archetypes.length>0){this.queryStats.archetypeHits++,i=[];for(const t of o.archetypes)i.push(...t.entities)}else if(1===t.length){this.queryStats.indexHits++;const e=this.componentIndexManager.query(t[0]);i=Array.from(e)}else{const e=this.componentIndexManager.queryMultiple(t,"AND");i=Array.from(e)}return this.addToCache(s,i),{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!1}}queryMultipleComponents(t){let e=null,s=1/0;for(const n of t){const t=this.entityIndex.byComponentType.get(n);if(!t||0===t.size)return[];t.size<s&&(s=t.size,e=t)}if(!e)return this.queryStats.linearScans++,this.queryByLinearScan(t);const n=this.createComponentMask(t),i=[];for(const t of e)(t.componentMask&n)===n&&i.push(t);return i}queryByLinearScan(t){const e=this.createComponentMask(t);return this.entities.filter((t=>(t.componentMask&e)===e))}queryAny(...t){const e=performance.now();this.queryStats.totalQueries++;const s=`any:${t.map((t=>t.name)).sort().join(",")}`,n=this.getFromCache(s);if(n)return this.queryStats.cacheHits++,{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!0};const i=this.archetypeSystem.queryArchetypes(t,"OR");let o;if(i.archetypes.length>0){this.queryStats.archetypeHits++,o=[];for(const t of i.archetypes)o.push(...t.entities)}else{const e=this.componentIndexManager.queryMultiple(t,"OR");o=Array.from(e)}return this.addToCache(s,o),{entities:o,count:o.length,executionTime:performance.now()-e,fromCache:!1}}queryNone(...t){const e=performance.now();this.queryStats.totalQueries++;const s=`none:${t.map((t=>t.name)).sort().join(",")}`,n=this.getFromCache(s);if(n)return this.queryStats.cacheHits++,{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!0};const i=this.createComponentMask(t),o=this.entities.filter((t=>(t.componentMask&i)===BigInt(0)));return this.addToCache(s,o),{entities:o,count:o.length,executionTime:performance.now()-e,fromCache:!1}}queryByTag(t){const e=performance.now();this.queryStats.totalQueries++;const s=`tag:${t}`,n=this.getFromCache(s);if(n)return this.queryStats.cacheHits++,{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;const i=Array.from(this.entityIndex.byTag.get(t)||[]);return this.addToCache(s,i),{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!1}}queryByName(t){const e=performance.now();this.queryStats.totalQueries++;const s=`name:${t}`,n=this.getFromCache(s);if(n)return this.queryStats.cacheHits++,{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;const i=Array.from(this.entityIndex.byName.get(t)||[]);return this.addToCache(s,i),{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!1}}queryByComponent(t){const e=performance.now();this.queryStats.totalQueries++;const s=`component:${t.name}`,n=this.getFromCache(s);if(n)return this.queryStats.cacheHits++,{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;const i=Array.from(this.entityIndex.byComponentType.get(t)||[]);return this.addToCach