// modules/core/PerformanceMonitor.js export class PerformanceMonitor { constructor({ fps = true } = {}) { this.fpsEnabled = fps; this.fps = 0; this.frameCount = 0; this.lastTime = performance.now(); this.visible = false; this.taskTimings = new Map(); this.logs = []; this.container = document.createElement('div'); this.container.style.position = 'fixed'; this.container.style.bottom = '0'; this.container.style.left = '0'; this.container.style.font = '12px Consolas, monospace'; this.container.style.color = '#0f0'; this.container.style.background = 'rgba(0,0,0,0.75)'; this.container.style.padding = '0.5rem'; this.container.style.zIndex = '9999'; this.container.style.pointerEvents = 'none'; this.container.style.lineHeight = '1.4'; this.container.style.whiteSpace = 'pre'; this.container.style.display = 'none'; document.body.appendChild(this.container); window.addEventListener('keydown', (e) => { if (e.key === 'ยง') { this.visible = !this.visible; this.container.style.display = this.visible ? 'block' : 'none'; } }); } log(message) { const timestamp = new Date().toLocaleTimeString(); this.logs.push(`[${timestamp}] ${message}`); if (this.logs.length > 5) this.logs.shift(); } update(taskMap = new Map()) { this.frameCount++; const now = performance.now(); if (now - this.lastTime >= 1000) { this.fps = this.frameCount; this.frameCount = 0; this.lastTime = now; const timings = []; for (const [id, duration] of this.taskTimings.entries()) { timings.push(`${id}: ${duration.toFixed(2)}ms`); } const barWidth = Math.min(this.fps * 2, 100); const logOutput = this.logs.slice().reverse().join('\n'); this.container.innerHTML = ` FPS: ${this.fps} | Tasks: ${taskMap.size} ${timings.join('\n')}
${logOutput ? '\nLogs:\n' + logOutput : ''} `; } } trackTask(id, callback) { const start = performance.now(); callback(); const duration = performance.now() - start; this.taskTimings.set(id, duration); } }