UNPKG

ive-connect

Version:

A universal haptic device control library for interactive experiences

221 lines (220 loc) 7.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DeviceManager = void 0; /** * Device Manager * * Central manager for all haptic devices */ const events_1 = require("./events"); /** * Device Manager class * Handles registration and control of multiple haptic devices */ class DeviceManager extends events_1.EventEmitter { constructor() { super(...arguments); this.devices = new Map(); this.scriptData = null; } /** * Register a device with the manager * @param device Device to register */ registerDevice(device) { // Don't register the same device twice if (this.devices.has(device.id)) { return; } this.devices.set(device.id, device); // Forward events from this device this.setupDeviceEventForwarding(device); // Emit device added event this.emit("deviceAdded", device); } /** * Unregister a device from the manager * @param deviceId Device ID to unregister */ unregisterDevice(deviceId) { const device = this.devices.get(deviceId); if (device) { this.devices.delete(deviceId); this.emit("deviceRemoved", device); } } /** * Get all registered devices */ getDevices() { return Array.from(this.devices.values()); } /** * Get a specific device by ID * @param deviceId Device ID to retrieve */ getDevice(deviceId) { return this.devices.get(deviceId); } /** * Connect to all registered devices * @returns Object with success status for each device */ async connectAll() { const results = {}; for (const [id, device] of this.devices.entries()) { try { results[id] = await device.connect(); } catch (error) { console.error(`Error connecting device ${id}:`, error); results[id] = false; } } return results; } /** * Disconnect from all registered devices * @returns Object with success status for each device */ async disconnectAll() { const results = {}; for (const [id, device] of this.devices.entries()) { try { results[id] = await device.disconnect(); } catch (error) { console.error(`Error disconnecting device ${id}:`, error); results[id] = false; } } return results; } /** * Load a script to all connected devices * @param scriptData Script data to load * @param options Options for script loading (e.g., invertScript) * @returns Object with success status for each device */ async loadScriptAll(scriptData, options) { const results = {}; this.scriptData = scriptData; for (const [id, device] of this.devices.entries()) { if (device.isConnected || device.id === "buttplug") { try { results[id] = await device.loadScript(scriptData, options); } catch (error) { console.error(`Error loading script to device ${id}:`, error); results[id] = { success: false }; } } else { results[id] = { success: false }; } } const transformedResults = {}; for (const [id, result] of Object.entries(results)) { if (result.scriptContent) { transformedResults["script"] = result.scriptContent; } transformedResults[id] = result.success; } return transformedResults; } /** * Start playback on all connected devices * @param timeMs Current time in milliseconds * @param playbackRate Playback rate (1.0 = normal speed) * @param loop Whether to loop the script * @returns Object with success status for each device */ async playAll(timeMs, playbackRate = 1.0, loop = false) { const results = {}; for (const [id, device] of this.devices.entries()) { if (device.isConnected) { try { results[id] = await device.play(timeMs, playbackRate, loop); } catch (error) { console.error(`Error playing on device ${id}:`, error); results[id] = false; } } else { results[id] = false; } } return results; } /** * Stop playback on all connected devices * @returns Object with success status for each device */ async stopAll() { const results = {}; for (const [id, device] of this.devices.entries()) { if (device.isConnected) { try { results[id] = await device.stop(); } catch (error) { console.error(`Error stopping device ${id}:`, error); results[id] = false; } } else { results[id] = false; } } return results; } /** * Synchronize time on all connected and playing devices * @param timeMs Current time in milliseconds * @param filter Time filter for synchronization * @returns Object with success status for each device */ async syncTimeAll(timeMs, filter = 0.5) { const results = {}; for (const [id, device] of this.devices.entries()) { if (device.isConnected && device.isPlaying) { try { results[id] = await device.syncTime(timeMs, filter); } catch (error) { console.error(`Error syncing time on device ${id}:`, error); results[id] = false; } } else { results[id] = false; } } return results; } /** * Set up event forwarding from a device to the manager * @param device Device to forward events from */ setupDeviceEventForwarding(device) { // Forward common events const eventsToForward = [ "error", "connected", "disconnected", "connectionStateChanged", "playbackStateChanged", "scriptLoaded", "configChanged", ]; for (const eventName of eventsToForward) { device.on(eventName, (data) => { this.emit(`device:${device.id}:${eventName}`, data); // Also emit a general event for any device this.emit(`device:${eventName}`, { deviceId: device.id, data }); }); } } } exports.DeviceManager = DeviceManager;