From 3de9181687aeb42aaf8687efa2aa4e46457efca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Kiss?= Date: Sat, 9 Dec 2017 16:11:03 +0100 Subject: [PATCH] feat(device): Ensure serial the device communication (#508) --- packages/uhk-agent/src/models/queue-entry.ts | 6 +++ .../uhk-agent/src/services/device.service.ts | 44 +++++++++++++++---- .../uhk-agent/src/services/queue-manager.ts | 30 +++++++++++++ 3 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 packages/uhk-agent/src/models/queue-entry.ts create mode 100644 packages/uhk-agent/src/services/queue-manager.ts diff --git a/packages/uhk-agent/src/models/queue-entry.ts b/packages/uhk-agent/src/models/queue-entry.ts new file mode 100644 index 00000000..6f9df70b --- /dev/null +++ b/packages/uhk-agent/src/models/queue-entry.ts @@ -0,0 +1,6 @@ +export interface QueueEntry { + method: Function; + bind: any; + params?: any[]; + asynchronous?: boolean; +} diff --git a/packages/uhk-agent/src/services/device.service.ts b/packages/uhk-agent/src/services/device.service.ts index b75f323f..5c9d8bb3 100644 --- a/packages/uhk-agent/src/services/device.service.ts +++ b/packages/uhk-agent/src/services/device.service.ts @@ -24,6 +24,7 @@ import 'rxjs/add/operator/distinctUntilChanged'; import { saveTmpFirmware } from '../util/save-extract-firmware'; import { TmpFirmware } from '../models/tmp-firmware'; +import { QueueManager } from './queue-manager'; /** * IpcMain pair of the UHK Communication @@ -35,16 +36,43 @@ import { TmpFirmware } from '../models/tmp-firmware'; export class DeviceService { private pollTimer$: Subscription; private connected = false; + private queueManager = new QueueManager(); constructor(private logService: LogService, private win: Electron.BrowserWindow, private device: UhkHidDevice, private operations: UhkOperations) { this.pollUhkDevice(); - ipcMain.on(IpcEvents.device.saveUserConfiguration, this.saveUserConfiguration.bind(this)); - ipcMain.on(IpcEvents.device.loadConfigurations, this.loadConfigurations.bind(this)); - ipcMain.on(IpcEvents.device.updateFirmware, this.updateFirmware.bind(this)); + + ipcMain.on(IpcEvents.device.saveUserConfiguration, (...args: any[]) => { + this.queueManager.add({ + method: this.saveUserConfiguration, + bind: this, + params: args, + asynchronous: true + }); + }); + + ipcMain.on(IpcEvents.device.loadConfigurations, (...args: any[]) => { + this.queueManager.add({ + method: this.loadConfigurations, + bind: this, + params: args, + asynchronous: true + }); + }); + + ipcMain.on(IpcEvents.device.updateFirmware, (...args: any[]) => { + this.queueManager.add({ + method: this.updateFirmware, + bind: this, + params: args, + asynchronous: true + }); + }); + ipcMain.on(IpcEvents.device.startConnectionPoller, this.pollUhkDevice.bind(this)); + logService.debug('[DeviceService] init success'); } @@ -144,16 +172,15 @@ export class DeviceService { this.logService.info('[DeviceService] Device connection checker stopped.'); } - public async updateFirmware(event: Electron.Event, data?: string): Promise { + public async updateFirmware(event: Electron.Event, args?: Array): Promise { const response = new IpcResponse(); - let firmwarePathData: TmpFirmware; try { this.stopPollTimer(); - if (data && data.length > 0) { - firmwarePathData = await saveTmpFirmware(data); + if (args && args.length > 0) { + firmwarePathData = await saveTmpFirmware(args[0]); await this.operations.updateRightFirmware(firmwarePathData.rightFirmwarePath); await this.operations.updateLeftModule(firmwarePathData.leftFirmwarePath); } @@ -216,8 +243,9 @@ export class DeviceService { return configSize; } - private async saveUserConfiguration(event: Electron.Event, json: string): Promise { + private async saveUserConfiguration(event: Electron.Event, args: Array): Promise { const response = new IpcResponse(); + const json = args[0]; try { this.logService.debug('[DeviceService] USB[T]: Write user configuration to keyboard'); diff --git a/packages/uhk-agent/src/services/queue-manager.ts b/packages/uhk-agent/src/services/queue-manager.ts new file mode 100644 index 00000000..0f3c3add --- /dev/null +++ b/packages/uhk-agent/src/services/queue-manager.ts @@ -0,0 +1,30 @@ +import { QueueEntry } from '../models/queue-entry'; + +export class QueueManager { + private _queue: QueueEntry[] = []; + private _processing = false; + + async add(entry: QueueEntry): Promise { + this._queue.push(entry); + this.process(); + } + + private async process(): Promise { + if (this._processing) { + return; + } + + this._processing = true; + + while (this._queue.length !== 0) { + const entry = this._queue.splice(0, 1)[0]; + if (entry.asynchronous) { + await entry.method.apply(entry.bind, entry.params); + } else { + entry.method.apply(entry.bind, entry.params); + } + } + + this._processing = false; + } +}