{"version":3,"file":"FrameThrottler.cjs","sources":["../../../src/managers/FrameThrottler.ts"],"sourcesContent":["// src/components/KineticSlider/managers/FrameThrottler.ts\n\n/**\n * @file FrameThrottler.ts\n * @description Provides advanced frame timing controls to optimize rendering performance.\n * Offers various throttling strategies to consolidate updates and reduce GPU load.\n */\n\n/**\n * Frame throttling strategies that determine how updates are scheduled.\n * @enum {string}\n */\nexport enum ThrottleStrategy {\n    /**\n     * Fixed frames per second - aims for consistent frame timing\n     * by enforcing a fixed interval between frames.\n     */\n    FIXED_FPS = 'fixed_fps',\n\n    /**\n     * Adaptive - adjusts timing based on device performance\n     * by monitoring actual frame rates and adjusting accordingly.\n     */\n    ADAPTIVE = 'adaptive',\n\n    /**\n     * Priority-based - only throttles lower priority updates\n     * while allowing high-priority updates to bypass throttling.\n     */\n    PRIORITY = 'priority',\n\n    /**\n     * None - no throttling applied (use with caution)\n     * as it may lead to performance issues on low-end devices.\n     */\n    NONE = 'none'\n}\n\n/**\n * Configuration options for the FrameThrottler.\n * @interface ThrottlerConfig\n */\nexport interface ThrottlerConfig {\n    /**\n     * Target frames per second (for FIXED_FPS strategy).\n     * Higher values provide smoother animation but require more processing power.\n     */\n    targetFps?: number;\n\n    /**\n     * Minimum acceptable frames per second (for ADAPTIVE strategy).\n     * The throttler will attempt to maintain at least this frame rate.\n     */\n    minFps?: number;\n\n    /**\n     * Maximum acceptable frames per second (for ADAPTIVE strategy).\n     * The throttler will cap the frame rate at this value to save resources.\n     */\n    maxFps?: number;\n\n    /**\n     * Selected throttling strategy to use.\n     * @see {ThrottleStrategy}\n     */\n    strategy?: ThrottleStrategy;\n\n    /**\n     * Enable performance monitoring and auto-adjustment.\n     * When enabled, the throttler will collect metrics and adjust settings dynamically.\n     */\n    enableMonitoring?: boolean;\n}\n\n/**\n * Default configuration values for the throttler.\n * @type {ThrottlerConfig}\n */\nconst DEFAULT_CONFIG: ThrottlerConfig = {\n    targetFps: 60,\n    minFps: 30,\n    maxFps: 120,\n    strategy: ThrottleStrategy.FIXED_FPS,\n    enableMonitoring: true\n};\n\n/**\n * Performance data for monitoring and auto-adjustment.\n * @interface PerformanceData\n * @private\n */\ninterface PerformanceData {\n    /**\n     * Array of recent frame durations in milliseconds.\n     * Used to calculate average performance over time.\n     */\n    frameTimes: number[];\n\n    /**\n     * Current average FPS calculated from recent frame times.\n     */\n    currentFps: number;\n\n    /**\n     * Number of frames processed since initialization.\n     */\n    frameCount: number;\n\n    /**\n     * Timestamp of last performance adjustment in milliseconds.\n     */\n    lastAdjustment: number;\n\n    /**\n     * Current throttle interval in milliseconds.\n     */\n    currentInterval: number;\n}\n\n/**\n * Manages frame timing and throttling for optimal performance.\n * This class helps reduce GPU load by controlling when frames are processed.\n */\nexport class FrameThrottler {\n    /** Active configuration */\n    private config: ThrottlerConfig;\n\n    /** Performance monitoring data */\n    private performance: PerformanceData;\n\n    /** Timestamp of the last processed frame */\n    private lastFrameTime: number = 0;\n\n    /**\n     * Create a new FrameThrottler with the specified configuration.\n     *\n     * @param {ThrottlerConfig} [config] - Configuration options for the throttler\n     *\n     * @example\n     * // Create a throttler with default settings (60fps, FIXED_FPS strategy)\n     * const throttler = new FrameThrottler();\n     *\n     * @example\n     * // Create a throttler with custom settings\n     * const throttler = new FrameThrottler({\n     *   targetFps: 30,\n     *   strategy: ThrottleStrategy.ADAPTIVE,\n     *   minFps: 15,\n     *   maxFps: 60\n     * });\n     */\n    constructor(config?: Partial<ThrottlerConfig>) {\n        this.config = { ...DEFAULT_CONFIG, ...config };\n\n        // Initialize performance data\n        this.performance = {\n            frameTimes: [],\n            currentFps: this.config.targetFps!,\n            frameCount: 0,\n            lastAdjustment: performance.now(),\n            currentInterval: this.calculateInterval(this.config.targetFps!)\n        };\n\n        this.lastFrameTime = performance.now();\n    }\n\n    /**\n     * Calculate the frame interval in milliseconds from FPS.\n     *\n     * @param {number} fps - Frames per second\n     * @returns {number} Interval in milliseconds between frames\n     * @private\n     */\n    private calculateInterval(fps: number): number {\n        return 1000 / fps;\n    }\n\n    /**\n     * Check if enough time has passed to process the next frame.\n     *\n     * @param {number} [priority] - Optional priority level to consider (higher values bypass more throttling)\n     * @returns {boolean} True if the frame should be processed, false if it should be skipped\n     *\n     * @example\n     * // Basic usage in animation loop\n     * if (throttler.shouldProcessFrame()) {\n     *   // Process frame\n     *   render();\n     *   throttler.frameProcessed();\n     * }\n     *\n     * @example\n     * // Usage with priority (3 is highest priority)\n     * if (throttler.shouldProcessFrame(2)) {\n     *   // Process high-priority frame\n     *   renderImportantElements();\n     *   throttler.frameProcessed();\n     * }\n     */\n    public shouldProcessFrame(priority?: number): boolean {\n        const now = performance.now();\n        const elapsed = now - this.lastFrameTime;\n\n        // Handle different strategies\n        switch (this.config.strategy) {\n            case ThrottleStrategy.NONE:\n                return true;\n\n            case ThrottleStrategy.PRIORITY:\n                // High priority updates bypass throttling\n                if (priority !== undefined && priority >= 2) {\n                    return true;\n                }\n                // Otherwise use fixed fps throttling\n                return elapsed >= this.performance.currentInterval;\n\n            case ThrottleStrategy.ADAPTIVE:\n                // Adaptively adjust the interval based on recent performance\n                this.updateAdaptivePerformance(now);\n                return elapsed >= this.performance.currentInterval;\n\n            case ThrottleStrategy.FIXED_FPS:\n            default:\n                // Simple fixed interval throttling\n                return elapsed >= this.performance.currentInterval;\n        }\n    }\n\n    /**\n     * Mark the current frame as processed and update timing metrics.\n     * Should be called after processing a frame that passed the shouldProcessFrame check.\n     *\n     * @example\n     * if (throttler.shouldProcessFrame()) {\n     *   // Process frame\n     *   render();\n     *   throttler.frameProcessed();\n     * }\n     */\n    public frameProcessed(): void {\n        const now = performance.now();\n        const frameDuration = now - this.lastFrameTime;\n        this.lastFrameTime = now;\n\n        // Update performance metrics\n        if (this.config.enableMonitoring) {\n            this.updatePerformanceMetrics(frameDuration);\n        }\n    }\n\n    /**\n     * Update performance metrics with the latest frame duration.\n     *\n     * @param {number} frameDuration - Duration of the last frame in milliseconds\n     * @private\n     */\n    private updatePerformanceMetrics(frameDuration: number): void {\n        // Add to the frame times array (keep last 60 frames)\n        this.performance.frameTimes.push(frameDuration);\n        if (this.performance.frameTimes.length > 60) {\n            this.performance.frameTimes.shift();\n        }\n\n        // Calculate current FPS\n        const avgFrameDuration = this.performance.frameTimes.reduce((sum, time) => sum + time, 0) /\n            this.performance.frameTimes.length;\n        this.performance.currentFps = 1000 / avgFrameDuration;\n\n        // Increment frame count\n        this.performance.frameCount++;\n    }\n\n    /**\n     * Update adaptive performance settings based on recent metrics.\n     * This method adjusts the frame rate based on the device's capabilities.\n     *\n     * @param {number} now - Current timestamp in milliseconds\n     * @private\n     */\n    private updateAdaptivePerformance(now: number): void {\n        // Only adjust every 1 second\n        if (now - this.performance.lastAdjustment < 1000 ||\n            this.performance.frameTimes.length < 10) {\n            return;\n        }\n\n        // Calculate average FPS\n        const avgFps = this.performance.currentFps;\n\n        // Adjust based on performance\n        let targetFps = this.config.targetFps!;\n\n        if (avgFps < this.config.minFps!) {\n            // Performance is too low, reduce target FPS\n            targetFps = Math.max(this.config.minFps!, targetFps * 0.8);\n        } else if (avgFps > this.config.maxFps!) {\n            // Performance is very good, increase target FPS up to max\n            targetFps = Math.min(this.config.maxFps!, targetFps * 1.2);\n        } else if (avgFps > targetFps * 1.2) {\n            // We have headroom, gradually increase target FPS\n            targetFps = Math.min(this.config.maxFps!, targetFps * 1.1);\n        }\n\n        // Update the interval\n        this.performance.currentInterval = this.calculateInterval(targetFps);\n        this.performance.lastAdjustment = now;\n    }\n\n    /**\n     * Set a specific throttling strategy.\n     *\n     * @param {ThrottleStrategy} strategy - The throttling strategy to use\n     *\n     * @example\n     * // Switch to adaptive strategy based on device capability\n     * if (isLowEndDevice) {\n     *   throttler.setStrategy(ThrottleStrategy.ADAPTIVE);\n     * }\n     */\n    public setStrategy(strategy: ThrottleStrategy): void {\n        this.config.strategy = strategy;\n    }\n\n    /**\n     * Set a specific target FPS.\n     *\n     * @param {number} fps - Target frames per second (must be > 0)\n     *\n     * @example\n     * // Reduce target FPS to save battery\n     * if (isBatteryLow) {\n     *   throttler.setTargetFps(30);\n     * } else {\n     *   throttler.setTargetFps(60);\n     * }\n     */\n    public setTargetFps(fps: number): void {\n        this.config.targetFps = Math.max(1, fps);\n\n        // Update the interval if using fixed FPS\n        if (this.config.strategy === ThrottleStrategy.FIXED_FPS) {\n            this.performance.currentInterval = this.calculateInterval(this.config.targetFps);\n        }\n    }\n\n    /**\n     * Get current performance metrics for monitoring and debugging.\n     *\n     * @returns {Object} Performance information including current FPS, interval, frame count, and strategy\n     *\n     * @example\n     * // Log performance metrics\n     * console.log(throttler.getPerformanceMetrics());\n     * // Example output: { currentFps: 58.2, targetInterval: 16.67, frameCount: 1242, strategy: 'fixed_fps' }\n     */\n    public getPerformanceMetrics(): {\n        currentFps: number;\n        targetInterval: number;\n        frameCount: number;\n        strategy: ThrottleStrategy;\n    } {\n        return {\n            currentFps: this.performance.currentFps,\n            targetInterval: this.performance.currentInterval,\n            frameCount: this.performance.frameCount,\n            strategy: this.config.strategy!\n        };\n    }\n}"],"names":["ThrottleStrategy"],"mappings":"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"}