From a594093573eb6cd65671a0bcaea18cc9e5965d90 Mon Sep 17 00:00:00 2001 From: JovannMC Date: Mon, 22 Jul 2024 21:27:26 +0300 Subject: [PATCH] Fix freezing w/ multiple isDeviceAvailable() calls --- src/HaritoraX.ts | 66 +++++++++++++++++++++++++++---------------- src/mode/bluetooth.ts | 47 +++++++++++------------------- src/mode/com.ts | 2 +- 3 files changed, 59 insertions(+), 56 deletions(-) diff --git a/src/HaritoraX.ts b/src/HaritoraX.ts index 38a4d42..40961a1 100644 --- a/src/HaritoraX.ts +++ b/src/HaritoraX.ts @@ -773,8 +773,8 @@ export default class HaritoraX extends EventEmitter { async getAvailableDevices(): Promise { let availableDevices: string[] = []; - const com = new COM("wireless", 100000); - const bluetooth = new Bluetooth(); + let com = new COM("wireless"); + let bluetooth = new Bluetooth(); if (await com.isDeviceAvailable()) { const devices = await com.getAvailableDevices(); @@ -792,6 +792,12 @@ export default class HaritoraX extends EventEmitter { availableDevices.push("HaritoraX Wireless"); } + com.removeAllListeners(); + bluetooth.removeAllListeners(); + + com = null; + bluetooth = null; + return availableDevices; } @@ -803,16 +809,20 @@ export default class HaritoraX extends EventEmitter { * @returns {string[]} The available ports for the specified device. */ async getDevicePorts(device: string): Promise { - const com = new COM("wireless", 100000); - - if (device === "HaritoraX Wired") { - return ( - (await com.getDevicePorts("HaritoraX 1.0")) || - (await com.getDevicePorts("HaritoraX 1.1")) || - (await com.getDevicePorts("HaritoraX 1.1b")) - ); - } else { - return await com.getDevicePorts(device); + let com = new COM("wireless"); + try { + if (device === "HaritoraX Wired") { + return ( + (await com.getDevicePorts("HaritoraX 1.0")) || + (await com.getDevicePorts("HaritoraX 1.1")) || + (await com.getDevicePorts("HaritoraX 1.1b")) + ); + } else { + return await com.getDevicePorts(device); + } + } finally { + com.removeAllListeners(); + com = null; } } } @@ -1652,19 +1662,25 @@ async function removeActiveDevices(deviceTypeToRemove: string) { function getTrackerSettingsFromMap(trackerName: string) { const settings = trackerSettings.get(trackerName); - const settingsToLog = { - "Sensor mode": settings[0], - "FPS mode": settings[1], - "Sensor auto correction": settings[2], - "Ankle motion detection": settings[3], - }; - logSettings(trackerName, settingsToLog); - return { - sensorMode: settings[0], - fpsMode: settings[1], - sensorAutoCorrection: settings[2], - ankleMotionDetection: settings[3], - }; + if (settings) { + const settingsToLog = { + "Sensor mode": settings[0], + "FPS mode": settings[1], + "Sensor auto correction": settings[2], + "Ankle motion detection": settings[3], + }; + logSettings(trackerName, settingsToLog); + + return { + sensorMode: settings[0], + fpsMode: settings[1], + sensorAutoCorrection: settings[2], + ankleMotionDetection: settings[3], + }; + } else { + error(`Tracker ${trackerName} settings not found in trackerSettings map.`); + return null; + } } /* diff --git a/src/mode/bluetooth.ts b/src/mode/bluetooth.ts index fb783f8..da0394f 100644 --- a/src/mode/bluetooth.ts +++ b/src/mode/bluetooth.ts @@ -1,6 +1,6 @@ "use strict"; -import noble, { Peripheral, Service, Characteristic } from "@abandonware/noble"; +import noble, { Peripheral, Service, Characteristic, _state } from "@abandonware/noble"; import { EventEmitter } from "events"; let main: Bluetooth = undefined; @@ -64,40 +64,27 @@ export default class Bluetooth extends EventEmitter { async isDeviceAvailable() { return new Promise((resolve) => { let found = false; - - const discoverListener = (peripheral: Peripheral) => { + + noble.on("discover", (peripheral) => { if (peripheral.advertisement.localName && peripheral.advertisement.localName.startsWith("HaritoraXW-")) { found = true; noble.stopScanning(); - cleanupListeners(); resolve(true); } - }; - - const stateChangeListener = (state: string) => { - if (state === "poweredOn" && !found) { - noble.startScanning([], true); - - setTimeout(() => { - if (!found) { - noble.stopScanning(); - cleanupListeners(); - resolve(false); - } - }, 3000); - } else { - cleanupListeners(); - resolve(false); - } - }; - - const cleanupListeners = () => { - noble.removeListener("discover", discoverListener); - noble.removeListener("stateChange", stateChangeListener); - }; - - noble.on("discover", discoverListener); - noble.on("stateChange", stateChangeListener); + }); + + if (noble._state === "poweredOn" && !found) { + noble.startScanning([], true); + + setTimeout(() => { + if (!found) { + noble.stopScanning(); + resolve(false); + } + }, 3000); + } else if (noble._state !== "poweredOn") { + resolve(false); + } }); } diff --git a/src/mode/com.ts b/src/mode/com.ts index 02e3146..8b81cea 100644 --- a/src/mode/com.ts +++ b/src/mode/com.ts @@ -55,7 +55,7 @@ let trackerModelEnabled: String; let heartbeatInterval: number; // in milliseconds export default class COM extends EventEmitter { - constructor(trackerModel: string, heartbeat: number) { + constructor(trackerModel: string, heartbeat?: number) { super(); this.setMaxListeners(1); // Prevent memory leaks main = this;