Files
michaelschiemer/resources/js/core/frameloop.js
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

114 lines
2.9 KiB
JavaScript

// modules/core/frameloop.js
import {Logger} from "./logger";
/**
* @typedef {Object} FrameTaskOptions
* @property {boolean} [autoStart=false] - Automatically start the frame loop
*/
/** @type {Map<string, Function>} */
const tasks = new Map();
/** @type {boolean} */
let running = false;
/** @type {boolean} */
let showDebug = false;
let lastTime = performance.now();
let frameCount = 0;
let fps = 0;
// Create debug overlay
const debugOverlay = document.createElement('div');
debugOverlay.style.position = 'fixed';
debugOverlay.style.bottom = '0';
debugOverlay.style.left = '0';
debugOverlay.style.font = '12px monospace';
debugOverlay.style.color = '#0f0';
debugOverlay.style.background = 'rgba(0,0,0,0.75)';
debugOverlay.style.padding = '0.25rem 0.5rem';
debugOverlay.style.zIndex = '9999';
debugOverlay.style.pointerEvents = 'none';
debugOverlay.style.display = 'none';
const barWidth = Math.min(fps * 2, 100);
const bar = `<div style="width:${barWidth}%;height:4px;background:#0f0;margin-top:4px;"></div>`;
debugOverlay.innerHTML += bar;
debugOverlay.style.lineHeight = '1.4';
document.body.appendChild(debugOverlay);
import { PerformanceMonitor } from './PerformanceMonitor.js';
/** @type {PerformanceMonitor} */
export const monitor = new PerformanceMonitor();
// Debug toggle with § key
window.addEventListener('keydown', (e) => {
if (e.key === '§') {
showDebug = !showDebug;
debugOverlay.style.display = showDebug ? 'block' : 'none';
}
});
/**
* Register a task to run on every frame
* @param {string} id - Unique identifier for the task
* @param {Function} callback - Function to execute each frame
* @param {FrameTaskOptions} [options={}] - Task options
*/
export function registerFrameTask(id, callback, options = {}) {
tasks.set(id, callback);
if (options.autoStart && !running) startFrameLoop();
}
/**
* Unregister a frame task
* @param {string} id - Task identifier to remove
*/
export function unregisterFrameTask(id) {
tasks.delete(id);
}
/**
* Clear all registered frame tasks
*/
export function clearFrameTasks() {
tasks.clear();
}
/**
* Start the main frame loop
*/
export function startFrameLoop() {
if (running) return;
running = true;
function loop() {
for (const [id, task] of tasks) {
try {
if (showDebug) {
monitor.trackTask(id, task);
} else {
task();
}
} catch (err) {
Logger.warn(`[Frameloop] Fehler in Task:`, err);
}
}
if (showDebug) {
monitor.update(tasks);
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}
/**
* Stop the frame loop
* Note: Loop continues until next frame, this just sets the flag
*/
export function stopFrameLoop() {
running = false;
// Achtung: Loop läuft weiter, solange nicht aktiv gestoppt
}