212 lines
6.2 KiB
JavaScript
212 lines
6.2 KiB
JavaScript
/**
|
|
* Animation Queue Module
|
|
* Handles scheduling and executing animations with proper resource management
|
|
* and synchronization with TTS
|
|
*/
|
|
import { BaseModule } from './base-module.js';
|
|
import { moduleRegistry } from './module-registry.js';
|
|
import { ModuleEvent } from './base-module.js'; // Add this import
|
|
|
|
class AnimationQueueModule extends BaseModule {
|
|
constructor() {
|
|
super('animation-queue', 'Animation Queue');
|
|
|
|
// Queue of scheduled animations/functions
|
|
this.queue = [];
|
|
|
|
// Animation timing properties
|
|
this.speed = 0.05; // Base animation speed (seconds per character)
|
|
this.delay = 0; // Current accumulated delay
|
|
|
|
// Module dependencies
|
|
this.dependencies = ['tts'];
|
|
this.tts = null; // TTS module reference
|
|
|
|
// Fast-forwarding state
|
|
this.isFastForwarding = false;
|
|
|
|
// Bind methods
|
|
this.schedule = this.schedule.bind(this);
|
|
this.fastForward = this.fastForward.bind(this);
|
|
this.clearAll = this.clearAll.bind(this);
|
|
this.setSpeed = this.setSpeed.bind(this);
|
|
}
|
|
|
|
async waitForDependencies() {
|
|
try {
|
|
// Wait for TTS module to be available
|
|
this.tts = moduleRegistry.getModule('tts');
|
|
|
|
if (!this.tts) {
|
|
console.warn("TTS module not ready, Animation Queue will have limited functionality");
|
|
return true; // Continue anyway
|
|
}
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error("Error waiting for Animation Queue dependencies:", error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async initialize() {
|
|
try {
|
|
// Nothing special to initialize here
|
|
this.reportProgress(100, "Animation Queue ready");
|
|
return true;
|
|
} catch (error) {
|
|
console.error("Error initializing Animation Queue:", error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Schedule a function to execute after a delay
|
|
* @param {Function} func - Function to execute
|
|
* @param {number} delay - Delay in milliseconds
|
|
* @param {...any} args - Arguments to pass to the function
|
|
* @returns {Object} - Timeout object that can be used to cancel
|
|
*/
|
|
schedule(func, delay, ...args) {
|
|
if (typeof func !== 'function') {
|
|
console.error('Animation Queue: Not a function passed to schedule');
|
|
return null;
|
|
}
|
|
|
|
// Create timeout object with execute method
|
|
const timeoutObject = {
|
|
execute: () => {
|
|
try {
|
|
func(...args);
|
|
} catch (error) {
|
|
console.error('Error executing scheduled function:', error);
|
|
}
|
|
},
|
|
timeoutId: null,
|
|
createdAt: Date.now(),
|
|
delay: delay
|
|
};
|
|
|
|
// Apply speed factor to the delay
|
|
const adjustedDelay = delay * this.speed;
|
|
|
|
// Schedule execution
|
|
timeoutObject.timeoutId = setTimeout(() => {
|
|
// Execute the function
|
|
timeoutObject.execute();
|
|
|
|
// Remove from queue
|
|
const index = this.queue.indexOf(timeoutObject);
|
|
if (index !== -1) {
|
|
this.queue.splice(index, 1);
|
|
}
|
|
}, adjustedDelay);
|
|
|
|
// Add to queue
|
|
this.queue.push(timeoutObject);
|
|
|
|
// Update current total delay
|
|
this.delay = adjustedDelay + delay;
|
|
|
|
return timeoutObject;
|
|
}
|
|
|
|
/**
|
|
* Fast-forward all pending animations
|
|
*/
|
|
fastForward() {
|
|
console.log(`Animation Queue: Fast-forwarding ${this.queue.length} pending items`);
|
|
|
|
// Stop TTS if playing
|
|
if (this.tts) {
|
|
this.tts.stop();
|
|
}
|
|
|
|
// Execute and clear all timeouts
|
|
const queueCopy = [...this.queue]; // Make a copy to avoid modification during iteration
|
|
|
|
queueCopy.forEach(timeoutObject => {
|
|
// Clear timeout
|
|
if (timeoutObject.timeoutId !== null) {
|
|
clearTimeout(timeoutObject.timeoutId);
|
|
}
|
|
|
|
// Execute immediately
|
|
timeoutObject.execute();
|
|
});
|
|
|
|
// Clear queue
|
|
this.queue = [];
|
|
|
|
// Reset delay
|
|
this.delay = 0;
|
|
|
|
// Use direct DOM event dispatch instead of this.dispatchEvent
|
|
document.dispatchEvent(new CustomEvent('animations:fastForwarded', {
|
|
detail: { moduleId: this.id }
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Clear all scheduled animations without executing them
|
|
*/
|
|
clearAll() {
|
|
console.log(`Animation Queue: Clearing ${this.queue.length} pending items`);
|
|
|
|
// Clear all timeouts
|
|
this.queue.forEach(timeoutObject => {
|
|
if (timeoutObject.timeoutId !== null) {
|
|
clearTimeout(timeoutObject.timeoutId);
|
|
}
|
|
});
|
|
|
|
// Clear queue
|
|
this.queue = [];
|
|
|
|
// Reset delay
|
|
this.delay = 0;
|
|
}
|
|
|
|
/**
|
|
* Set the animation speed
|
|
* @param {number} speed - Animation speed factor (lower is faster)
|
|
*/
|
|
setSpeed(speed) {
|
|
if (typeof speed !== 'number' || speed <= 0) {
|
|
console.error('Animation Queue: Invalid speed value');
|
|
return;
|
|
}
|
|
|
|
this.speed = speed;
|
|
console.log(`Animation Queue: Speed set to ${speed}`);
|
|
}
|
|
|
|
/**
|
|
* Get current queue length
|
|
* @returns {number} - Number of items in the queue
|
|
*/
|
|
getQueueLength() {
|
|
return this.queue.length;
|
|
}
|
|
|
|
/**
|
|
* Get current accumulated delay
|
|
* @returns {number} - Current delay in milliseconds
|
|
*/
|
|
getCurrentDelay() {
|
|
return this.delay;
|
|
}
|
|
}
|
|
|
|
// Create the singleton instance
|
|
const AnimationQueue = new AnimationQueueModule();
|
|
|
|
// Register with the module registry
|
|
moduleRegistry.register(AnimationQueue);
|
|
|
|
// Export the module
|
|
export { AnimationQueue };
|
|
|
|
// Keep a reference in window for loader system
|
|
window.AnimationQueue = AnimationQueue;
|