From 3806d56e94e14d5bb81d234346cb32f5a5c4f4b8 Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Tue, 4 Aug 2020 15:07:16 +0200 Subject: [PATCH] queued the menu updates. Signed-off-by: Akos Kitta --- .../boards/boards-data-menu-updater.ts | 108 +++++++++--------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/arduino-ide-extension/src/browser/boards/boards-data-menu-updater.ts b/arduino-ide-extension/src/browser/boards/boards-data-menu-updater.ts index 3e6f524f..30169a3b 100644 --- a/arduino-ide-extension/src/browser/boards/boards-data-menu-updater.ts +++ b/arduino-ide-extension/src/browser/boards/boards-data-menu-updater.ts @@ -1,3 +1,4 @@ +import * as PQueue from 'p-queue'; import { inject, injectable } from 'inversify'; import { CommandRegistry } from '@theia/core/lib/common/command'; import { MenuModelRegistry, MenuNode } from '@theia/core/lib/common/menu'; @@ -27,71 +28,74 @@ export class BoardsDataMenuUpdater implements FrontendApplicationContribution { @inject(BoardsServiceClientImpl) protected readonly boardsServiceClient: BoardsServiceClientImpl; + protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 }); protected readonly toDisposeOnBoardChange = new DisposableCollection(); async onStart(): Promise { - await this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard); - this.boardsDataStore.onChanged(async () => await this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard)); - this.boardsServiceClient.onBoardsConfigChanged(async ({ selectedBoard }) => await this.updateMenuActions(selectedBoard)); + this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard); + this.boardsDataStore.onChanged(() => this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard)); + this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) => this.updateMenuActions(selectedBoard)); } protected async updateMenuActions(selectedBoard: Board | undefined): Promise { - if (selectedBoard) { + return this.queue.add(async () => { this.toDisposeOnBoardChange.dispose(); this.mainMenuManager.update(); - const { fqbn } = selectedBoard; - if (fqbn) { - const { configOptions, programmers, selectedProgrammer } = await this.boardsDataStore.getData(fqbn); - if (configOptions.length) { - const boardsConfigMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z01_boardsConfig']; // `z_` is for ordering. - for (const { label, option, values } of configOptions.sort(ConfigOption.LABEL_COMPARATOR)) { - const menuPath = [...boardsConfigMenuPath, `${option}`]; - const commands = new Map() - for (const value of values) { - const id = `${fqbn}-${option}--${value.value}`; - const command = { id }; - const selectedValue = value.value; - const handler = { - execute: () => this.boardsDataStore.selectConfigOption({ fqbn, option, selectedValue }), - isToggled: () => value.selected - }; - commands.set(id, Object.assign(this.commandRegistry.registerCommand(command, handler), { label: value.label })); + if (selectedBoard) { + const { fqbn } = selectedBoard; + if (fqbn) { + const { configOptions, programmers, selectedProgrammer } = await this.boardsDataStore.getData(fqbn); + if (configOptions.length) { + const boardsConfigMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z01_boardsConfig']; // `z_` is for ordering. + for (const { label, option, values } of configOptions.sort(ConfigOption.LABEL_COMPARATOR)) { + const menuPath = [...boardsConfigMenuPath, `${option}`]; + const commands = new Map() + for (const value of values) { + const id = `${fqbn}-${option}--${value.value}`; + const command = { id }; + const selectedValue = value.value; + const handler = { + execute: () => this.boardsDataStore.selectConfigOption({ fqbn, option, selectedValue }), + isToggled: () => value.selected + }; + commands.set(id, Object.assign(this.commandRegistry.registerCommand(command, handler), { label: value.label })); + } + this.menuRegistry.registerSubmenu(menuPath, label); + this.toDisposeOnBoardChange.pushAll([ + ...commands.values(), + Disposable.create(() => this.unregisterSubmenu(menuPath)), // We cannot dispose submenu entries: https://github.com/eclipse-theia/theia/issues/7299 + ...Array.from(commands.keys()).map((commandId, i) => { + const { label } = commands.get(commandId)!; + this.menuRegistry.registerMenuAction(menuPath, { commandId, order: `${i}`, label }); + return Disposable.create(() => this.menuRegistry.unregisterMenuAction(commandId)); + }) + ]); } - this.menuRegistry.registerSubmenu(menuPath, label); - this.toDisposeOnBoardChange.pushAll([ - ...commands.values(), - Disposable.create(() => this.unregisterSubmenu(menuPath)), // We cannot dispose submenu entries: https://github.com/eclipse-theia/theia/issues/7299 - ...Array.from(commands.keys()).map((commandId, i) => { - const { label } = commands.get(commandId)!; - this.menuRegistry.registerMenuAction(menuPath, { commandId, order: `${i}`, label }); - return Disposable.create(() => this.menuRegistry.unregisterMenuAction(commandId)); - }) - ]); } - } - if (programmers.length) { - const programmersMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z02_programmers']; - const label = selectedProgrammer ? `Programmer: "${selectedProgrammer.name}"` : 'Programmer' - this.menuRegistry.registerSubmenu(programmersMenuPath, label); - this.toDisposeOnBoardChange.push(Disposable.create(() => this.unregisterSubmenu(programmersMenuPath))); - for (const programmer of programmers) { - const { id, name } = programmer; - const command = { id: `${fqbn}-programmer--${id}` }; - const handler = { - execute: () => this.boardsDataStore.selectProgrammer({ fqbn, selectedProgrammer: programmer }), - isToggled: () => Programmer.equals(programmer, selectedProgrammer) - }; - this.menuRegistry.registerMenuAction(programmersMenuPath, { commandId: command.id, label: name }); - this.commandRegistry.registerCommand(command, handler); - this.toDisposeOnBoardChange.pushAll([ - Disposable.create(() => this.commandRegistry.unregisterCommand(command)), - Disposable.create(() => this.menuRegistry.unregisterMenuAction(command.id)) - ]); + if (programmers.length) { + const programmersMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z02_programmers']; + const label = selectedProgrammer ? `Programmer: "${selectedProgrammer.name}"` : 'Programmer' + this.menuRegistry.registerSubmenu(programmersMenuPath, label); + this.toDisposeOnBoardChange.push(Disposable.create(() => this.unregisterSubmenu(programmersMenuPath))); + for (const programmer of programmers) { + const { id, name } = programmer; + const command = { id: `${fqbn}-programmer--${id}` }; + const handler = { + execute: () => this.boardsDataStore.selectProgrammer({ fqbn, selectedProgrammer: programmer }), + isToggled: () => Programmer.equals(programmer, selectedProgrammer) + }; + this.menuRegistry.registerMenuAction(programmersMenuPath, { commandId: command.id, label: name }); + this.commandRegistry.registerCommand(command, handler); + this.toDisposeOnBoardChange.pushAll([ + Disposable.create(() => this.commandRegistry.unregisterCommand(command)), + Disposable.create(() => this.menuRegistry.unregisterMenuAction(command.id)) + ]); + } } + this.mainMenuManager.update(); } - this.mainMenuManager.update(); } - } + }); } protected unregisterSubmenu(menuPath: string[]): void {