UNPKG

@esengine/ecs-framework

Version:

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

1 lines 130 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 n{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,n,s){this._timeInSeconds=t,this._repeats=e,this.context=n,this._onTime=s.bind(n)}unload(){this.context=null,this._onTime=null}}class s 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,s,i){let o=new n;return o.initialize(t,e,s,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,n=0){if(!this._isEnabled||0===e)return;const s=performance.now(),i=s-e,o={name:t,executionTime:i,entityCount:n,averageTimePerEntity:n>0?i/n:0,lastUpdateTime:s};this._systemData.set(t,o),this.updateStats(t,i)}updateStats(t,e){let n=this._systemStats.get(t);n||(n={totalTime:0,averageTime:0,minTime:Number.MAX_VALUE,maxTime:0,executionCount:0,recentTimes:[],standardDeviation:0,percentile95:0,percentile99:0},this._systemStats.set(t,n)),n.totalTime+=e,n.executionCount++,n.averageTime=n.totalTime/n.executionCount,n.minTime=Math.min(n.minTime,e),n.maxTime=Math.max(n.maxTime,e),n.recentTimes.push(e),n.recentTimes.length>this._maxRecentSamples&&n.recentTimes.shift(),this.calculateAdvancedStats(n)}calculateAdvancedStats(t){if(0===t.recentTimes.length)return;const e=t.recentTimes.reduce(((t,e)=>t+e),0)/t.recentTimes.length,n=t.recentTimes.reduce(((t,n)=>t+Math.pow(n-e,2)),0)/t.recentTimes.length;t.standardDeviation=Math.sqrt(n);const s=[...t.recentTimes].sort(((t,e)=>t-e)),i=s.length;t.percentile95=s[Math.floor(.95*i)]||0,t.percentile99=s[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[n,s]of e){const e=this._systemData.get(n);t.push(`System: ${n}`),t.push(` Current: ${e?.executionTime.toFixed(2)}ms (${e?.entityCount} entities)`),t.push(` Average: ${s.averageTime.toFixed(2)}ms`),t.push(` Min/Max: ${s.minTime.toFixed(2)}ms / ${s.maxTime.toFixed(2)}ms`),t.push(` Total: ${s.totalTime.toFixed(2)}ms (${s.executionCount} calls)`),e?.averageTimePerEntity&&e.averageTimePerEntity>0&&t.push(` Per Entity: ${e.averageTimePerEntity.toFixed(4)}ms`),t.push("")}const n=Array.from(this._systemData.values()).reduce(((t,e)=>t+e.executionTime),0);return t.push(`Total Frame Time: ${n.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[n,s]of this._systemData.entries())s.executionTime>t&&e.push(`${n}: ${s.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,n=1024){this._objects=[],this._createFn=t,this._maxSize=e,this._objectSize=n,this._stats={size:0,maxSize:e,totalCreated:0,totalObtained:0,totalReleased:0,hitRate:0,estimatedMemoryUsage:0}}static getPool(t,e=100,n=1024){let s=this._pools.get(t);return s||(s=new u((()=>new t),e,n),this._pools.set(t,s)),s}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,n]of this._pools.entries()){t[e.name||"Unknown"]=n.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[n,s]of Object.entries(t))e.push(`${n}:`),e.push(` Size: ${s.size}/${s.maxSize}`),e.push(` Hit Rate: ${(100*s.hitRate).toFixed(1)}%`),e.push(` Total Created: ${s.totalCreated}`),e.push(` Total Obtained: ${s.totalObtained}`),e.push(` Memory: ${(s.estimatedMemoryUsage/1024).toFixed(1)} KB`),e.push("");return e.join("\n")}}u._pools=new Map;class p{constructor(t,e,n=[10,50,200],s=1024){this.pools=[],this.totalObtained=0,this.totalReleased=0,this.createFn=t,this.resetFn=e,this.tierSizes=n;for(const e of n)this.pools.push(new u(t,e,s))}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 n=Math.min(e,t.maxSize);if(t.warmUp(n),e-=n,e<=0)break}}clear(){for(const t of this.pools)t.clear()}getStats(){let t=0,e=0,n=0;const s=[];for(const i of this.pools){const o=i.getStats();s.push(o),t+=o.size,e+=o.maxSize,n+=o.estimatedMemoryUsage}return{totalSize:t,totalMaxSize:e,totalMemoryUsage:n,tierStats:s,hitRate:this.totalObtained>0?(this.totalObtained-this.getTotalCreated())/this.totalObtained:0}}getTotalCreated(){return this.pools.reduce(((t,e)=>t+e.getStats().totalCreated),0)}}class d{constructor(){this.pools=new Map,this.autoCompactInterval=6e4,this.lastCompactTime=0}static getInstance(){return d.instance||(d.instance=new d),d.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,n]of this.pools.entries())(n instanceof u||n instanceof p)&&t.set(e,n.getStats());return t}generateReport(){const t=[];t.push("=== Pool Manager Report ===");let e=0;for(const[n,s]of this.pools.entries())if(t.push(`\n${n}:`),s instanceof u){const n=s.getStats();t.push(" Type: Standard Pool"),t.push(` Size: ${n.size}/${n.maxSize}`),t.push(` Hit Rate: ${(100*n.hitRate).toFixed(1)}%`),t.push(` Memory: ${(n.estimatedMemoryUsage/1024).toFixed(1)} KB`),e+=n.estimatedMemoryUsage}else if(s instanceof p){const n=s.getStats();t.push(" Type: Tiered Pool"),t.push(` Total Size: ${n.totalSize}/${n.totalMaxSize}`),t.push(` Hit Rate: ${(100*n.hitRate).toFixed(1)}%`),t.push(` Memory: ${(n.totalMemoryUsage/1024).toFixed(1)} KB`),e+=n.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 n;this.freeIndices.length>0?(n=this.freeIndices.pop(),this.components[n]=e,this.indexToEntity[n]=t):(n=this.components.length,this.components.push(e),this.indexToEntity.push(t)),this.entityToIndex.set(t,n),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 n=this.components[e];return this.entityToIndex.delete(t),this.components[e]=null,this.freeIndices.push(e),this._size--,n}forEach(t){for(let e=0;e<this.components.length;e++){const n=this.components[e];n&&t(n,this.indexToEntity[e],e)}}getDenseArray(){const t=[],e=[];for(let n=0;n<this.components.length;n++){const s=this.components[n];s&&(t.push(s),e.push(this.indexToEntity[n]))}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=[],n=new Map;let s=0;for(let i=0;i<this.components.length;i++){const o=this.components[i];o&&(t[s]=o,e[s]=this.indexToEntity[i],n.set(this.indexToEntity[i],s),s++)}this.components=t,this.indexToEntity=e,this.entityToIndex=n,this.freeIndices.length=0}getStats(){const t=this.components.length,e=this._size,n=this.freeIndices.length;return{totalSlots:t,usedSlots:e,freeSlots:n,fragmentation:t>0?n/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 n=e.constructor;this.getStorage(n).addComponent(t,e)}getComponent(t,e){const n=this.storages.get(e);return n?n.getComponent(t):null}hasComponent(t,e){const n=this.storages.get(e);return!!n&&n.hasComponent(t)}removeComponent(t,e){const n=this.storages.get(e);return n?n.removeComponent(t):null}removeAllComponents(t){for(const e of this.storages.values())e.removeComponent(t)}getComponentMask(t){let e=BigInt(0);for(const[n,s]of this.storages.entries())s.hasComponent(t)&&(e|=y.getBitMask(n));return e}compactAll(){for(const t of this.storages.values())t.compact()}getAllStats(){const t=new Map;for(const[e,n]of this.storages.entries()){const s=e.name||"Unknown";t.set(s,n.getStats())}return t}clear(){for(const t of this.storages.values())t.clear();this.storages.clear()}}class _{compare(t,e){let n=t.updateOrder-e.updateOrder;return 0==n&&(n=t.id-e.id),n}}class S{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 n={component:e,lastAccessed:Date.now(),accessCount:1};this.cache.set(t,n),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 n of this.cache.values())t+=n.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 C{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 S}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 n=new t(...e);return this.addComponent(n)}addComponentInternal(t){const e=t.constructor;y.isRegistered(e)||y.register(e),t.entity=this;const n=this.components.length;return this.components.push(t),this._componentTypeToIndex.set(e,n),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(),C.eventBus&&C.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 n=this._componentCache.get(t);if(n)return this.recordCacheHit(t),n;const s=this._componentTypeToIndex.get(t);if(void 0!==s&&s<this.components.length){const e=this.components[s];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 n=this.components[e];if(n instanceof t)return this._componentTypeToIndex.set(t,e),this._componentCache.set(t,n),this.recordCacheHit(t),n}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 n=this.getComponent(t);return n||(n=this.createComponent(t,...e)),n}removeComponent(t){const e=t.constructor,n=this.components.indexOf(t);if(-1!==n&&(this.components.splice(n,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(),C.eventBus&&C.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 n of t)try{e.push(this.addComponent(n))}catch(t){console.warn(`添加组件失败 ${n.constructor.name}:`,t)}return e}removeComponentsByTypes(t){const e=[];for(const n of t)e.push(this.removeComponentByType(n));return e}getComponentCacheStats(){const t=new Map;for(const[e,n]of this._componentAccessStats){const s=n.cacheHits+n.cacheMisses;t.set(e.name,{...n,hitRate:s>0?n.cacheHits/s: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],n=e.constructor;this._componentTypeToIndex.set(n,t),this._componentCache.set(n,e)}}cleanupComponentCache(){const t=Date.now();for(const[e,n]of this._componentAccessStats)t-n.lastAccessed>3e4&&n.accessCount<5&&this._componentCache.delete(e)}getComponents(t){const e=[];for(const n of this.components)n instanceof t&&e.push(n);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 n=e.findChild(t,!0);if(n)return n}return null}findChildrenByTag(t,e=!1){const n=[];for(const e of this._children)e.tag===t&&n.push(e);if(e)for(const e of this._children)n.push(...e.findChildrenByTag(t,!0));return n}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(((n,s)=>{t(n,s),e&&n.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}}}C.entityComparer=new _,C.eventBus=null;class E{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 n of this.buffer)n.tag===t&&e.push(n);return e}findEntitiesWithComponent(t){const e=[];for(const n of this.buffer)n.hasComponent(t)&&e.push(n);return e}forEach(t){for(const e of this.buffer)t(e)}forEachWhere(t,e){for(const n of this.buffer)t(n)&&e(n)}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 n=e.indexOf(t);-1!==n&&(e.splice(n,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 T{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,n=1e3){this.pool=[],this.createFn=t,this.resetFn=e,this.maxSize=n}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 I{constructor(){this.pools=new Map}static getInstance(){return I.instance||(I.instance=new I),I.instance}registerPool(t,e,n,s){this.pools.set(t,new b(e,n,s))}acquireComponent(t){const e=this.pools.get(t);return e?e.acquire():null}releaseComponent(t,e){const n=this.pools.get(t);n&&n.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,n]of this.pools)t.set(e,{available:n.getAvailableCount(),maxSize:n.getMaxSize()});return t}getPoolUtilization(){const t=new Map;for(const[e,n]of this.pools){const s=n.getAvailableCount(),i=n.getMaxSize(),o=i-s,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 n=e.getAvailableCount(),s=e.getMaxSize();return s>0?(s-n)/s*100:0}}class v{constructor(){this.maskCache=new Map,this.componentTypeMap=new Map,this.nextComponentId=0}static getInstance(){return v.instance||(v.instance=new v),v.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 n=this.getComponentTypeId(t);if(void 0===n)throw new Error(`Component type not registered: ${t}`);const s=1n<<BigInt(n);return this.maskCache.set(e,s),s}createCombinedMask(t){const e=`combined:${[...t].sort().join(",")}`;if(this.maskCache.has(e))return this.maskCache.get(e);let n=0n;for(const e of t){const t=this.getComponentTypeId(e);if(void 0===t)throw new Error(`Component type not registered: ${e}`);n|=1n<<BigInt(t)}return this.maskCache.set(e,n),n}maskContainsComponent(t,e){return 0n!==(t&this.createSingleComponentMask(e))}maskContainsAllComponents(t,e){const n=this.createCombinedMask(e);return(t&n)===n}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[n,s]of this.componentTypeMap){0n!==(t&1n<<BigInt(s))&&e.push(n)}return e}getComponentCount(t){let e=0,n=t;for(;0n!==n;)0n!=(1n&n)&&e++,n>>=1n;return e}}!function(t){t.ADD_ENTITY="add_entity",t.REMOVE_ENTITY="remove_entity",t.UPDATE_ENTITY="update_entity"}(o||(o={}));class w{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=[],n=[],s=[];for(const i of t)switch(i.type){case o.ADD_ENTITY:e.push(i.entity);break;case o.REMOVE_ENTITY:n.push(i.entity);break;case o.UPDATE_ENTITY:void 0!==i.oldMask&&void 0!==i.newMask&&s.push({entity:i.entity,oldMask:i.oldMask,newMask:i.newMask})}e.length>0&&this.processBatchAdd(e),n.length>0&&this.processBatchRemove(n),s.length>0&&this.processBatchUpdate(s)}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 D{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,n=new Set;for(const s of e){const e=s.constructor;n.add(e);let i=this._componentToEntities.get(e);i||(i=new Set,this._componentToEntities.set(e,i)),i.add(t)}this._entityToComponents.set(t,n),this._lastUpdated=Date.now()}removeEntity(t){const e=this._entityToComponents.get(t);if(e){for(const n of e){const e=this._componentToEntities.get(n);e&&(e.delete(t),0===e.size&&this._componentToEntities.delete(n))}this._entityToComponents.delete(t),this._lastUpdated=Date.now()}}query(t){const e=performance.now(),n=new Set(this._componentToEntities.get(t)||[]);return this._queryCount++,this._totalQueryTime+=performance.now()-e,n}queryMultiple(t,e){const n=performance.now();if(0===t.length)return new Set;if(1===t.length)return this.query(t[0]);let s;if("AND"===e){let e,i=1/0;for(const s of t){const t=this._componentToEntities.get(s);if(!t||0===t.size)return this._queryCount++,this._totalQueryTime+=performance.now()-n,new Set;t.size<i&&(i=t.size,e=t)}if(s=new Set,e)for(const n of e){let e=!0;for(const s of t){const t=this._componentToEntities.get(s);if(!t||!t.has(n)){e=!1;break}}e&&s.add(n)}}else{s=new Set;for(const e of t){const t=this._componentToEntities.get(e);if(t)for(const e of t)s.add(e)}}return this._queryCount++,this._totalQueryTime+=performance.now()-n,s}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 x{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 n of t.components){const s=n.constructor;let i=this._componentTypeToBit.get(s);void 0===i&&(i=this._nextBit++,this._componentTypeToBit.set(s,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[n,s]of this._bitToEntities)0!==(e&n)&&(s.delete(t),0===s.size&&this._bitToEntities.delete(n));this._entityToBitmap.delete(t),this._lastUpdated=Date.now()}}query(t){const e=performance.now(),n=this._componentTypeToBit.get(t);if(void 0===n)return this._queryCount++,this._totalQueryTime+=performance.now()-e,new Set;const s=new Set(this._bitToEntities.get(1<<n)||[]);return this._queryCount++,this._totalQueryTime+=performance.now()-e,s}queryMultiple(t,e){const n=performance.now();if(0===t.length)return new Set;let s=0;const i=[];for(const e of t){const t=this._componentTypeToBit.get(e);void 0!==t&&(s|=1<<t,i.push(1<<t))}const o=new Set;if("AND"===e)for(const[t,e]of this._entityToBitmap)(e&s)===s&&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()-n,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 D;case r.BITMAP:return new x;case r.SORTED:default:return new D}}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),n=this.generateArchetypeId(e);let s=this._archetypes.get(n);s||(s=this.createArchetype(e)),s.entities.push(t),s.updatedAt=Date.now(),this._entityToArchetype.set(t,s),this.updateComponentIndexes(s,e,!0),this.invalidateQueryCache()}removeEntity(t){const e=this._entityToArchetype.get(t);if(!e)return;const n=e.entities.indexOf(t);-1!==n&&(e.entities.splice(n,1),e.updatedAt=Date.now()),this._entityToArchetype.delete(t),this.invalidateQueryCache()}queryArchetypes(t,e="AND"){const n=performance.now(),s=`${e}:${t.map((t=>t.name)).sort().join(",")}`,i=this._queryCache.get(s);if(i&&Date.now()-i.timestamp<this._cacheTimeout)return{...i.result,executionTime:performance.now()-n,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 n of t){const t=this._componentToArchetypes.get(n);if(t)for(const n of t)e.add(n)}for(const t of e)o.push(t),r+=t.entities.length}const a={archetypes:o,totalEntities:r,executionTime:performance.now()-n,fromCache:!1};return this._queryCache.set(s,{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),n={id:e,componentTypes:[...t],entities:[],createdAt:Date.now(),updatedAt:Date.now()};return this._archetypes.set(e,n),n}archetypeContainsAllComponents(t,e){for(const n of e)if(!t.componentTypes.includes(n))return!1;return!0}updateComponentIndexes(t,e,n){for(const s of e){let e=this._componentToArchetypes.get(s);e||(e=new Set,this._componentToArchetypes.set(s,e)),n?e.add(t):(e.delete(t),0===e.size&&this._componentToArchetypes.delete(s))}}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 z{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,n=[]){this._stats.totalMarkings++;let s=this._dirtyEntities.get(t);s||(s={entity:t,flags:0,modifiedComponents:new Set,timestamp:performance.now(),frameNumber:this._currentFrame},this._dirtyEntities.set(t,s)),s.flags|=e,s.timestamp=performance.now(),s.frameNumber=this._currentFrame;for(const t of n)s.modifiedComponents.add(t);this.notifyListeners(s,e)}isDirty(t,e=a.ALL){const n=this._dirtyEntities.get(t);return!!n&&0!==(n.flags&e)}clearDirty(t,e=a.ALL){const n=this._dirtyEntities.get(t);n&&(e===a.ALL?this._dirtyEntities.delete(t):(n.flags&=~e,0===n.flags&&this._dirtyEntities.delete(t)),this._stats.totalCleanups++)}getDirtyEntities(t=a.ALL){const e=[];for(const n of this._dirtyEntities.values())0!==(n.flags&t)&&e.push(n);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 n=this._processingQueue.shift();this.processEntity(n),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("脏数据监听器错误:",t)}this.clearDirty(t.entity)}notifyListeners(t,e){for(const n of this._listeners)if(0!==(e&n.flags))try{n.callback(t)}catch(t){console.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 N{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=I.getInstance(),this.bitMaskOptimizer=v.getInstance(),this.indexUpdateBatcher=new w,this.componentIndexManager=new A(r.HASH),this.archetypeSystem=new O,this.dirtyTrackingSystem=new z,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 n=0;for(const s of t)e.has(s.id)||(this.entities.push(s),this.addEntityToIndexes(s),e.add(s.id),n++);n>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 n=this.entityIndex.byMask.get(e);n||(n=new Set,this.entityIndex.byMask.set(e,n)),n.add(t);const s=t.components;for(let e=0;e<s.length;e++){const n=s[e].constructor;let i=this.entityIndex.byComponentType.get(n);i||(i=new Set,this.entityIndex.byComponentType.set(n,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,n=this.entityIndex.byMask.get(e);n&&(n.delete(t),0===n.size&&this.entityIndex.byMask.delete(e));for(const e of t.components){const n=e.constructor,s=this.entityIndex.byComponentType.get(n);s&&(s.delete(t),0===s.size&&this.entityIndex.byComponentType.delete(n))}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 n=`all:${t.map((t=>t.name)).sort().join(",")}`,s=this.getFromCache(n);if(s)return this.queryStats.cacheHits++,{entities:s,count:s.length,executionTime:performance.now()-e,fromCache:!0};let i=[];const o=this.archetypeSystem.queryArchetypes(t,"AND");if(o.archetypes.length>0){this.queryStats.archetypeHits++;for(const t of o.archetypes)i.push(...t.entities)}else try{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)}}catch(t){i=[]}return 0===i.length&&this.entities.length>0&&(this.queryStats.linearScans++,i=this.queryByLinearScan(t)),this.addToCache(n,i),{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!1}}queryMultipleComponents(t){let e=null,n=1/0;for(const s of t){const t=this.entityIndex.byComponentType.get(s);if(!t||0===t.size)return[];t.size<n&&(n=t.size,e=t)}if(!e)return this.queryStats.linearScans++,this.queryByLinearScan(t);const s=this.createComponentMask(t),i=[];for(const t of e)(t.componentMask&s)===s&&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 n=`any:${t.map((t=>t.name)).sort().join(",")}`,s=this.getFromCache(n);if(s)return this.queryStats.cacheHits++,{entities:s,count:s.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(n,o),{entities:o,count:o.length,executionTime:performance.now()-e,fromCache:!1}}queryNone(...t){const e=performance.now();this.queryStats.totalQueries++;const n=`none:${t.map((t=>t.name)).sort().join(",")}`,s=this.getFromCache(n);if(s)return this.queryStats.cacheHits++,{entities:s,count:s.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(n,o),{entities:o,count:o.length,executionTime:performance.now()-e,fromCache:!1}}queryByTag(t){const e=performance.now();this.queryStats.totalQueries++;const n=`tag:${t}`,s=this.getFromCache(n);if(s)return this.queryStats.cacheHits++,{entities:s,count:s.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;const i=Array.from(this.entityIndex.byTag.get(t)||[]);return this.addToCache(n,i),{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!1}}queryByName(t){const e=performance.now();this.queryStats.totalQueries++;const n=`name:${t}`,s=this.getFromCache(n);if(s)return this.queryStats.cacheHits++,{entities:s,count:s.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;const i=Array.from(this.entityIndex.byName.get(t)||[]);return this.addToCache(n,i),{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!1}}queryByComponent(t){const e=performance.now();this.queryStats.totalQueries++;const n=`component:${t.name}`,s=this.getFromCache(n);if(s)return this.queryStats.cacheHits++,{entities:s,count:s.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;const i=Array.from(thi