'use strict'; /** * Base Controller class that provides common functionality for all controller types */ class BaseController { constructor(device, uiDependencies = {}) { this.device = device; this.type = "undefined"; // to be set by subclasses // UI dependencies injected from core this.l = uiDependencies.l; } getType() { return this.type; } /** * Get the underlying HID device * @returns {HIDDevice} The HID device */ getDevice() { return this.device; } getInputConfig() { throw new Error('getInputConfig() must be implemented by subclass'); } /** * Set input report handler * @param {Function} handler Input report handler function */ setInputReportHandler(handler) { this.device.oninputreport = handler; } /** * Allocate request buffer with proper size based on device feature reports * @param {number} id Report ID * @param {Array} data Data array to include in the request * @returns {Uint8Array} Allocated request buffer */ alloc_req(id, data = []) { const fr = this.device.collections[0].featureReports; const report = fr.find(e => e.reportId === id); const maxLen = report?.reportCount || data.length; const out = new Uint8Array(data.length); out.set(data.slice(0, maxLen)); return out; } /** * Send feature report to device * @param {number} reportId Report ID * @param {ArrayBuffer|Array} data Data to send (if Array, will be processed through allocReq) */ async sendFeatureReport(reportId, data) { // If data is an array, use allocReq to create proper buffer if (Array.isArray(data)) { data = this.alloc_req(reportId, data); } return await this.device.sendFeatureReport(reportId, data); } /** * Receive feature report from device * @param {number} reportId Report ID */ async receiveFeatureReport(reportId) { return await this.device.receiveFeatureReport(reportId); } /** * Close the HID device connection */ async close() { if (this.device && this.device.opened) { await this.device.close(); } } // Abstract methods that must be implemented by subclasses async getInfo() { throw new Error('getInfo() must be implemented by subclass'); } async flash(progressCallback = null) { throw new Error('flash() must be implemented by subclass'); } async reset() { throw new Error('reset() must be implemented by subclass'); } async nvsLock() { throw new Error('nvsLock() must be implemented by subclass'); } async nvsUnlock() { throw new Error('nvsUnlock() must be implemented by subclass'); } async calibrateSticksBegin() { throw new Error('calibrateSticksBegin() must be implemented by subclass'); } async calibrateSticksEnd() { throw new Error('calibrateSticksEnd() must be implemented by subclass'); } async calibrateSticksSample() { throw new Error('calibrateSticksSample() must be implemented by subclass'); } async calibrateRangeBegin() { throw new Error('calibrateRangeBegin() must be implemented by subclass'); } async calibrateRangeEnd() { throw new Error('calibrateRangeEnd() must be implemented by subclass'); } } export default BaseController;