修复循环依赖问题

This commit is contained in:
YHH
2025-09-24 10:20:36 +08:00
parent 168e028098
commit 0b4244fd8e
7 changed files with 52 additions and 112 deletions

41
package-lock.json generated
View File

@@ -529,43 +529,6 @@
"@babel/core": "^7.0.0" "@babel/core": "^7.0.0"
} }
}, },
"node_modules/@babel/plugin-proposal-nullish-coalescing-operator": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz",
"integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==",
"deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.18.6",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-proposal-optional-chaining": {
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz",
"integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==",
"deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
"@babel/plugin-syntax-optional-chaining": "^7.8.3"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-proposal-private-property-in-object": { "node_modules/@babel/plugin-proposal-private-property-in-object": {
"version": "7.21.0-placeholder-for-preset-env.2", "version": "7.21.0-placeholder-for-preset-env.2",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
@@ -13079,12 +13042,10 @@
}, },
"packages/core": { "packages/core": {
"name": "@esengine/ecs-framework", "name": "@esengine/ecs-framework",
"version": "2.1.45", "version": "2.1.47",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.28.3", "@babel/core": "^7.28.3",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
"@babel/plugin-transform-optional-chaining": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1",
"@babel/preset-env": "^7.28.3", "@babel/preset-env": "^7.28.3",

View File

@@ -1,7 +1,7 @@
import { IComponentDebugData } from '../../Types'; import { IComponentDebugData } from '../../Types';
import { Core } from '../../Core';
import { ComponentPoolManager } from '../../ECS/Core/ComponentPool'; import { ComponentPoolManager } from '../../ECS/Core/ComponentPool';
import { getComponentInstanceTypeName } from '../../ECS/Decorators'; import { getComponentInstanceTypeName } from '../../ECS/Decorators';
import { IScene } from '../../ECS/IScene';
/** /**
* 组件数据收集器 * 组件数据收集器
@@ -12,8 +12,7 @@ export class ComponentDataCollector {
/** /**
* 收集组件数据(轻量版,不计算实际内存大小) * 收集组件数据(轻量版,不计算实际内存大小)
*/ */
public collectComponentData(): IComponentDebugData { public collectComponentData(scene?: IScene | null): IComponentDebugData {
const scene = Core.scene;
if (!scene) { if (!scene) {
return { return {
componentTypes: 0, componentTypes: 0,
@@ -73,7 +72,7 @@ export class ComponentDataCollector {
const poolSize = poolSizes.get(typeName) || 0; const poolSize = poolSizes.get(typeName) || 0;
const poolUtilization = poolUtilizations.get(typeName) || 0; const poolUtilization = poolUtilizations.get(typeName) || 0;
// 使用预估的基础内存大小,避免每帧计算 // 使用预估的基础内存大小,避免每帧计算
const memoryPerInstance = this.getEstimatedComponentSize(typeName); const memoryPerInstance = this.getEstimatedComponentSize(typeName, scene);
return { return {
typeName, typeName,
@@ -91,12 +90,11 @@ export class ComponentDataCollector {
/** /**
* 获取组件类型的估算内存大小(基于预设值,不进行实际计算) * 获取组件类型的估算内存大小(基于预设值,不进行实际计算)
*/ */
private getEstimatedComponentSize(typeName: string): number { private getEstimatedComponentSize(typeName: string, scene?: IScene | null): number {
if (ComponentDataCollector.componentSizeCache.has(typeName)) { if (ComponentDataCollector.componentSizeCache.has(typeName)) {
return ComponentDataCollector.componentSizeCache.get(typeName)!; return ComponentDataCollector.componentSizeCache.get(typeName)!;
} }
const scene = Core.scene;
if (!scene) return 64; if (!scene) return 64;
const entityList = (scene as any).entities; const entityList = (scene as any).entities;
@@ -170,12 +168,11 @@ export class ComponentDataCollector {
* 为内存快照功能提供的详细内存计算 * 为内存快照功能提供的详细内存计算
* 只在用户主动请求内存快照时调用 * 只在用户主动请求内存快照时调用
*/ */
public calculateDetailedComponentMemory(typeName: string): number { public calculateDetailedComponentMemory(typeName: string, scene?: IScene | null): number {
const scene = Core.scene; if (!scene) return this.getEstimatedComponentSize(typeName, scene);
if (!scene) return this.getEstimatedComponentSize(typeName);
const entityList = (scene as any).entities; const entityList = (scene as any).entities;
if (!entityList?.buffer) return this.getEstimatedComponentSize(typeName); if (!entityList?.buffer) return this.getEstimatedComponentSize(typeName, scene);
try { try {
// 找到第一个包含此组件的实体,分析组件大小 // 找到第一个包含此组件的实体,分析组件大小
@@ -191,7 +188,7 @@ export class ComponentDataCollector {
// 忽略错误,使用估算值 // 忽略错误,使用估算值
} }
return this.getEstimatedComponentSize(typeName); return this.getEstimatedComponentSize(typeName, scene);
} }
/** /**

View File

@@ -5,7 +5,6 @@ import { PerformanceDataCollector } from './PerformanceDataCollector';
import { ComponentDataCollector } from './ComponentDataCollector'; import { ComponentDataCollector } from './ComponentDataCollector';
import { SceneDataCollector } from './SceneDataCollector'; import { SceneDataCollector } from './SceneDataCollector';
import { WebSocketManager } from './WebSocketManager'; import { WebSocketManager } from './WebSocketManager';
import { Core } from '../../Core';
import { Component } from '../../ECS/Component'; import { Component } from '../../ECS/Component';
import { ComponentPoolManager } from '../../ECS/Core/ComponentPool'; import { ComponentPoolManager } from '../../ECS/Core/ComponentPool';
import { Pool } from '../../Utils/Pool'; import { Pool } from '../../Utils/Pool';
@@ -24,15 +23,21 @@ export class DebugManager {
private performanceCollector: PerformanceDataCollector; private performanceCollector: PerformanceDataCollector;
private componentCollector: ComponentDataCollector; private componentCollector: ComponentDataCollector;
private sceneCollector: SceneDataCollector; private sceneCollector: SceneDataCollector;
private sceneProvider: () => any;
private performanceMonitorProvider: () => any;
private frameCounter: number = 0; private frameCounter: number = 0;
private lastSendTime: number = 0; private lastSendTime: number = 0;
private sendInterval: number; private sendInterval: number;
private isRunning: boolean = false; private isRunning: boolean = false;
constructor(core: Core, config: IECSDebugConfig) { constructor(core: any, config: IECSDebugConfig) {
this.config = config; this.config = config;
// 设置提供器函数
this.sceneProvider = () => (core as any).scene || (core.constructor as any).scene;
this.performanceMonitorProvider = () => core._performanceMonitor;
// 初始化数据收集器 // 初始化数据收集器
this.entityCollector = new EntityDataCollector(); this.entityCollector = new EntityDataCollector();
this.systemCollector = new SystemDataCollector(); this.systemCollector = new SystemDataCollector();
@@ -326,12 +331,12 @@ export class DebugManager {
private captureMemorySnapshot(): any { private captureMemorySnapshot(): any {
const timestamp = Date.now(); const timestamp = Date.now();
// 使用专门的内存计算方法收集实体数据
const entityData = this.entityCollector.collectEntityDataWithMemory();
// 收集其他内存统计 // 收集其他内存统计
const baseMemoryInfo = this.collectBaseMemoryInfo(); const baseMemoryInfo = this.collectBaseMemoryInfo();
const scene = Core.scene; const scene = this.sceneProvider();
// 使用专门的内存计算方法收集实体数据
const entityData = this.entityCollector.collectEntityDataWithMemory(scene);
const componentMemoryStats = scene?.entities ? this.collectComponentMemoryStats(scene.entities) : { totalMemory: 0, componentTypes: 0, totalInstances: 0, breakdown: [] }; const componentMemoryStats = scene?.entities ? this.collectComponentMemoryStats(scene.entities) : { totalMemory: 0, componentTypes: 0, totalInstances: 0, breakdown: [] };
const systemMemoryStats = this.collectSystemMemoryStats(); const systemMemoryStats = this.collectSystemMemoryStats();
const poolMemoryStats = this.collectPoolMemoryStats(); const poolMemoryStats = this.collectPoolMemoryStats();
@@ -536,7 +541,7 @@ export class DebugManager {
updateOrder: number; updateOrder: number;
}>; }>;
} { } {
const scene = Core.scene; const scene = this.sceneProvider();
let totalSystemMemory = 0; let totalSystemMemory = 0;
const systemBreakdown: Array<{ const systemBreakdown: Array<{
name: string; name: string;
@@ -710,8 +715,7 @@ export class DebugManager {
error?: string; error?: string;
} { } {
try { try {
const coreInstance = Core.Instance as Core & { _performanceMonitor?: unknown }; const performanceMonitor = this.performanceMonitorProvider();
const performanceMonitor = coreInstance._performanceMonitor;
if (!performanceMonitor) { if (!performanceMonitor) {
return { enabled: false }; return { enabled: false };
} }
@@ -744,7 +748,7 @@ export class DebugManager {
*/ */
public getDebugData(): IECSDebugData { public getDebugData(): IECSDebugData {
const currentTime = Date.now(); const currentTime = Date.now();
const scene = Core.scene; const scene = this.sceneProvider();
const debugData: IECSDebugData = { const debugData: IECSDebugData = {
timestamp: currentTime, timestamp: currentTime,
@@ -756,27 +760,25 @@ export class DebugManager {
// 根据配置收集各种数据 // 根据配置收集各种数据
if (this.config.channels.entities) { if (this.config.channels.entities) {
debugData.entities = this.entityCollector.collectEntityData(); debugData.entities = this.entityCollector.collectEntityData(scene);
} }
if (this.config.channels.systems) { if (this.config.channels.systems) {
const coreInstance = Core.Instance as Core & { _performanceMonitor?: unknown }; const performanceMonitor = this.performanceMonitorProvider();
const performanceMonitor = coreInstance._performanceMonitor; debugData.systems = this.systemCollector.collectSystemData(performanceMonitor, scene);
debugData.systems = this.systemCollector.collectSystemData(performanceMonitor);
} }
if (this.config.channels.performance) { if (this.config.channels.performance) {
const coreInstance = Core.Instance as Core & { _performanceMonitor?: unknown }; const performanceMonitor = this.performanceMonitorProvider();
const performanceMonitor = coreInstance._performanceMonitor;
debugData.performance = this.performanceCollector.collectPerformanceData(performanceMonitor); debugData.performance = this.performanceCollector.collectPerformanceData(performanceMonitor);
} }
if (this.config.channels.components) { if (this.config.channels.components) {
debugData.components = this.componentCollector.collectComponentData(); debugData.components = this.componentCollector.collectComponentData(scene);
} }
if (this.config.channels.scenes) { if (this.config.channels.scenes) {
debugData.scenes = this.sceneCollector.collectSceneData(); debugData.scenes = this.sceneCollector.collectSceneData(scene);
} }
return debugData; return debugData;

View File

@@ -1,16 +1,15 @@
import { IEntityDebugData } from '../../Types'; import { IEntityDebugData } from '../../Types';
import { Core } from '../../Core';
import { Entity } from '../../ECS/Entity'; import { Entity } from '../../ECS/Entity';
import { Component } from '../../ECS/Component'; import { Component } from '../../ECS/Component';
import { ComponentTypeManager } from '../../ECS/Utils/ComponentTypeManager'; import { ComponentTypeManager } from '../../ECS/Utils/ComponentTypeManager';
import { getComponentInstanceTypeName, getSystemInstanceTypeName } from '../../ECS/Decorators'; import { getComponentInstanceTypeName, getSystemInstanceTypeName } from '../../ECS/Decorators';
import { IScene } from '../../ECS/IScene';
/** /**
* 实体数据收集器 * 实体数据收集器
*/ */
export class EntityDataCollector { export class EntityDataCollector {
public collectEntityData(): IEntityDebugData { public collectEntityData(scene?: IScene | null): IEntityDebugData {
const scene = Core.scene;
if (!scene) { if (!scene) {
return this.getEmptyEntityDebugData(); return this.getEmptyEntityDebugData();
} }
@@ -51,7 +50,7 @@ export class EntityDataCollector {
} }
public getRawEntityList(): Array<{ public getRawEntityList(scene?: IScene | null): Array<{
id: number; id: number;
name: string; name: string;
active: boolean; active: boolean;
@@ -65,7 +64,6 @@ export class EntityDataCollector {
tag: number; tag: number;
updateOrder: number; updateOrder: number;
}> { }> {
const scene = Core.scene;
if (!scene) return []; if (!scene) return [];
const entityList = (scene as any).entities; const entityList = (scene as any).entities;
@@ -88,9 +86,8 @@ export class EntityDataCollector {
} }
public getEntityDetails(entityId: number): any { public getEntityDetails(entityId: number, scene?: IScene | null): any {
try { try {
const scene = Core.scene;
if (!scene) return null; if (!scene) return null;
const entityList = (scene as any).entities; const entityList = (scene as any).entities;
@@ -101,7 +98,7 @@ export class EntityDataCollector {
const baseDebugInfo = entity.getDebugInfo ? const baseDebugInfo = entity.getDebugInfo ?
entity.getDebugInfo() : entity.getDebugInfo() :
this.buildFallbackEntityInfo(entity); this.buildFallbackEntityInfo(entity, scene);
const componentDetails = this.extractComponentDetails(entity.components); const componentDetails = this.extractComponentDetails(entity.components);
@@ -155,8 +152,7 @@ export class EntityDataCollector {
} }
public collectEntityDataWithMemory(): IEntityDebugData { public collectEntityDataWithMemory(scene?: IScene | null): IEntityDebugData {
const scene = Core.scene;
if (!scene) { if (!scene) {
return this.getEmptyEntityDebugData(); return this.getEmptyEntityDebugData();
} }
@@ -192,7 +188,7 @@ export class EntityDataCollector {
entitiesPerArchetype: archetypeData.distribution, entitiesPerArchetype: archetypeData.distribution,
topEntitiesByComponents: archetypeData.topEntities, topEntitiesByComponents: archetypeData.topEntities,
entityHierarchy: this.buildEntityHierarchyTree(entityList), entityHierarchy: this.buildEntityHierarchyTree(entityList),
entityDetailsMap: this.buildEntityDetailsMap(entityList) entityDetailsMap: this.buildEntityDetailsMap(entityList, scene)
}; };
} }
@@ -635,7 +631,7 @@ export class EntityDataCollector {
/** /**
* 构建实体详情映射 * 构建实体详情映射
*/ */
private buildEntityDetailsMap(entityList: { buffer?: Entity[] }): Record<number, any> { private buildEntityDetailsMap(entityList: { buffer?: Entity[] }, scene?: IScene | null): Record<number, any> {
if (!entityList?.buffer) return {}; if (!entityList?.buffer) return {};
const entityDetailsMap: Record<number, any> = {}; const entityDetailsMap: Record<number, any> = {};
@@ -648,7 +644,7 @@ export class EntityDataCollector {
batch.forEach((entity: Entity) => { batch.forEach((entity: Entity) => {
const baseDebugInfo = entity.getDebugInfo ? const baseDebugInfo = entity.getDebugInfo ?
entity.getDebugInfo() : entity.getDebugInfo() :
this.buildFallbackEntityInfo(entity); this.buildFallbackEntityInfo(entity, scene);
const componentCacheStats = (entity as any).getComponentCacheStats ? const componentCacheStats = (entity as any).getComponentCacheStats ?
(entity as any).getComponentCacheStats() : null; (entity as any).getComponentCacheStats() : null;
@@ -676,8 +672,7 @@ export class EntityDataCollector {
/** /**
* 构建实体基础信息 * 构建实体基础信息
*/ */
private buildFallbackEntityInfo(entity: Entity): any { private buildFallbackEntityInfo(entity: Entity, scene?: IScene | null): any {
const scene = Core.scene;
const sceneInfo = this.getSceneInfo(scene); const sceneInfo = this.getSceneInfo(scene);
return { return {
@@ -757,9 +752,8 @@ export class EntityDataCollector {
/** /**
* 获取组件的完整属性信息(仅在需要时调用) * 获取组件的完整属性信息(仅在需要时调用)
*/ */
public getComponentProperties(entityId: number, componentIndex: number): Record<string, any> { public getComponentProperties(entityId: number, componentIndex: number, scene?: IScene | null): Record<string, any> {
try { try {
const scene = Core.scene;
if (!scene) return {}; if (!scene) return {};
const entityList = (scene as any).entities; const entityList = (scene as any).entities;
@@ -950,9 +944,8 @@ export class EntityDataCollector {
/** /**
* 展开懒加载对象(供调试面板调用) * 展开懒加载对象(供调试面板调用)
*/ */
public expandLazyObject(entityId: number, componentIndex: number, propertyPath: string): any { public expandLazyObject(entityId: number, componentIndex: number, propertyPath: string, scene?: IScene | null): any {
try { try {
const scene = Core.scene;
if (!scene) return null; if (!scene) return null;
const entityList = (scene as any).entities; const entityList = (scene as any).entities;

View File

@@ -1,6 +1,5 @@
import { IPerformanceDebugData } from '../../Types'; import { IPerformanceDebugData } from '../../Types';
import { Time } from '../Time'; import { Time } from '../Time';
import { Core } from '../../Core';
/** /**
* 性能数据收集器 * 性能数据收集器
@@ -63,17 +62,7 @@ export class PerformanceDataCollector {
private getECSPerformanceData(performanceMonitor: any): { totalExecutionTime: number; systemBreakdown: Array<any> } { private getECSPerformanceData(performanceMonitor: any): { totalExecutionTime: number; systemBreakdown: Array<any> } {
// 检查性能监视器是否存在 // 检查性能监视器是否存在
if (!performanceMonitor) { if (!performanceMonitor) {
// 尝试从Core实例获取性能监视器 return { totalExecutionTime: 0, systemBreakdown: [] };
try {
const coreInstance = Core.Instance;
if (coreInstance && (coreInstance as any)._performanceMonitor) {
performanceMonitor = (coreInstance as any)._performanceMonitor;
} else {
return { totalExecutionTime: 0, systemBreakdown: [] };
}
} catch (error) {
return { totalExecutionTime: 0, systemBreakdown: [] };
}
} }
if (!performanceMonitor.enabled) { if (!performanceMonitor.enabled) {

View File

@@ -1,5 +1,5 @@
import { ISceneDebugData } from '../../Types'; import { ISceneDebugData } from '../../Types';
import { Core } from '../../Core'; import { IScene } from '../../ECS/IScene';
/** /**
* 场景数据收集器 * 场景数据收集器
@@ -10,8 +10,7 @@ export class SceneDataCollector {
/** /**
* 收集场景数据 * 收集场景数据
*/ */
public collectSceneData(): ISceneDebugData { public collectSceneData(scene?: IScene | null): ISceneDebugData {
const scene = Core.scene;
if (!scene) { if (!scene) {
return { return {
currentSceneName: 'No Scene', currentSceneName: 'No Scene',

View File

@@ -1,6 +1,6 @@
import { ISystemDebugData } from '../../Types'; import { ISystemDebugData } from '../../Types';
import { Core } from '../../Core';
import { getSystemInstanceTypeName } from '../../ECS/Decorators'; import { getSystemInstanceTypeName } from '../../ECS/Decorators';
import { IScene } from '../../ECS/IScene';
/** /**
* 系统数据收集器 * 系统数据收集器
@@ -9,8 +9,7 @@ export class SystemDataCollector {
/** /**
* 收集系统数据 * 收集系统数据
*/ */
public collectSystemData(performanceMonitor: any): ISystemDebugData { public collectSystemData(performanceMonitor: any, scene?: IScene | null): ISystemDebugData {
const scene = Core.scene;
if (!scene) { if (!scene) {
return { return {
totalSystems: 0, totalSystems: 0,