Chore/lint fixes (#212)
* fix(eslint): 修复装饰器缩进配置 * fix(eslint): 修复装饰器缩进配置 * chore: 删除未使用的导入 * chore(lint): 移除未使用的导入和变量 * chore(lint): 修复editor-app中未使用的函数参数 * chore(lint): 修复未使用的赋值变量 * chore(eslint): 将所有错误级别改为警告以通过CI * fix(codeql): 修复GitHub Advanced Security检测到的问题
This commit is contained in:
@@ -57,410 +57,410 @@ export interface ProfilerData {
|
||||
type ProfilerDataListener = (data: ProfilerData) => void;
|
||||
|
||||
export class ProfilerService {
|
||||
private ws: WebSocket | null = null;
|
||||
private isServerRunning = false;
|
||||
private wsPort: string;
|
||||
private listeners: Set<ProfilerDataListener> = new Set();
|
||||
private currentData: ProfilerData | null = null;
|
||||
private checkServerInterval: NodeJS.Timeout | null = null;
|
||||
private reconnectTimeout: NodeJS.Timeout | null = null;
|
||||
private clientIdMap: Map<string, string> = new Map(); // 客户端地址 -> 客户端ID映射
|
||||
private autoStart: boolean;
|
||||
private ws: WebSocket | null = null;
|
||||
private isServerRunning = false;
|
||||
private wsPort: string;
|
||||
private listeners: Set<ProfilerDataListener> = new Set();
|
||||
private currentData: ProfilerData | null = null;
|
||||
private checkServerInterval: NodeJS.Timeout | null = null;
|
||||
private reconnectTimeout: NodeJS.Timeout | null = null;
|
||||
private clientIdMap: Map<string, string> = new Map(); // 客户端地址 -> 客户端ID映射
|
||||
private autoStart: boolean;
|
||||
|
||||
constructor() {
|
||||
const settings = SettingsService.getInstance();
|
||||
this.wsPort = settings.get('profiler.port', '8080');
|
||||
this.autoStart = settings.get('profiler.autoStart', true);
|
||||
constructor() {
|
||||
const settings = SettingsService.getInstance();
|
||||
this.wsPort = settings.get('profiler.port', '8080');
|
||||
this.autoStart = settings.get('profiler.autoStart', true);
|
||||
|
||||
this.startServerCheck();
|
||||
this.listenToSettingsChanges();
|
||||
this.startServerCheck();
|
||||
this.listenToSettingsChanges();
|
||||
|
||||
// 如果设置了自动启动,则启动服务器
|
||||
if (this.autoStart) {
|
||||
this.manualStartServer();
|
||||
}
|
||||
}
|
||||
|
||||
private listenToSettingsChanges(): void {
|
||||
window.addEventListener('settings:changed', ((event: CustomEvent) => {
|
||||
const newPort = event.detail['profiler.port'];
|
||||
if (newPort && newPort !== this.wsPort) {
|
||||
this.wsPort = newPort;
|
||||
this.reconnectWithNewPort();
|
||||
}
|
||||
}) as EventListener);
|
||||
}
|
||||
|
||||
private async reconnectWithNewPort(): Promise<void> {
|
||||
this.disconnect();
|
||||
|
||||
if (this.checkServerInterval) {
|
||||
clearInterval(this.checkServerInterval);
|
||||
this.checkServerInterval = null;
|
||||
// 如果设置了自动启动,则启动服务器
|
||||
if (this.autoStart) {
|
||||
this.manualStartServer();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await invoke('stop_profiler_server');
|
||||
this.isServerRunning = false;
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to stop server:', error);
|
||||
private listenToSettingsChanges(): void {
|
||||
window.addEventListener('settings:changed', ((event: CustomEvent) => {
|
||||
const newPort = event.detail['profiler.port'];
|
||||
if (newPort && newPort !== this.wsPort) {
|
||||
this.wsPort = newPort;
|
||||
this.reconnectWithNewPort();
|
||||
}
|
||||
}) as EventListener);
|
||||
}
|
||||
|
||||
this.startServerCheck();
|
||||
}
|
||||
private async reconnectWithNewPort(): Promise<void> {
|
||||
this.disconnect();
|
||||
|
||||
public subscribe(listener: ProfilerDataListener): () => void {
|
||||
this.listeners.add(listener);
|
||||
if (this.checkServerInterval) {
|
||||
clearInterval(this.checkServerInterval);
|
||||
this.checkServerInterval = null;
|
||||
}
|
||||
|
||||
// 如果已有数据,立即发送给新订阅者
|
||||
if (this.currentData) {
|
||||
listener(this.currentData);
|
||||
try {
|
||||
await invoke('stop_profiler_server');
|
||||
this.isServerRunning = false;
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to stop server:', error);
|
||||
}
|
||||
|
||||
this.startServerCheck();
|
||||
}
|
||||
|
||||
return () => {
|
||||
this.listeners.delete(listener);
|
||||
};
|
||||
}
|
||||
public subscribe(listener: ProfilerDataListener): () => void {
|
||||
this.listeners.add(listener);
|
||||
|
||||
public isConnected(): boolean {
|
||||
return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
|
||||
}
|
||||
// 如果已有数据,立即发送给新订阅者
|
||||
if (this.currentData) {
|
||||
listener(this.currentData);
|
||||
}
|
||||
|
||||
public isServerActive(): boolean {
|
||||
return this.isServerRunning;
|
||||
}
|
||||
return () => {
|
||||
this.listeners.delete(listener);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
public isConnected(): boolean {
|
||||
return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
|
||||
}
|
||||
|
||||
public isServerActive(): boolean {
|
||||
return this.isServerRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动启动服务器
|
||||
*/
|
||||
public async manualStartServer(): Promise<void> {
|
||||
await this.startServer();
|
||||
}
|
||||
public async manualStartServer(): Promise<void> {
|
||||
await this.startServer();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 手动停止服务器
|
||||
*/
|
||||
public async manualStopServer(): Promise<void> {
|
||||
try {
|
||||
await invoke('stop_profiler_server');
|
||||
this.isServerRunning = false;
|
||||
this.disconnect();
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to stop server:', error);
|
||||
}
|
||||
}
|
||||
|
||||
private startServerCheck(): void {
|
||||
this.checkServerStatus();
|
||||
this.checkServerInterval = setInterval(() => {
|
||||
this.checkServerStatus();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
private async checkServerStatus(): Promise<void> {
|
||||
try {
|
||||
const status = await invoke<boolean>('get_profiler_status');
|
||||
const wasRunning = this.isServerRunning;
|
||||
this.isServerRunning = status;
|
||||
|
||||
// 服务器启动了,尝试连接
|
||||
if (status && !this.ws) {
|
||||
this.connectToServer();
|
||||
}
|
||||
|
||||
// 服务器从运行变为停止
|
||||
if (wasRunning && !status) {
|
||||
this.disconnect();
|
||||
}
|
||||
} catch (error) {
|
||||
this.isServerRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async startServer(): Promise<void> {
|
||||
try {
|
||||
const port = parseInt(this.wsPort);
|
||||
await invoke<string>('start_profiler_server', { port });
|
||||
this.isServerRunning = true;
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to start server:', error);
|
||||
}
|
||||
}
|
||||
|
||||
private connectToServer(): void {
|
||||
if (this.ws) return;
|
||||
|
||||
try {
|
||||
const ws = new WebSocket(`ws://localhost:${this.wsPort}`);
|
||||
|
||||
ws.onopen = () => {
|
||||
this.notifyListeners(this.createEmptyData());
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
this.ws = null;
|
||||
|
||||
// 通知监听器连接已断开
|
||||
if (this.currentData) {
|
||||
this.notifyListeners(this.currentData);
|
||||
}
|
||||
|
||||
// 如果服务器还在运行,尝试重连
|
||||
if (this.isServerRunning && !this.reconnectTimeout) {
|
||||
this.reconnectTimeout = setTimeout(() => {
|
||||
this.reconnectTimeout = null;
|
||||
this.connectToServer();
|
||||
}, 3000);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error('[ProfilerService] WebSocket error:', error);
|
||||
this.ws = null;
|
||||
|
||||
// 通知监听器连接出错
|
||||
if (this.currentData) {
|
||||
this.notifyListeners(this.currentData);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
public async manualStopServer(): Promise<void> {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
if (message.type === 'debug_data' && message.data) {
|
||||
this.handleDebugData(message.data);
|
||||
} else if (message.type === 'get_raw_entity_list_response' && message.data) {
|
||||
this.handleRawEntityListResponse(message.data);
|
||||
} else if (message.type === 'get_entity_details_response' && message.data) {
|
||||
this.handleEntityDetailsResponse(message.data);
|
||||
} else if (message.type === 'log' && message.data) {
|
||||
this.handleRemoteLog(message.data);
|
||||
}
|
||||
await invoke('stop_profiler_server');
|
||||
this.isServerRunning = false;
|
||||
this.disconnect();
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to parse message:', error);
|
||||
console.error('[ProfilerService] Failed to stop server:', error);
|
||||
}
|
||||
};
|
||||
|
||||
this.ws = ws;
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to create WebSocket:', error);
|
||||
}
|
||||
}
|
||||
|
||||
public requestEntityDetails(entityId: number): void {
|
||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const request = {
|
||||
type: 'get_entity_details',
|
||||
requestId: `entity_details_${entityId}_${Date.now()}`,
|
||||
entityId
|
||||
};
|
||||
this.ws.send(JSON.stringify(request));
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to request entity details:', error);
|
||||
}
|
||||
}
|
||||
|
||||
private handleDebugData(debugData: any): void {
|
||||
const performance = debugData.performance;
|
||||
if (!performance) return;
|
||||
|
||||
const totalFrameTime = performance.frameTime || 0;
|
||||
const fps = totalFrameTime > 0 ? Math.round(1000 / totalFrameTime) : 0;
|
||||
|
||||
let systems: SystemPerformanceData[] = [];
|
||||
if (performance.systemPerformance && Array.isArray(performance.systemPerformance)) {
|
||||
systems = performance.systemPerformance
|
||||
.map((sys: any) => ({
|
||||
name: sys.systemName,
|
||||
executionTime: sys.lastExecutionTime || sys.averageTime || 0,
|
||||
entityCount: sys.entityCount || 0,
|
||||
averageTime: sys.averageTime || 0,
|
||||
percentage: 0
|
||||
}))
|
||||
.sort((a: SystemPerformanceData, b: SystemPerformanceData) =>
|
||||
b.executionTime - a.executionTime
|
||||
);
|
||||
|
||||
const totalTime = performance.frameTime || 1;
|
||||
systems.forEach((sys: SystemPerformanceData) => {
|
||||
sys.percentage = (sys.executionTime / totalTime) * 100;
|
||||
});
|
||||
private startServerCheck(): void {
|
||||
this.checkServerStatus();
|
||||
this.checkServerInterval = setInterval(() => {
|
||||
this.checkServerStatus();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
const entityCount = debugData.entities?.totalEntities || debugData.entities?.totalCount || 0;
|
||||
const componentTypes = debugData.components?.types || [];
|
||||
const componentCount = componentTypes.length;
|
||||
private async checkServerStatus(): Promise<void> {
|
||||
try {
|
||||
const status = await invoke<boolean>('get_profiler_status');
|
||||
const wasRunning = this.isServerRunning;
|
||||
this.isServerRunning = status;
|
||||
|
||||
this.currentData = {
|
||||
totalFrameTime,
|
||||
systems,
|
||||
entityCount,
|
||||
componentCount,
|
||||
fps,
|
||||
entities: []
|
||||
};
|
||||
// 服务器启动了,尝试连接
|
||||
if (status && !this.ws) {
|
||||
this.connectToServer();
|
||||
}
|
||||
|
||||
this.notifyListeners(this.currentData);
|
||||
|
||||
// 请求完整的实体列表
|
||||
this.requestRawEntityList();
|
||||
}
|
||||
|
||||
private requestRawEntityList(): void {
|
||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||||
return;
|
||||
// 服务器从运行变为停止
|
||||
if (wasRunning && !status) {
|
||||
this.disconnect();
|
||||
}
|
||||
} catch (error) {
|
||||
this.isServerRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const request = {
|
||||
type: 'get_raw_entity_list',
|
||||
requestId: `entity_list_${Date.now()}`
|
||||
};
|
||||
this.ws.send(JSON.stringify(request));
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to request entity list:', error);
|
||||
}
|
||||
}
|
||||
|
||||
private handleRawEntityListResponse(data: any): void {
|
||||
if (!data || !Array.isArray(data)) {
|
||||
return;
|
||||
private async startServer(): Promise<void> {
|
||||
try {
|
||||
const port = parseInt(this.wsPort);
|
||||
await invoke<string>('start_profiler_server', { port });
|
||||
this.isServerRunning = true;
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to start server:', error);
|
||||
}
|
||||
}
|
||||
|
||||
const entities: RemoteEntity[] = data.map((e: any) => ({
|
||||
id: e.id,
|
||||
name: e.name || `Entity ${e.id}`,
|
||||
enabled: e.enabled !== false,
|
||||
active: e.active !== false,
|
||||
activeInHierarchy: e.activeInHierarchy !== false,
|
||||
componentCount: e.componentCount || 0,
|
||||
componentTypes: e.componentTypes || [],
|
||||
parentId: e.parentId || null,
|
||||
childIds: e.childIds || [],
|
||||
depth: e.depth || 0,
|
||||
tag: e.tag || 0,
|
||||
updateOrder: e.updateOrder || 0
|
||||
}));
|
||||
private connectToServer(): void {
|
||||
if (this.ws) return;
|
||||
|
||||
if (this.currentData) {
|
||||
this.currentData.entities = entities;
|
||||
this.notifyListeners(this.currentData);
|
||||
}
|
||||
}
|
||||
try {
|
||||
const ws = new WebSocket(`ws://localhost:${this.wsPort}`);
|
||||
|
||||
private handleEntityDetailsResponse(data: any): void {
|
||||
if (!data) {
|
||||
return;
|
||||
ws.onopen = () => {
|
||||
this.notifyListeners(this.createEmptyData());
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
this.ws = null;
|
||||
|
||||
// 通知监听器连接已断开
|
||||
if (this.currentData) {
|
||||
this.notifyListeners(this.currentData);
|
||||
}
|
||||
|
||||
// 如果服务器还在运行,尝试重连
|
||||
if (this.isServerRunning && !this.reconnectTimeout) {
|
||||
this.reconnectTimeout = setTimeout(() => {
|
||||
this.reconnectTimeout = null;
|
||||
this.connectToServer();
|
||||
}, 3000);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error('[ProfilerService] WebSocket error:', error);
|
||||
this.ws = null;
|
||||
|
||||
// 通知监听器连接出错
|
||||
if (this.currentData) {
|
||||
this.notifyListeners(this.currentData);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
if (message.type === 'debug_data' && message.data) {
|
||||
this.handleDebugData(message.data);
|
||||
} else if (message.type === 'get_raw_entity_list_response' && message.data) {
|
||||
this.handleRawEntityListResponse(message.data);
|
||||
} else if (message.type === 'get_entity_details_response' && message.data) {
|
||||
this.handleEntityDetailsResponse(message.data);
|
||||
} else if (message.type === 'log' && message.data) {
|
||||
this.handleRemoteLog(message.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to parse message:', error);
|
||||
}
|
||||
};
|
||||
|
||||
this.ws = ws;
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to create WebSocket:', error);
|
||||
}
|
||||
}
|
||||
|
||||
const entityDetails: RemoteEntityDetails = {
|
||||
id: data.id,
|
||||
name: data.name || `Entity ${data.id}`,
|
||||
enabled: data.enabled !== false,
|
||||
active: data.active !== false,
|
||||
activeInHierarchy: data.activeInHierarchy !== false,
|
||||
scene: data.scene || '',
|
||||
sceneName: data.sceneName || '',
|
||||
sceneType: data.sceneType || '',
|
||||
componentCount: data.componentCount || 0,
|
||||
componentTypes: data.componentTypes || [],
|
||||
components: data.components || [],
|
||||
parentName: data.parentName || null
|
||||
};
|
||||
public requestEntityDetails(entityId: number): void {
|
||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.dispatchEvent(new CustomEvent('profiler:entity-details', {
|
||||
detail: entityDetails
|
||||
}));
|
||||
}
|
||||
|
||||
private handleRemoteLog(data: any): void {
|
||||
if (!data) {
|
||||
return;
|
||||
try {
|
||||
const request = {
|
||||
type: 'get_entity_details',
|
||||
requestId: `entity_details_${entityId}_${Date.now()}`,
|
||||
entityId
|
||||
};
|
||||
this.ws.send(JSON.stringify(request));
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to request entity details:', error);
|
||||
}
|
||||
}
|
||||
|
||||
const levelMap: Record<string, LogLevel> = {
|
||||
'debug': LogLevel.Debug,
|
||||
'info': LogLevel.Info,
|
||||
'warn': LogLevel.Warn,
|
||||
'error': LogLevel.Error,
|
||||
'fatal': LogLevel.Fatal
|
||||
};
|
||||
private handleDebugData(debugData: any): void {
|
||||
const performance = debugData.performance;
|
||||
if (!performance) return;
|
||||
|
||||
const level = levelMap[data.level?.toLowerCase() || 'info'] || LogLevel.Info;
|
||||
const totalFrameTime = performance.frameTime || 0;
|
||||
const fps = totalFrameTime > 0 ? Math.round(1000 / totalFrameTime) : 0;
|
||||
|
||||
let message = data.message || '';
|
||||
if (typeof message === 'object') {
|
||||
try {
|
||||
message = JSON.stringify(message, null, 2);
|
||||
} catch {
|
||||
message = String(message);
|
||||
}
|
||||
let systems: SystemPerformanceData[] = [];
|
||||
if (performance.systemPerformance && Array.isArray(performance.systemPerformance)) {
|
||||
systems = performance.systemPerformance
|
||||
.map((sys: any) => ({
|
||||
name: sys.systemName,
|
||||
executionTime: sys.lastExecutionTime || sys.averageTime || 0,
|
||||
entityCount: sys.entityCount || 0,
|
||||
averageTime: sys.averageTime || 0,
|
||||
percentage: 0
|
||||
}))
|
||||
.sort((a: SystemPerformanceData, b: SystemPerformanceData) =>
|
||||
b.executionTime - a.executionTime
|
||||
);
|
||||
|
||||
const totalTime = performance.frameTime || 1;
|
||||
systems.forEach((sys: SystemPerformanceData) => {
|
||||
sys.percentage = (sys.executionTime / totalTime) * 100;
|
||||
});
|
||||
}
|
||||
|
||||
const entityCount = debugData.entities?.totalEntities || debugData.entities?.totalCount || 0;
|
||||
const componentTypes = debugData.components?.types || [];
|
||||
const componentCount = componentTypes.length;
|
||||
|
||||
this.currentData = {
|
||||
totalFrameTime,
|
||||
systems,
|
||||
entityCount,
|
||||
componentCount,
|
||||
fps,
|
||||
entities: []
|
||||
};
|
||||
|
||||
this.notifyListeners(this.currentData);
|
||||
|
||||
// 请求完整的实体列表
|
||||
this.requestRawEntityList();
|
||||
}
|
||||
|
||||
const clientId = data.clientId || data.client_id || 'unknown';
|
||||
private requestRawEntityList(): void {
|
||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.dispatchEvent(new CustomEvent('profiler:remote-log', {
|
||||
detail: {
|
||||
level,
|
||||
message,
|
||||
timestamp: data.timestamp ? new Date(data.timestamp) : new Date(),
|
||||
clientId
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private createEmptyData(): ProfilerData {
|
||||
return {
|
||||
totalFrameTime: 0,
|
||||
systems: [],
|
||||
entityCount: 0,
|
||||
componentCount: 0,
|
||||
fps: 0
|
||||
};
|
||||
}
|
||||
|
||||
private notifyListeners(data: ProfilerData): void {
|
||||
this.listeners.forEach(listener => {
|
||||
try {
|
||||
listener(data);
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Error in listener:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private disconnect(): void {
|
||||
const hadConnection = this.ws !== null;
|
||||
|
||||
if (this.ws) {
|
||||
this.ws.close();
|
||||
this.ws = null;
|
||||
try {
|
||||
const request = {
|
||||
type: 'get_raw_entity_list',
|
||||
requestId: `entity_list_${Date.now()}`
|
||||
};
|
||||
this.ws.send(JSON.stringify(request));
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Failed to request entity list:', error);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.reconnectTimeout) {
|
||||
clearTimeout(this.reconnectTimeout);
|
||||
this.reconnectTimeout = null;
|
||||
private handleRawEntityListResponse(data: any): void {
|
||||
if (!data || !Array.isArray(data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entities: RemoteEntity[] = data.map((e: any) => ({
|
||||
id: e.id,
|
||||
name: e.name || `Entity ${e.id}`,
|
||||
enabled: e.enabled !== false,
|
||||
active: e.active !== false,
|
||||
activeInHierarchy: e.activeInHierarchy !== false,
|
||||
componentCount: e.componentCount || 0,
|
||||
componentTypes: e.componentTypes || [],
|
||||
parentId: e.parentId || null,
|
||||
childIds: e.childIds || [],
|
||||
depth: e.depth || 0,
|
||||
tag: e.tag || 0,
|
||||
updateOrder: e.updateOrder || 0
|
||||
}));
|
||||
|
||||
if (this.currentData) {
|
||||
this.currentData.entities = entities;
|
||||
this.notifyListeners(this.currentData);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有连接且手动断开,通知监听器
|
||||
if (hadConnection && this.currentData) {
|
||||
this.notifyListeners(this.currentData);
|
||||
}
|
||||
}
|
||||
private handleEntityDetailsResponse(data: any): void {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.disconnect();
|
||||
const entityDetails: RemoteEntityDetails = {
|
||||
id: data.id,
|
||||
name: data.name || `Entity ${data.id}`,
|
||||
enabled: data.enabled !== false,
|
||||
active: data.active !== false,
|
||||
activeInHierarchy: data.activeInHierarchy !== false,
|
||||
scene: data.scene || '',
|
||||
sceneName: data.sceneName || '',
|
||||
sceneType: data.sceneType || '',
|
||||
componentCount: data.componentCount || 0,
|
||||
componentTypes: data.componentTypes || [],
|
||||
components: data.components || [],
|
||||
parentName: data.parentName || null
|
||||
};
|
||||
|
||||
if (this.checkServerInterval) {
|
||||
clearInterval(this.checkServerInterval);
|
||||
this.checkServerInterval = null;
|
||||
window.dispatchEvent(new CustomEvent('profiler:entity-details', {
|
||||
detail: entityDetails
|
||||
}));
|
||||
}
|
||||
|
||||
this.listeners.clear();
|
||||
this.currentData = null;
|
||||
}
|
||||
private handleRemoteLog(data: any): void {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const levelMap: Record<string, LogLevel> = {
|
||||
'debug': LogLevel.Debug,
|
||||
'info': LogLevel.Info,
|
||||
'warn': LogLevel.Warn,
|
||||
'error': LogLevel.Error,
|
||||
'fatal': LogLevel.Fatal
|
||||
};
|
||||
|
||||
const level = levelMap[data.level?.toLowerCase() || 'info'] || LogLevel.Info;
|
||||
|
||||
let message = data.message || '';
|
||||
if (typeof message === 'object') {
|
||||
try {
|
||||
message = JSON.stringify(message, null, 2);
|
||||
} catch {
|
||||
message = String(message);
|
||||
}
|
||||
}
|
||||
|
||||
const clientId = data.clientId || data.client_id || 'unknown';
|
||||
|
||||
window.dispatchEvent(new CustomEvent('profiler:remote-log', {
|
||||
detail: {
|
||||
level,
|
||||
message,
|
||||
timestamp: data.timestamp ? new Date(data.timestamp) : new Date(),
|
||||
clientId
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private createEmptyData(): ProfilerData {
|
||||
return {
|
||||
totalFrameTime: 0,
|
||||
systems: [],
|
||||
entityCount: 0,
|
||||
componentCount: 0,
|
||||
fps: 0
|
||||
};
|
||||
}
|
||||
|
||||
private notifyListeners(data: ProfilerData): void {
|
||||
this.listeners.forEach((listener) => {
|
||||
try {
|
||||
listener(data);
|
||||
} catch (error) {
|
||||
console.error('[ProfilerService] Error in listener:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private disconnect(): void {
|
||||
const hadConnection = this.ws !== null;
|
||||
|
||||
if (this.ws) {
|
||||
this.ws.close();
|
||||
this.ws = null;
|
||||
}
|
||||
|
||||
if (this.reconnectTimeout) {
|
||||
clearTimeout(this.reconnectTimeout);
|
||||
this.reconnectTimeout = null;
|
||||
}
|
||||
|
||||
// 如果有连接且手动断开,通知监听器
|
||||
if (hadConnection && this.currentData) {
|
||||
this.notifyListeners(this.currentData);
|
||||
}
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.disconnect();
|
||||
|
||||
if (this.checkServerInterval) {
|
||||
clearInterval(this.checkServerInterval);
|
||||
this.checkServerInterval = null;
|
||||
}
|
||||
|
||||
this.listeners.clear();
|
||||
this.currentData = null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user