UNPKG

@esengine/ecs-framework

Version:

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

1 lines 563 kB
{"version":3,"file":"index.mjs","sources":["../bin/Utils/GlobalManager.js","../bin/Utils/Time.js","../bin/Utils/Timers/Timer.js","../bin/Utils/Timers/TimerManager.js","../bin/Utils/PerformanceMonitor.js","../bin/ECS/Core/IndexUpdateBatcher.js","../bin/ECS/Core/ComponentIndex.js","../bin/ECS/Core/DirtyTrackingSystem.js","../bin/ECS/Core/QuerySystem.js","../bin/ECS/CoreEvents.js","../bin/Utils/Pool.js","../bin/ECS/Core/ComponentStorage.js","../bin/ECS/Entity.js","../bin/ECS/Utils/EntityList.js","../bin/ECS/Utils/EntityProcessorList.js","../bin/ECS/Utils/IdentifierPool.js","../bin/ECS/Core/ComponentPool.js","../bin/ECS/Core/BitMaskOptimizer.js","../bin/ECS/Core/ArchetypeSystem.js","../bin/ECS/Core/EventSystem.js","../bin/ECS/Scene.js","../bin/ECS/Core/FluentAPI.js","../bin/Utils/Debug/EntityDataCollector.js","../bin/Utils/Debug/SystemDataCollector.js","../bin/Utils/Debug/PerformanceDataCollector.js","../bin/Utils/Debug/ComponentDataCollector.js","../bin/Utils/Debug/SceneDataCollector.js","../bin/Utils/Debug/WebSocketManager.js","../bin/Utils/Debug/DebugManager.js","../bin/Core.js","../bin/Utils/Emitter.js","../bin/ECS/Component.js","../bin/ECS/Utils/Bits.js","../bin/ECS/Utils/ComponentTypeManager.js","../bin/ECS/Utils/Matcher.js","../bin/ECS/Systems/EntitySystem.js","../bin/ECS/Systems/ProcessingSystem.js","../bin/ECS/Systems/PassiveSystem.js","../bin/ECS/Systems/IntervalSystem.js","../bin/ECS/Core/EventBus.js","../bin/ECS/Core/EntityManager.js","../bin/Utils/Extensions/TypeUtils.js","../bin/Utils/Extensions/NumberExtension.js","../bin/Utils/Snapshot/SnapshotManager.js","../bin/Utils/Snapshot/SnapshotExtension.js"],"sourcesContent":["/**\n * 全局管理器的基类。所有全局管理器都应该从此类继承。\n */\nexport class GlobalManager {\n constructor() {\n /**\n * 表示管理器是否启用\n */\n this._enabled = false;\n }\n /**\n * 获取或设置管理器是否启用\n */\n get enabled() {\n return this._enabled;\n }\n set enabled(value) {\n this.setEnabled(value);\n }\n /**\n * 设置管理器是否启用\n * @param isEnabled 如果为true,则启用管理器;否则禁用管理器\n */\n setEnabled(isEnabled) {\n if (this._enabled != isEnabled) {\n this._enabled = isEnabled;\n if (this._enabled) {\n // 如果启用了管理器,则调用onEnabled方法\n this.onEnabled();\n }\n else {\n // 如果禁用了管理器,则调用onDisabled方法\n this.onDisabled();\n }\n }\n }\n /**\n * 在启用管理器时调用的回调方法\n */\n onEnabled() {\n }\n /**\n * 在禁用管理器时调用的回调方法\n */\n onDisabled() {\n }\n /**\n * 更新管理器状态的方法\n */\n update() {\n }\n}\n//# sourceMappingURL=GlobalManager.js.map","/**\n * 时间管理工具类\n * 提供游戏时间相关的功能,包括帧时间、总时间、时间缩放等\n */\nexport class Time {\n /**\n * 使用外部引擎提供的deltaTime更新时间信息\n * @param deltaTime 外部引擎提供的帧时间间隔(秒)\n */\n static update(deltaTime) {\n // 设置未缩放的帧时间\n this.unscaledDeltaTime = deltaTime;\n this.deltaTime = deltaTime * this.timeScale;\n // 更新总时间\n this.unscaledTotalTime += this.unscaledDeltaTime;\n this.totalTime += this.deltaTime;\n // 更新帧数\n this.frameCount++;\n }\n /**\n * 场景改变时重置时间\n */\n static sceneChanged() {\n this.frameCount = 0;\n this.totalTime = 0;\n this.unscaledTotalTime = 0;\n this.deltaTime = 0;\n this.unscaledDeltaTime = 0;\n }\n /**\n * 检查指定的时间间隔是否已经过去\n * @param interval 时间间隔(秒)\n * @param lastTime 上次检查的时间\n * @returns 是否已经过去指定时间\n */\n static checkEvery(interval, lastTime) {\n return this.totalTime - lastTime >= interval;\n }\n}\n/**\n * 上一帧到当前帧的时间间隔(秒)\n */\nTime.deltaTime = 0;\n/**\n * 未缩放的帧时间间隔(秒)\n */\nTime.unscaledDeltaTime = 0;\n/**\n * 游戏开始以来的总时间(秒)\n */\nTime.totalTime = 0;\n/**\n * 未缩放的总时间(秒)\n */\nTime.unscaledTotalTime = 0;\n/**\n * 时间缩放比例\n */\nTime.timeScale = 1;\n/**\n * 当前帧数\n */\nTime.frameCount = 0;\n//# sourceMappingURL=Time.js.map","import { Time } from '../Time';\n/**\n * 私有类隐藏ITimer的实现\n */\nexport class Timer {\n constructor() {\n this._timeInSeconds = 0;\n this._repeats = false;\n this._isDone = false;\n this._elapsedTime = 0;\n }\n getContext() {\n return this.context;\n }\n /**\n * 定时器是否已完成\n */\n get isDone() {\n return this._isDone;\n }\n /**\n * 定时器已运行的时间\n */\n get elapsedTime() {\n return this._elapsedTime;\n }\n reset() {\n this._elapsedTime = 0;\n }\n stop() {\n this._isDone = true;\n }\n tick() {\n // 如果stop在tick之前被调用,那么isDone将为true,我们不应该再做任何事情\n if (!this._isDone && this._elapsedTime > this._timeInSeconds) {\n this._elapsedTime -= this._timeInSeconds;\n this._onTime(this);\n if (!this._isDone && !this._repeats)\n this._isDone = true;\n }\n this._elapsedTime += Time.deltaTime;\n return this._isDone;\n }\n initialize(timeInsSeconds, repeats, context, onTime) {\n this._timeInSeconds = timeInsSeconds;\n this._repeats = repeats;\n this.context = context;\n this._onTime = onTime.bind(context);\n }\n /**\n * 空出对象引用,以便在js需要时GC可以清理它们的引用\n */\n unload() {\n this.context = null;\n this._onTime = null;\n }\n}\n//# sourceMappingURL=Timer.js.map","import { GlobalManager } from '../GlobalManager';\nimport { Timer } from './Timer';\n/**\n * 允许动作的延迟和重复执行\n */\nexport class TimerManager extends GlobalManager {\n constructor() {\n super(...arguments);\n this._timers = [];\n }\n update() {\n for (let i = this._timers.length - 1; i >= 0; i--) {\n if (this._timers[i].tick()) {\n this._timers[i].unload();\n this._timers.splice(i, 1);\n }\n }\n }\n /**\n * 调度一个一次性或重复的计时器,该计时器将调用已传递的动作\n * @param timeInSeconds\n * @param repeats\n * @param context\n * @param onTime\n */\n schedule(timeInSeconds, repeats, context, onTime) {\n let timer = new Timer();\n timer.initialize(timeInSeconds, repeats, context, onTime);\n this._timers.push(timer);\n return timer;\n }\n}\n//# sourceMappingURL=TimerManager.js.map","/**\n * 性能警告类型\n */\nexport var PerformanceWarningType;\n(function (PerformanceWarningType) {\n PerformanceWarningType[\"HIGH_EXECUTION_TIME\"] = \"high_execution_time\";\n PerformanceWarningType[\"HIGH_MEMORY_USAGE\"] = \"high_memory_usage\";\n PerformanceWarningType[\"HIGH_CPU_USAGE\"] = \"high_cpu_usage\";\n PerformanceWarningType[\"FREQUENT_GC\"] = \"frequent_gc\";\n PerformanceWarningType[\"LOW_FPS\"] = \"low_fps\";\n PerformanceWarningType[\"HIGH_ENTITY_COUNT\"] = \"high_entity_count\";\n})(PerformanceWarningType || (PerformanceWarningType = {}));\n/**\n * 高性能监控器\n * 用于监控ECS系统的性能表现,提供详细的分析和优化建议\n */\nexport class PerformanceMonitor {\n /**\n * 获取单例实例\n */\n static get instance() {\n if (!PerformanceMonitor._instance) {\n PerformanceMonitor._instance = new PerformanceMonitor();\n }\n return PerformanceMonitor._instance;\n }\n constructor() {\n this._systemData = new Map();\n this._systemStats = new Map();\n this._warnings = [];\n this._isEnabled = false;\n this._maxRecentSamples = 60; // 保留最近60帧的数据\n this._maxWarnings = 100; // 最大警告数量\n // 性能阈值配置\n this._thresholds = {\n executionTime: { warning: 16.67, critical: 33.33 }, // 60fps和30fps对应的帧时间\n memoryUsage: { warning: 100, critical: 200 }, // MB\n cpuUsage: { warning: 70, critical: 90 }, // 百分比\n fps: { warning: 45, critical: 30 },\n entityCount: { warning: 1000, critical: 5000 }\n };\n // FPS监控\n this._fpsHistory = [];\n this._lastFrameTime = 0;\n this._frameCount = 0;\n this._fpsUpdateInterval = 1000; // 1秒更新一次FPS\n this._lastFpsUpdate = 0;\n this._currentFps = 60;\n // 内存监控\n this._memoryCheckInterval = 5000; // 5秒检查一次内存\n this._lastMemoryCheck = 0;\n this._memoryHistory = [];\n // GC监控\n this._gcCount = 0;\n this._lastGcCheck = 0;\n this._gcCheckInterval = 1000;\n }\n /**\n * 启用性能监控\n */\n enable() {\n this._isEnabled = true;\n }\n /**\n * 禁用性能监控\n */\n disable() {\n this._isEnabled = false;\n }\n /**\n * 检查是否启用了性能监控\n */\n get isEnabled() {\n return this._isEnabled;\n }\n /**\n * 开始监控系统性能\n * @param systemName 系统名称\n * @returns 开始时间戳\n */\n startMonitoring(systemName) {\n if (!this._isEnabled) {\n return 0;\n }\n return performance.now();\n }\n /**\n * 结束监控并记录性能数据\n * @param systemName 系统名称\n * @param startTime 开始时间戳\n * @param entityCount 处理的实体数量\n */\n endMonitoring(systemName, startTime, entityCount = 0) {\n if (!this._isEnabled || startTime === 0) {\n return;\n }\n const endTime = performance.now();\n const executionTime = endTime - startTime;\n const averageTimePerEntity = entityCount > 0 ? executionTime / entityCount : 0;\n // 更新当前性能数据\n const data = {\n name: systemName,\n executionTime,\n entityCount,\n averageTimePerEntity,\n lastUpdateTime: endTime\n };\n this._systemData.set(systemName, data);\n // 更新统计信息\n this.updateStats(systemName, executionTime);\n }\n /**\n * 更新系统统计信息\n * @param systemName 系统名称\n * @param executionTime 执行时间\n */\n updateStats(systemName, executionTime) {\n let stats = this._systemStats.get(systemName);\n if (!stats) {\n stats = {\n totalTime: 0,\n averageTime: 0,\n minTime: Number.MAX_VALUE,\n maxTime: 0,\n executionCount: 0,\n recentTimes: [],\n standardDeviation: 0,\n percentile95: 0,\n percentile99: 0\n };\n this._systemStats.set(systemName, stats);\n }\n // 更新基本统计\n stats.totalTime += executionTime;\n stats.executionCount++;\n stats.averageTime = stats.totalTime / stats.executionCount;\n stats.minTime = Math.min(stats.minTime, executionTime);\n stats.maxTime = Math.max(stats.maxTime, executionTime);\n // 更新最近时间列表\n stats.recentTimes.push(executionTime);\n if (stats.recentTimes.length > this._maxRecentSamples) {\n stats.recentTimes.shift();\n }\n // 计算高级统计信息\n this.calculateAdvancedStats(stats);\n }\n /**\n * 计算高级统计信息\n * @param stats 统计信息对象\n */\n calculateAdvancedStats(stats) {\n if (stats.recentTimes.length === 0)\n return;\n // 计算标准差\n const mean = stats.recentTimes.reduce((a, b) => a + b, 0) / stats.recentTimes.length;\n const variance = stats.recentTimes.reduce((acc, time) => acc + Math.pow(time - mean, 2), 0) / stats.recentTimes.length;\n stats.standardDeviation = Math.sqrt(variance);\n // 计算百分位数\n const sortedTimes = [...stats.recentTimes].sort((a, b) => a - b);\n const len = sortedTimes.length;\n stats.percentile95 = sortedTimes[Math.floor(len * 0.95)] || 0;\n stats.percentile99 = sortedTimes[Math.floor(len * 0.99)] || 0;\n }\n /**\n * 获取系统的当前性能数据\n * @param systemName 系统名称\n * @returns 性能数据或undefined\n */\n getSystemData(systemName) {\n return this._systemData.get(systemName);\n }\n /**\n * 获取系统的统计信息\n * @param systemName 系统名称\n * @returns 统计信息或undefined\n */\n getSystemStats(systemName) {\n return this._systemStats.get(systemName);\n }\n /**\n * 获取所有系统的性能数据\n * @returns 所有系统的性能数据\n */\n getAllSystemData() {\n return new Map(this._systemData);\n }\n /**\n * 获取所有系统的统计信息\n * @returns 所有系统的统计信息\n */\n getAllSystemStats() {\n return new Map(this._systemStats);\n }\n /**\n * 获取性能报告\n * @returns 格式化的性能报告字符串\n */\n getPerformanceReport() {\n if (!this._isEnabled) {\n return \"Performance monitoring is disabled.\";\n }\n const lines = [];\n lines.push(\"=== ECS Performance Report ===\");\n lines.push(\"\");\n // 按平均执行时间排序\n const sortedSystems = Array.from(this._systemStats.entries())\n .sort((a, b) => b[1].averageTime - a[1].averageTime);\n for (const [systemName, stats] of sortedSystems) {\n const data = this._systemData.get(systemName);\n lines.push(`System: ${systemName}`);\n lines.push(` Current: ${data?.executionTime.toFixed(2)}ms (${data?.entityCount} entities)`);\n lines.push(` Average: ${stats.averageTime.toFixed(2)}ms`);\n lines.push(` Min/Max: ${stats.minTime.toFixed(2)}ms / ${stats.maxTime.toFixed(2)}ms`);\n lines.push(` Total: ${stats.totalTime.toFixed(2)}ms (${stats.executionCount} calls)`);\n if (data?.averageTimePerEntity && data.averageTimePerEntity > 0) {\n lines.push(` Per Entity: ${data.averageTimePerEntity.toFixed(4)}ms`);\n }\n lines.push(\"\");\n }\n // 总体统计\n const totalCurrentTime = Array.from(this._systemData.values())\n .reduce((sum, data) => sum + data.executionTime, 0);\n lines.push(`Total Frame Time: ${totalCurrentTime.toFixed(2)}ms`);\n lines.push(`Systems Count: ${this._systemData.size}`);\n return lines.join('\\n');\n }\n /**\n * 重置所有性能数据\n */\n reset() {\n this._systemData.clear();\n this._systemStats.clear();\n }\n /**\n * 重置指定系统的性能数据\n * @param systemName 系统名称\n */\n resetSystem(systemName) {\n this._systemData.delete(systemName);\n this._systemStats.delete(systemName);\n }\n /**\n * 获取性能警告\n * @param thresholdMs 警告阈值(毫秒)\n * @returns 超过阈值的系统列表\n */\n getPerformanceWarnings(thresholdMs = 16.67) {\n const warnings = [];\n for (const [systemName, data] of this._systemData.entries()) {\n if (data.executionTime > thresholdMs) {\n warnings.push(`${systemName}: ${data.executionTime.toFixed(2)}ms (>${thresholdMs}ms)`);\n }\n }\n return warnings;\n }\n /**\n * 设置最大保留样本数\n * @param maxSamples 最大样本数\n */\n setMaxRecentSamples(maxSamples) {\n this._maxRecentSamples = maxSamples;\n // 裁剪现有数据\n for (const stats of this._systemStats.values()) {\n while (stats.recentTimes.length > maxSamples) {\n stats.recentTimes.shift();\n }\n }\n }\n}\n//# sourceMappingURL=PerformanceMonitor.js.map","/**\n * 索引更新操作类型\n */\nexport var IndexUpdateType;\n(function (IndexUpdateType) {\n IndexUpdateType[\"ADD_ENTITY\"] = \"add_entity\";\n IndexUpdateType[\"REMOVE_ENTITY\"] = \"remove_entity\";\n IndexUpdateType[\"UPDATE_ENTITY\"] = \"update_entity\";\n})(IndexUpdateType || (IndexUpdateType = {}));\n/**\n * 延迟索引更新器,用于批量更新查询索引以提高性能\n */\nexport class IndexUpdateBatcher {\n constructor() {\n this.pendingOperations = [];\n this.isProcessing = false;\n this.batchSize = 1000;\n this.flushTimeout = null;\n this.flushDelay = 16; // 16ms,约60fps\n }\n /**\n * 添加索引更新操作\n */\n addOperation(operation) {\n this.pendingOperations.push(operation);\n // 如果达到批量大小,立即处理\n if (this.pendingOperations.length >= this.batchSize) {\n this.flush();\n }\n else {\n // 否则延迟处理\n this.scheduleFlush();\n }\n }\n /**\n * 批量添加实体\n */\n addEntities(entities) {\n for (const entity of entities) {\n this.pendingOperations.push({\n type: IndexUpdateType.ADD_ENTITY,\n entity\n });\n }\n if (this.pendingOperations.length >= this.batchSize) {\n this.flush();\n }\n else {\n this.scheduleFlush();\n }\n }\n /**\n * 批量移除实体\n */\n removeEntities(entities) {\n for (const entity of entities) {\n this.pendingOperations.push({\n type: IndexUpdateType.REMOVE_ENTITY,\n entity\n });\n }\n if (this.pendingOperations.length >= this.batchSize) {\n this.flush();\n }\n else {\n this.scheduleFlush();\n }\n }\n /**\n * 批量更新实体\n */\n updateEntities(updates) {\n for (const update of updates) {\n this.pendingOperations.push({\n type: IndexUpdateType.UPDATE_ENTITY,\n entity: update.entity,\n oldMask: update.oldMask,\n newMask: update.newMask\n });\n }\n if (this.pendingOperations.length >= this.batchSize) {\n this.flush();\n }\n else {\n this.scheduleFlush();\n }\n }\n /**\n * 安排延迟刷新\n */\n scheduleFlush() {\n if (this.flushTimeout) {\n return;\n }\n this.flushTimeout = setTimeout(() => {\n this.flush();\n }, this.flushDelay);\n }\n /**\n * 立即处理所有待处理的操作\n */\n flush() {\n if (this.isProcessing || this.pendingOperations.length === 0) {\n return;\n }\n this.isProcessing = true;\n if (this.flushTimeout) {\n clearTimeout(this.flushTimeout);\n this.flushTimeout = null;\n }\n try {\n this.processBatch();\n }\n finally {\n this.isProcessing = false;\n }\n }\n /**\n * 处理批量操作\n */\n processBatch() {\n const operations = this.pendingOperations;\n this.pendingOperations = [];\n // 按操作类型分组以优化处理\n const addOperations = [];\n const removeOperations = [];\n const updateOperations = [];\n for (const operation of operations) {\n switch (operation.type) {\n case IndexUpdateType.ADD_ENTITY:\n addOperations.push(operation.entity);\n break;\n case IndexUpdateType.REMOVE_ENTITY:\n removeOperations.push(operation.entity);\n break;\n case IndexUpdateType.UPDATE_ENTITY:\n if (operation.oldMask !== undefined && operation.newMask !== undefined) {\n updateOperations.push({\n entity: operation.entity,\n oldMask: operation.oldMask,\n newMask: operation.newMask\n });\n }\n break;\n }\n }\n // 批量处理每种类型的操作\n if (addOperations.length > 0) {\n this.processBatchAdd(addOperations);\n }\n if (removeOperations.length > 0) {\n this.processBatchRemove(removeOperations);\n }\n if (updateOperations.length > 0) {\n this.processBatchUpdate(updateOperations);\n }\n }\n /**\n * 批量处理添加操作\n */\n processBatchAdd(entities) {\n // 这里应该调用QuerySystem的批量添加方法\n // 由于需要访问QuerySystem,这个方法应该由外部注入处理函数\n if (this.onBatchAdd) {\n this.onBatchAdd(entities);\n }\n }\n /**\n * 批量处理移除操作\n */\n processBatchRemove(entities) {\n if (this.onBatchRemove) {\n this.onBatchRemove(entities);\n }\n }\n /**\n * 批量处理更新操作\n */\n processBatchUpdate(updates) {\n if (this.onBatchUpdate) {\n this.onBatchUpdate(updates);\n }\n }\n /**\n * 设置批量大小\n */\n setBatchSize(size) {\n this.batchSize = Math.max(1, size);\n }\n /**\n * 设置刷新延迟\n */\n setFlushDelay(delay) {\n this.flushDelay = Math.max(0, delay);\n }\n /**\n * 获取待处理操作数量\n */\n getPendingCount() {\n return this.pendingOperations.length;\n }\n /**\n * 清空所有待处理操作\n */\n clear() {\n this.pendingOperations.length = 0;\n if (this.flushTimeout) {\n clearTimeout(this.flushTimeout);\n this.flushTimeout = null;\n }\n }\n /**\n * 检查是否有待处理操作\n */\n hasPendingOperations() {\n return this.pendingOperations.length > 0;\n }\n}\n//# sourceMappingURL=IndexUpdateBatcher.js.map","/**\n * 组件索引类型\n */\nexport var IndexType;\n(function (IndexType) {\n /** 哈希索引 - 最快查找 */\n IndexType[\"HASH\"] = \"hash\";\n /** 位图索引 - 内存高效 */\n IndexType[\"BITMAP\"] = \"bitmap\";\n /** 排序索引 - 支持范围查询 */\n IndexType[\"SORTED\"] = \"sorted\";\n})(IndexType || (IndexType = {}));\n/**\n * 哈希索引实现\n *\n * 使用Map数据结构,提供O(1)的查找性能。\n * 适合大多数查询场景。\n */\nexport class HashComponentIndex {\n constructor() {\n this.type = IndexType.HASH;\n this._componentToEntities = new Map();\n this._entityToComponents = new Map();\n this._queryCount = 0;\n this._totalQueryTime = 0;\n this._lastUpdated = Date.now();\n }\n addEntity(entity) {\n const components = entity.components;\n const componentTypes = new Set();\n for (const component of components) {\n const componentType = component.constructor;\n componentTypes.add(componentType);\n let entities = this._componentToEntities.get(componentType);\n if (!entities) {\n entities = new Set();\n this._componentToEntities.set(componentType, entities);\n }\n entities.add(entity);\n }\n this._entityToComponents.set(entity, componentTypes);\n this._lastUpdated = Date.now();\n }\n removeEntity(entity) {\n const componentTypes = this._entityToComponents.get(entity);\n if (!componentTypes)\n return;\n for (const componentType of componentTypes) {\n const entities = this._componentToEntities.get(componentType);\n if (entities) {\n entities.delete(entity);\n if (entities.size === 0) {\n this._componentToEntities.delete(componentType);\n }\n }\n }\n this._entityToComponents.delete(entity);\n this._lastUpdated = Date.now();\n }\n query(componentType) {\n const startTime = performance.now();\n const result = new Set(this._componentToEntities.get(componentType) || []);\n this._queryCount++;\n this._totalQueryTime += performance.now() - startTime;\n return result;\n }\n queryMultiple(componentTypes, operation) {\n const startTime = performance.now();\n if (componentTypes.length === 0) {\n return new Set();\n }\n if (componentTypes.length === 1) {\n return this.query(componentTypes[0]);\n }\n let result;\n if (operation === 'AND') {\n let smallestSet;\n let smallestSize = Infinity;\n for (const componentType of componentTypes) {\n const entities = this._componentToEntities.get(componentType);\n if (!entities || entities.size === 0) {\n this._queryCount++;\n this._totalQueryTime += performance.now() - startTime;\n return new Set();\n }\n if (entities.size < smallestSize) {\n smallestSize = entities.size;\n smallestSet = entities;\n }\n }\n result = new Set();\n if (smallestSet) {\n for (const entity of smallestSet) {\n let hasAll = true;\n for (const componentType of componentTypes) {\n const entities = this._componentToEntities.get(componentType);\n if (!entities || !entities.has(entity)) {\n hasAll = false;\n break;\n }\n }\n if (hasAll) {\n result.add(entity);\n }\n }\n }\n }\n else {\n result = new Set();\n for (const componentType of componentTypes) {\n const entities = this._componentToEntities.get(componentType);\n if (entities) {\n for (const entity of entities) {\n result.add(entity);\n }\n }\n }\n }\n this._queryCount++;\n this._totalQueryTime += performance.now() - startTime;\n return result;\n }\n clear() {\n this._componentToEntities.clear();\n this._entityToComponents.clear();\n this._lastUpdated = Date.now();\n }\n getStats() {\n let memoryUsage = 0;\n memoryUsage += this._componentToEntities.size * 64;\n memoryUsage += this._entityToComponents.size * 64;\n for (const entities of this._componentToEntities.values()) {\n memoryUsage += entities.size * 8;\n }\n for (const components of this._entityToComponents.values()) {\n memoryUsage += components.size * 8;\n }\n return {\n type: this.type,\n size: this._componentToEntities.size,\n memoryUsage,\n queryCount: this._queryCount,\n avgQueryTime: this._queryCount > 0 ? this._totalQueryTime / this._queryCount : 0,\n lastUpdated: this._lastUpdated\n };\n }\n}\n/**\n * 位图索引实现\n *\n * 使用位操作进行快速集合运算,内存效率高。\n * 适合有限组件类型和大量实体的场景。\n */\nexport class BitmapComponentIndex {\n constructor() {\n this.type = IndexType.BITMAP;\n this._componentTypeToBit = new Map();\n this._entityToBitmap = new Map();\n this._bitToEntities = new Map();\n this._nextBit = 0;\n this._queryCount = 0;\n this._totalQueryTime = 0;\n this._lastUpdated = Date.now();\n }\n addEntity(entity) {\n let bitmap = 0;\n for (const component of entity.components) {\n const componentType = component.constructor;\n let bit = this._componentTypeToBit.get(componentType);\n if (bit === undefined) {\n bit = this._nextBit++;\n this._componentTypeToBit.set(componentType, bit);\n }\n bitmap |= (1 << bit);\n let entities = this._bitToEntities.get(1 << bit);\n if (!entities) {\n entities = new Set();\n this._bitToEntities.set(1 << bit, entities);\n }\n entities.add(entity);\n }\n this._entityToBitmap.set(entity, bitmap);\n this._lastUpdated = Date.now();\n }\n removeEntity(entity) {\n const bitmap = this._entityToBitmap.get(entity);\n if (bitmap === undefined)\n return;\n // 从所有相关的位集合中移除实体\n for (const [bitMask, entities] of this._bitToEntities) {\n if ((bitmap & bitMask) !== 0) {\n entities.delete(entity);\n if (entities.size === 0) {\n this._bitToEntities.delete(bitMask);\n }\n }\n }\n this._entityToBitmap.delete(entity);\n this._lastUpdated = Date.now();\n }\n query(componentType) {\n const startTime = performance.now();\n const bit = this._componentTypeToBit.get(componentType);\n if (bit === undefined) {\n this._queryCount++;\n this._totalQueryTime += performance.now() - startTime;\n return new Set();\n }\n const result = new Set(this._bitToEntities.get(1 << bit) || []);\n this._queryCount++;\n this._totalQueryTime += performance.now() - startTime;\n return result;\n }\n queryMultiple(componentTypes, operation) {\n const startTime = performance.now();\n if (componentTypes.length === 0) {\n return new Set();\n }\n let targetBitmap = 0;\n const validBits = [];\n for (const componentType of componentTypes) {\n const bit = this._componentTypeToBit.get(componentType);\n if (bit !== undefined) {\n targetBitmap |= (1 << bit);\n validBits.push(1 << bit);\n }\n }\n const result = new Set();\n if (operation === 'AND') {\n for (const [entity, entityBitmap] of this._entityToBitmap) {\n if ((entityBitmap & targetBitmap) === targetBitmap) {\n result.add(entity);\n }\n }\n }\n else {\n for (const bitMask of validBits) {\n const entities = this._bitToEntities.get(bitMask);\n if (entities) {\n for (const entity of entities) {\n result.add(entity);\n }\n }\n }\n }\n this._queryCount++;\n this._totalQueryTime += performance.now() - startTime;\n return result;\n }\n clear() {\n this._componentTypeToBit.clear();\n this._entityToBitmap.clear();\n this._bitToEntities.clear();\n this._nextBit = 0;\n this._lastUpdated = Date.now();\n }\n getStats() {\n let memoryUsage = 0;\n memoryUsage += this._componentTypeToBit.size * 12;\n memoryUsage += this._entityToBitmap.size * 12;\n memoryUsage += this._bitToEntities.size * 64;\n for (const entities of this._bitToEntities.values()) {\n memoryUsage += entities.size * 8;\n }\n return {\n type: this.type,\n size: this._componentTypeToBit.size,\n memoryUsage,\n queryCount: this._queryCount,\n avgQueryTime: this._queryCount > 0 ? this._totalQueryTime / this._queryCount : 0,\n lastUpdated: this._lastUpdated\n };\n }\n}\n/**\n * 智能组件索引管理器\n *\n * 根据使用模式自动选择最优的索引策略。\n * 支持动态切换索引类型以获得最佳性能。\n */\nexport class ComponentIndexManager {\n constructor(initialType = IndexType.HASH) {\n this._indexHistory = new Map();\n this._autoOptimize = true;\n this._optimizationThreshold = 1000;\n this._activeIndex = this.createIndex(initialType);\n }\n /**\n * 添加实体到索引\n */\n addEntity(entity) {\n this._activeIndex.addEntity(entity);\n this.checkOptimization();\n }\n /**\n * 从索引中移除实体\n */\n removeEntity(entity) {\n this._activeIndex.removeEntity(entity);\n }\n /**\n * 查询包含指定组件的实体\n */\n query(componentType) {\n return this._activeIndex.query(componentType);\n }\n /**\n * 批量查询多个组件\n */\n queryMultiple(componentTypes, operation) {\n return this._activeIndex.queryMultiple(componentTypes, operation);\n }\n /**\n * 手动切换索引类型\n */\n switchIndexType(type) {\n if (type === this._activeIndex.type)\n return;\n this._indexHistory.set(this._activeIndex.type, this._activeIndex.getStats());\n const oldIndex = this._activeIndex;\n this._activeIndex = this.createIndex(type);\n oldIndex.clear();\n }\n /**\n * 启用/禁用自动优化\n */\n setAutoOptimize(enabled) {\n this._autoOptimize = enabled;\n }\n /**\n * 获取当前索引统计信息\n */\n getStats() {\n return this._activeIndex.getStats();\n }\n /**\n * 获取所有索引类型的历史统计信息\n */\n getAllStats() {\n const current = this._activeIndex.getStats();\n return new Map([\n ...this._indexHistory,\n [current.type, current]\n ]);\n }\n /**\n * 清空索引\n */\n clear() {\n this._activeIndex.clear();\n }\n /**\n * 创建指定类型的索引\n */\n createIndex(type) {\n switch (type) {\n case IndexType.HASH:\n return new HashComponentIndex();\n case IndexType.BITMAP:\n return new BitmapComponentIndex();\n case IndexType.SORTED:\n return new HashComponentIndex();\n default:\n return new HashComponentIndex();\n }\n }\n /**\n * 检查是否需要优化索引\n */\n checkOptimization() {\n if (!this._autoOptimize)\n return;\n const stats = this._activeIndex.getStats();\n if (stats.queryCount < this._optimizationThreshold)\n return;\n if (stats.avgQueryTime > 1.0 && stats.type !== IndexType.HASH) {\n this.switchIndexType(IndexType.HASH);\n }\n else if (stats.memoryUsage > 10 * 1024 * 1024 && stats.type !== IndexType.BITMAP) {\n this.switchIndexType(IndexType.BITMAP);\n }\n }\n}\n//# sourceMappingURL=ComponentIndex.js.map","/**\n * 脏标记类型\n */\nexport var DirtyFlag;\n(function (DirtyFlag) {\n /** 组件数据已修改 */\n DirtyFlag[DirtyFlag[\"COMPONENT_MODIFIED\"] = 1] = \"COMPONENT_MODIFIED\";\n /** 组件已添加 */\n DirtyFlag[DirtyFlag[\"COMPONENT_ADDED\"] = 2] = \"COMPONENT_ADDED\";\n /** 组件已移除 */\n DirtyFlag[DirtyFlag[\"COMPONENT_REMOVED\"] = 4] = \"COMPONENT_REMOVED\";\n /** 实体位置已改变 */\n DirtyFlag[DirtyFlag[\"TRANSFORM_CHANGED\"] = 8] = \"TRANSFORM_CHANGED\";\n /** 实体状态已改变 */\n DirtyFlag[DirtyFlag[\"STATE_CHANGED\"] = 16] = \"STATE_CHANGED\";\n /** 自定义标记1 */\n DirtyFlag[DirtyFlag[\"CUSTOM_1\"] = 256] = \"CUSTOM_1\";\n /** 自定义标记2 */\n DirtyFlag[DirtyFlag[\"CUSTOM_2\"] = 512] = \"CUSTOM_2\";\n /** 自定义标记3 */\n DirtyFlag[DirtyFlag[\"CUSTOM_3\"] = 1024] = \"CUSTOM_3\";\n /** 所有标记 */\n DirtyFlag[DirtyFlag[\"ALL\"] = 4294967295] = \"ALL\";\n})(DirtyFlag || (DirtyFlag = {}));\n/**\n * 脏标记追踪系统\n *\n * 提供高效的组件和实体变更追踪,避免不必要的计算和更新。\n * 支持细粒度的脏标记和批量处理机制。\n *\n * @example\n * ```typescript\n * const dirtySystem = new DirtyTrackingSystem();\n *\n * // 标记实体的位置组件已修改\n * dirtySystem.markDirty(entity, DirtyFlag.TRANSFORM_CHANGED, [PositionComponent]);\n *\n * // 监听位置变化\n * dirtySystem.addListener({\n * flags: DirtyFlag.TRANSFORM_CHANGED,\n * callback: (data) => {\n * console.log('Entity position changed:', data.entity.name);\n * }\n * });\n *\n * // 处理所有脏标记\n * dirtySystem.processDirtyEntities();\n * ```\n */\nexport class DirtyTrackingSystem {\n constructor() {\n /** 脏实体映射表 */\n this._dirtyEntities = new Map();\n /** 脏标记监听器 */\n this._listeners = [];\n /** 性能统计 */\n this._stats = {\n totalMarkings: 0,\n totalCleanups: 0,\n frameCount: 0,\n totalDirtyPerFrame: 0\n };\n /** 当前帧编号 */\n this._currentFrame = 0;\n this._batchSize = 100;\n this._maxProcessingTime = 16;\n /** 延迟处理队列 */\n this._processingQueue = [];\n this._isProcessing = false;\n }\n /**\n * 标记实体为脏状态\n *\n * @param entity 要标记的实体\n * @param flags 脏标记位\n * @param modifiedComponents 修改的组件类型列表\n */\n markDirty(entity, flags, modifiedComponents = []) {\n this._stats.totalMarkings++;\n let dirtyData = this._dirtyEntities.get(entity);\n if (!dirtyData) {\n dirtyData = {\n entity,\n flags: 0,\n modifiedComponents: new Set(),\n timestamp: performance.now(),\n frameNumber: this._currentFrame\n };\n this._dirtyEntities.set(entity, dirtyData);\n }\n dirtyData.flags |= flags;\n dirtyData.timestamp = performance.now();\n dirtyData.frameNumber = this._currentFrame;\n for (const componentType of modifiedComponents) {\n dirtyData.modifiedComponents.add(componentType);\n }\n this.notifyListeners(dirtyData, flags);\n }\n /**\n * 检查实体是否有指定的脏标记\n *\n * @param entity 要检查的实体\n * @param flags 要检查的标记位\n * @returns 是否有指定的脏标记\n */\n isDirty(entity, flags = DirtyFlag.ALL) {\n const dirtyData = this._dirtyEntities.get(entity);\n return dirtyData ? (dirtyData.flags & flags) !== 0 : false;\n }\n /**\n * 清除实体的脏标记\n *\n * @param entity 要清除的实体\n * @param flags 要清除的标记位,默认清除所有\n */\n clearDirty(entity, flags = DirtyFlag.ALL) {\n const dirtyData = this._dirtyEntities.get(entity);\n if (!dirtyData)\n return;\n if (flags === DirtyFlag.ALL) {\n this._dirtyEntities.delete(entity);\n }\n else {\n dirtyData.flags &= ~flags;\n if (dirtyData.flags === 0) {\n this._dirtyEntities.delete(entity);\n }\n }\n this._stats.totalCleanups++;\n }\n /**\n * 获取所有脏实体\n *\n * @param flags 过滤标记位,只返回包含指定标记的实体\n * @returns 脏实体数据数组\n */\n getDirtyEntities(flags = DirtyFlag.ALL) {\n const result = [];\n for (const dirtyData of this._dirtyEntities.values()) {\n if ((dirtyData.flags & flags) !== 0) {\n result.push(dirtyData);\n }\n }\n return result;\n }\n /**\n * 批量处理脏实体\n *\n * 使用时间分片的方式处理脏实体,避免单帧卡顿\n */\n processDirtyEntities() {\n if (this._isProcessing)\n return;\n this._isProcessing = true;\n const startTime = performance.now();\n if (this._processingQueue.length === 0) {\n this._processingQueue.push(...this._dirtyEntities.values());\n }\n let processed = 0;\n while (this._processingQueue.length > 0 && processed < this._batchSize) {\n const elapsed = performance.now() - startTime;\n if (elapsed > this._maxProcessingTime) {\n break;\n }\n const dirtyData = this._processingQueue.shift();\n this.processEntity(dirtyData);\n processed++;\n }\n if (this._processingQueue.length === 0) {\n this._isProcessing = false;\n this.onFrameEnd();\n }\n }\n /**\n * 添加脏标记监听器\n *\n * @param listener 监听器配置\n */\n addListener(listener) {\n this._listeners.push(listener);\n this._listeners.sort((a, b) => (a.priority || 100) - (b.priority || 100));\n }\n /**\n * 移除脏标记监听器\n *\n * @param callback 要移除的回调函数\n */\n removeListener(callback) {\n const index = this._listeners.findIndex(l => l.callback === callback);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n /**\n * 开始新的帧\n */\n beginFrame() {\n this._currentFrame++;\n }\n /**\n * 结束当前帧\n */\n endFrame() {\n if (!this._isProcessing) {\n this.processDirtyEntities();\n }\n }\n /**\n * 获取统计信息\n */\n getStats() {\n return {\n dirtyEntityCount: this._dirtyEntities.size,\n totalMarkings: this._stats.totalMarkings,\n totalCleanups: this._stats.totalCleanups,\n listenerCount: this._listeners.length,\n avgDirtyPerFrame: this._stats.frameCount > 0 ?\n this._stats.totalDirtyPerFrame / this._stats.frameCount : 0,\n estimatedMemoryUsage: this.estimateMemoryUsage()\n };\n }\n /**\n * 清空所有脏标记和统计信息\n */\n clear() {\n this._dirtyEntities.clear();\n this._processingQueue.length = 0;\n this._isProcessing = false;\n this._stats = {\n totalMarkings: 0,\n totalCleanups: 0,\n frameCount: 0,\n totalDirtyPerFrame: 0\n };\n }\n /**\n * 配置批量处理参数\n *\n * @param batchSize 每次处理的最大实体数量\n * @param maxProcessingTime 每帧最大处理时间(毫秒)\n */\n configureBatchProcessing(batchSize, maxProcessingTime) {\n this._batchSize = batchSize;\n this._maxProcessingTime = maxProcessingTime;\n }\n /**\n * 处理单个脏实体\n */\n processEntity(dirtyData) {\n for (const listener of this._listeners) {\n if ((dirtyData.flags & listener.flags) !== 0) {\n try {\n listener.callback(dirtyData);\n }\n catch (error) {\n console.error('脏数据监听器错误:', error);\n }\n }\n }\n this.clearDirty(dirtyData.entity);\n }\n /**\n * 通知监听器\n */\n notifyListeners(dirtyData, newFlags) {\n for (const listener of this._listeners) {\n if ((newFlags & listener.flags) !== 0) {\n try {\n listener.callback(dirtyData);\n }\n catch (error) {\n console.error('脏数据监听器通知错误:', error);\n }\n }\n }\n }\n /**\n * 帧结束时的统计更新\n */\n onFrameEnd() {\n this._stats.frameCount++;\n this._stats.totalDirtyPerFrame += this._dirtyEntities.size;\n }\n /**\n * 估算内存使用量\n */\n estimateMemoryUsage() {\n let usage = 0;\n usage += this._dirtyEntities.size * 100;\n usage += this._listeners.length * 50;\n usage += this._processingQueue.length * 8;\n return usage;\n }\n}\n//# sourceMappingURL=DirtyTrackingSystem.js.map","import { ComponentRegistry } from './ComponentStorage';\nimport { ComponentPoolManager } from './ComponentPool';\nimport { BitMaskOptimizer } from './BitMaskOptimizer';\nimport { IndexUpdateBatcher } from './IndexUpdateBatcher';\nimport { ComponentIndexManager, IndexType } from './ComponentIndex';\nimport { ArchetypeSystem } from './ArchetypeSystem';\nimport { DirtyTrackingSystem, DirtyFlag } from './DirtyTrackingSystem';\n/**\n * 查询条件类型\n */\nexport var QueryConditionType;\n(function (QueryConditionType) {\n /** 必须包含所有指定组件 */\n QueryConditionType[\"ALL\"] = \"all\";\n /** 必须包含任意一个指定组件 */\n QueryConditionType[\"ANY\"] = \"any\";\n /** 不能包含任何指定组件 */\n QueryConditionType[\"NONE\"] = \"none\";\n})(QueryConditionType || (QueryConditionType = {}));\n/**\n * 高性能实体查询系统\n *\n * 提供快速的实体查询功能,支持按组件类型、标签、名称等多种方式查询实体。\n * 系统采用多级索引和智能缓存机制,确保在大量实体场景下的查询性能。\n *\n * 主要特性:\n * - 支持单组件和多组件查询\n * - 自动索引管理和缓存优化\n * - WebAssembly计算加速(如果可用)\n * - 详细的性能统计信息\n *\n * @example\n * ```typescript\n * // 查询所有包含Position和Velocity组件的实体\n * const movingEntities = querySystem.queryAll(PositionComponent, VelocityComponent);\n *\n * // 查询特定标签的实体\n * const playerEntities = querySystem.queryByTag(PLAYER_TAG);\n * ```\n */\nexport class QuerySystem {\n constructor() {\n this.entities = [];\n this.indexDirty = true;\n // 查询缓存系统\n this.queryCache = new Map();\n this.cacheMaxSize = 1000;\n this.cacheTimeout = 5000; // 5秒缓存过期\n // 性能统计\n this.queryStats = {\n totalQueries: 0,\n cacheHits: 0,\n indexHits: 0,\n linearScans: 0,\n archetypeHits: 0,\n dirtyChecks: 0\n };\n this.entityIndex = {\n byMask: new Map(),\n byComponentType: new Map(),\n byTag: new Map(),\n byName: new Map()\n };\n // 初始化优化组件\n this.componentPoolManager = ComponentPoolManager.getInstance();\n this.bitMaskOptimizer = BitMaskOptimizer.getInstance();\n this.indexUpdateBatcher = new IndexUpdateBatcher();\n // 初始化新的性能优化系统\n this.componentIndexManager = new ComponentIndexManager(IndexType.HASH);\n this.archetypeSystem = new ArchetypeSystem();\n this.dirtyTrackingSystem = new DirtyTrackingSystem();\n // 设置索引更新批处理器的回调\n this.indexUpdateBatcher.onBatchAdd = (entities) => {\n for (const entity of entities) {\n this.addEntityToIndexes(entity);\n }\n };\n this.indexUpdateBatcher.onBatchRemove = (entities) => {\n for (const entity of entities) {\n this.removeEntityFromIndexes(entity);\n }\n };\n this.indexUpdateBatcher.onBatchUpdate = (updates) => {\n for (const update of updates) {\n this.removeEntityFromIndexes(update.entity);\n this.addEntityToIndexes(update.entity);\n }\n };\n }\n /**\n * 设置实体列表并重建索引\n *\n * 当实体集合发生大规模变化时调用此方法。\n * 系统将重新构建所有索引以确保查询性能。\n *\n * @param entities 新的实体列表\n */\n setEntities(entities) {\n this.entities = entities;\n this.clearQueryCache();\n this.rebuildIndexes();\n }\n /**\n * 添加单个实体到查询系统\n *\n * 将新实体添加到查询系统中,并自动更新相关索引。\n * 为了提高批量添加性能,可以延迟缓存清理。\n *\n * @param entity 要添加的实体\n * @param deferCacheClear 是否延迟缓存清理(用于批量操作)\n */\n addEntity(entity, deferCacheClear = false) {\n if (!this.entities.includes(entity)) {\n this.entities.push(entity);\n this.addEntityToIndexes(entity);\n this.componentIndexManager.addEntity(entity);\n this.archetypeSystem.addEntity(entity);\n this.dirtyTrackingSystem.markDirty(entity, DirtyFlag.COMPONENT_ADDED);\n // 只有在非延迟模式下才立即清理缓存\n if (!deferCacheClear) {\n this.clearQueryCache();\n }\n }\n }\n /**\n * 批量添加实体\n *\n * 高效地批量添加多个实体,减少缓存清理次数。\n * 使用Set来避免O(n)的重复检查。\n *\n * @param entities 要添加的实体列表\n */\n addEntities(entities) {\n if (entities.length === 0)\n return;\n // 使用Set来快速检查重复\n const existingIds = new Set(this.entities.map(e => e.id));\n let addedCount = 0;\n for (const entity of entities) {\n if (!existingIds.has(entity.id)) {\n this.entities.push(entity);\n this.addEntityToIndexes(entity);\n existingIds.add(entity.id);\n addedCount++;\n }\n }\n // 只在有实体被添加时才清理缓存\n if (addedCount > 0) {\n this.clearQueryCache();\n }\n }\n /**\n * 批量添加实体(无重复检查版本)\n *\n * 假设所有实体都是新的,跳过重复检查以获得最大性能。\n * 仅在确保没有重复实体时使用。\n *\n * @param entities 要添加的实体列表\n */\n addEntitiesUnchecked(entities) {\n if (entities.length === 0)\n return;\n // 避免调用栈溢出,分批添加\n for (const entity of entities) {\n this.entities.push(entity);\n }\n // 批量更新索引\n for (const entity of entities) {\n this.addEntityToIndexes(entity);\n }\n // 清理缓存\n this.clearQueryCache();\n }\n /**\n * 从查询系统移除实体\n *\n * 从查询系统中移除指定实体,并清理相关索引。\n *\n * @param entity 要移除的实体\n */\n removeEntity(entity) {\n const index = this.entities.indexOf(entity);\n if (index !== -1) {\n this.entities.splice(index, 1);\n this.removeEntityFromIndexes(entity);\n this.componentIndexManager.removeEntity(entity);\n this.archetypeSystem.removeEntity(entity);\n this.dirtyTrackingSystem.markDirty(entity, DirtyFlag.COMPONENT_REMOVED);\n this.clearQueryCache();\n }\n }\n /**\n * 将实体添加到各种索引中(优化版本)\n */\n addEntityToIndexes(entity) {\n const mask = entity.componentMask;\n // 组件掩码索引 - 优化Map操作\n let maskSet = this.entityIndex.byMask.get(mask);\n if (!maskSet) {\n maskSet = new Set();\n this.entityIndex.byMask.set(mask, maskSet);\n }\n maskSet.add(entity);\n // 组件类型索引 - 批量处理\n const components = entity.components;\n for (let i = 0; i < components.length; i++) {\n const componentType = components[i].constructor;\n let typeSet = this.entityIndex.byComponentType.get(componentType);\n if (!typeSet) {\n typeSet = new Set();\n this.entityIndex.byComponentType.set(componentType, typeSet);\n }\n typeSet.add(entity);\n }\n // 标签索引 - 只在有标签时处理\n const tag = entity.tag;\n if (tag !== undefined) {\n let tagSet = this.entityIndex.byTag.get(tag);\n if (!tagSet) {\n tagSet = new Set();\n this.entityIndex.byTag.set(tag, tagSet);\n }\n tagSet.add(entity);\n }\n // 名称索引 - 只在有名称时处理\n const name = entity.name;\n if (name) {\n let nameSet = this.entityIndex.byName.get(name);\n if (!nameSet) {\n nameSet = new Set();\n this.entityIndex.byName.set(name, nameSet);\n }\n nameSet.add(entity);\n }\n }\n /**\n * 从各种索引中移除实体\n */\n removeEntityFromIndexes(entity) {\n const mask = entity.componentMask;\n // 从组件掩码索引移除\n const maskSet = this.entityIndex.byMask.get(mask);\n if (maskSet) {\n maskSet.delete(entity);\n if (maskSet.size === 0) {\n this.entityIndex.byMask.delete(mask);\n }\n }\n // 从组件类型索引移除\n for (const component of entity.components) {\n const componentType = component.constructor;\n const typeSet = this.entityIndex.byComponentType.get(componentType);\n if (typeSet) {\n typeSet.delete(entity);\n if (typeSet.size === 0) {\n