Przeglądaj źródła

Used event emitter over promise.

Andrew Chalkley 9 lat temu
rodzic
commit
3865c1c128
3 zmienionych plików z 104 dodań i 27 usunięć
  1. 0 11
      back-end/available_serial_ports.js
  2. 71 0
      back-end/serial_scanner.js
  3. 33 16
      front-end/js/app.js

+ 0 - 11
back-end/available_serial_ports.js

@@ -1,11 +0,0 @@
-var serialport = require("serialport");
-
-module.exports = function getAvailablePorts(){
-    return new Promise(function(resolve, reject){
-        serialport.list(function (err, ports) {
-            if(err) reject(err);
-            else if(ports.length === 0) reject(new Error("No serial ports detected."));
-            else resolve(ports.map(p => { return p.comName }));
-        });
-  });
-};

+ 71 - 0
back-end/serial_scanner.js

@@ -0,0 +1,71 @@
+"use strict";
+
+const serialport = require("serialport");
+const EventEmitter = require("events");
+
+module.exports = class SerialScanner extends EventEmitter {
+    /**
+     * Scans for ports and emits a "ports" event with an array of
+     */
+    scan() {
+        serialport.list(
+            (err, ports) => {
+                this._listWithCallback(err,ports, () => {
+                    this.ports = ports.map(this._portMap);
+                    this.emit("ports", this.ports);
+                });
+            }
+        )
+    }
+
+    checkForChanges(){
+        serialport.list(
+            (err, ports) => {
+                this._listWithCallback(err,ports, () => {
+                    let newPorts = ports.map(this._portMap);
+                    this.checkDeviceRemoved(newPorts);
+                    this.checkDeviceAdded(newPorts);
+                    this.ports = newPorts;
+                });
+            }
+        )
+    }
+
+    checkDeviceAdded(newPorts){
+        newPorts.forEach((newPort) => {
+            if(this.ports.indexOf(newPort) === - 1) {
+                this.emit("deviceAdded", newPort);
+            }
+        });
+    }
+
+    checkDeviceRemoved(newPorts) {
+        this.ports.forEach((oldPort) => {
+            if(newPorts.indexOf(oldPort) === - 1) {
+                this.emit("deviceRemoved", oldPort);
+            }
+        });
+    }
+
+    _emitError(err) {
+        this.emit("error", err);
+    }
+
+    _listWithCallback(err, ports, callback) {
+        if(err) {
+            this._emitError(err);
+        }
+        else if(ports.length === 0) {
+            this._emitError( new Error("No serial ports detected."));
+        }
+        else {
+            callback();
+        }
+    }
+
+    _portMap(port) {
+        return port.comName;
+    }
+
+
+};

+ 33 - 16
front-end/js/app.js

@@ -1,36 +1,43 @@
-const availableSerialPorts = require("../back-end/available_serial_ports");
+const SerialScanner = require("../back-end/serial_scanner");
 
 function $(id) { return document.getElementById(id) }
 
 const flashButton = $("flash-button");
 const appStatus = $("status");
 const portsSelect = $("ports");
+const serialScanner = new SerialScanner();
+const portToElementMap = {};
 var last_notification = "";
 
 flashButton.addEventListener("click", event => {
     var notification = new Notification("Flash Finished!");
 });
 
+serialScanner.on("ports", (ports) => {
+   addPortsToSelect(ports);
+   readyToFlash();
+});
 
-function checkPorts() {
-    availableSerialPorts()
-        .then(addPortsToSelect)
-        .then(readyToFlash)
-        .catch(onError);
+serialScanner.on("deviceAdded", (port ) => {
+    appendPortToSelect(port);
+    new Notification(`Added: ${port}`)
+});
 
-}
+serialScanner.on("deviceRemoved", (port ) => {
+    removePortFromSelect(port);
+    new Notification(`Removed: ${port}!`)
+});
+
+serialScanner.on("error", onError);
 
 /**
  * Removes existing comment, adds ports to the serial port SELECT element.
  * @param ports An Array of strings.
  */
 function addPortsToSelect(ports) {
-    //Gets currently selected
-    const previousValue = portsSelect.value;
     //Empty Select
-    portsSelect.innerHTML = "";
     ports.forEach(port => {
-        appendPortToSelect(port, previousValue)
+        appendPortToSelect(port);
     });
 }
 
@@ -38,12 +45,22 @@ function addPortsToSelect(ports) {
  * Appends a single port to the end of serial port SELECT element.
  * @param port
  */
-function appendPortToSelect(port, previousValue){
+function appendPortToSelect(port){
+    const option = createPortOption(port);
+    portToElementMap[port] = option;
+    portsSelect.appendChild(option);
+}
+
+function createPortOption(port) {
     const option = document.createElement("option");
     option.textContent = port;
     option.value = port;
-    option.selected = previousValue === port;
-    portsSelect.appendChild(option);
+    return option;
+}
+
+function removePortFromSelect(port) {
+    portsSelect.removeChild(portToElementMap[port]);
+    delete portToElementMap[port];
 }
 
 /**
@@ -78,8 +95,8 @@ function onError(error){
  * Sets up UI
  */
 function init() {
-    checkPorts();
-    setInterval(checkPorts, 1000);
+    serialScanner.scan();
+    setInterval(() =>{ serialScanner.checkForChanges(); }, 1000);
 }
 
 init();