Skip to content

Commit 3806d56

Browse files
author
Akos Kitta
committed
queued the menu updates.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
1 parent f0015e3 commit 3806d56

File tree

1 file changed

+55
-51
lines changed

1 file changed

+55
-51
lines changed

arduino-ide-extension/src/browser/boards/boards-data-menu-updater.ts

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as PQueue from 'p-queue';
12
import { inject, injectable } from 'inversify';
23
import { CommandRegistry } from '@theia/core/lib/common/command';
34
import { MenuModelRegistry, MenuNode } from '@theia/core/lib/common/menu';
@@ -27,71 +28,74 @@ export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
2728
@inject(BoardsServiceClientImpl)
2829
protected readonly boardsServiceClient: BoardsServiceClientImpl;
2930

31+
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
3032
protected readonly toDisposeOnBoardChange = new DisposableCollection();
3133

3234
async onStart(): Promise<void> {
33-
await this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard);
34-
this.boardsDataStore.onChanged(async () => await this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard));
35-
this.boardsServiceClient.onBoardsConfigChanged(async ({ selectedBoard }) => await this.updateMenuActions(selectedBoard));
35+
this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard);
36+
this.boardsDataStore.onChanged(() => this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard));
37+
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) => this.updateMenuActions(selectedBoard));
3638
}
3739

3840
protected async updateMenuActions(selectedBoard: Board | undefined): Promise<void> {
39-
if (selectedBoard) {
41+
return this.queue.add(async () => {
4042
this.toDisposeOnBoardChange.dispose();
4143
this.mainMenuManager.update();
42-
const { fqbn } = selectedBoard;
43-
if (fqbn) {
44-
const { configOptions, programmers, selectedProgrammer } = await this.boardsDataStore.getData(fqbn);
45-
if (configOptions.length) {
46-
const boardsConfigMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z01_boardsConfig']; // `z_` is for ordering.
47-
for (const { label, option, values } of configOptions.sort(ConfigOption.LABEL_COMPARATOR)) {
48-
const menuPath = [...boardsConfigMenuPath, `${option}`];
49-
const commands = new Map<string, Disposable & { label: string }>()
50-
for (const value of values) {
51-
const id = `${fqbn}-${option}--${value.value}`;
52-
const command = { id };
53-
const selectedValue = value.value;
44+
if (selectedBoard) {
45+
const { fqbn } = selectedBoard;
46+
if (fqbn) {
47+
const { configOptions, programmers, selectedProgrammer } = await this.boardsDataStore.getData(fqbn);
48+
if (configOptions.length) {
49+
const boardsConfigMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z01_boardsConfig']; // `z_` is for ordering.
50+
for (const { label, option, values } of configOptions.sort(ConfigOption.LABEL_COMPARATOR)) {
51+
const menuPath = [...boardsConfigMenuPath, `${option}`];
52+
const commands = new Map<string, Disposable & { label: string }>()
53+
for (const value of values) {
54+
const id = `${fqbn}-${option}--${value.value}`;
55+
const command = { id };
56+
const selectedValue = value.value;
57+
const handler = {
58+
execute: () => this.boardsDataStore.selectConfigOption({ fqbn, option, selectedValue }),
59+
isToggled: () => value.selected
60+
};
61+
commands.set(id, Object.assign(this.commandRegistry.registerCommand(command, handler), { label: value.label }));
62+
}
63+
this.menuRegistry.registerSubmenu(menuPath, label);
64+
this.toDisposeOnBoardChange.pushAll([
65+
...commands.values(),
66+
Disposable.create(() => this.unregisterSubmenu(menuPath)), // We cannot dispose submenu entries: https://github.com/eclipse-theia/theia/issues/7299
67+
...Array.from(commands.keys()).map((commandId, i) => {
68+
const { label } = commands.get(commandId)!;
69+
this.menuRegistry.registerMenuAction(menuPath, { commandId, order: `${i}`, label });
70+
return Disposable.create(() => this.menuRegistry.unregisterMenuAction(commandId));
71+
})
72+
]);
73+
}
74+
}
75+
if (programmers.length) {
76+
const programmersMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z02_programmers'];
77+
const label = selectedProgrammer ? `Programmer: "${selectedProgrammer.name}"` : 'Programmer'
78+
this.menuRegistry.registerSubmenu(programmersMenuPath, label);
79+
this.toDisposeOnBoardChange.push(Disposable.create(() => this.unregisterSubmenu(programmersMenuPath)));
80+
for (const programmer of programmers) {
81+
const { id, name } = programmer;
82+
const command = { id: `${fqbn}-programmer--${id}` };
5483
const handler = {
55-
execute: () => this.boardsDataStore.selectConfigOption({ fqbn, option, selectedValue }),
56-
isToggled: () => value.selected
84+
execute: () => this.boardsDataStore.selectProgrammer({ fqbn, selectedProgrammer: programmer }),
85+
isToggled: () => Programmer.equals(programmer, selectedProgrammer)
5786
};
58-
commands.set(id, Object.assign(this.commandRegistry.registerCommand(command, handler), { label: value.label }));
87+
this.menuRegistry.registerMenuAction(programmersMenuPath, { commandId: command.id, label: name });
88+
this.commandRegistry.registerCommand(command, handler);
89+
this.toDisposeOnBoardChange.pushAll([
90+
Disposable.create(() => this.commandRegistry.unregisterCommand(command)),
91+
Disposable.create(() => this.menuRegistry.unregisterMenuAction(command.id))
92+
]);
5993
}
60-
this.menuRegistry.registerSubmenu(menuPath, label);
61-
this.toDisposeOnBoardChange.pushAll([
62-
...commands.values(),
63-
Disposable.create(() => this.unregisterSubmenu(menuPath)), // We cannot dispose submenu entries: https://github.com/eclipse-theia/theia/issues/7299
64-
...Array.from(commands.keys()).map((commandId, i) => {
65-
const { label } = commands.get(commandId)!;
66-
this.menuRegistry.registerMenuAction(menuPath, { commandId, order: `${i}`, label });
67-
return Disposable.create(() => this.menuRegistry.unregisterMenuAction(commandId));
68-
})
69-
]);
7094
}
95+
this.mainMenuManager.update();
7196
}
72-
if (programmers.length) {
73-
const programmersMenuPath = [...ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, 'z02_programmers'];
74-
const label = selectedProgrammer ? `Programmer: "${selectedProgrammer.name}"` : 'Programmer'
75-
this.menuRegistry.registerSubmenu(programmersMenuPath, label);
76-
this.toDisposeOnBoardChange.push(Disposable.create(() => this.unregisterSubmenu(programmersMenuPath)));
77-
for (const programmer of programmers) {
78-
const { id, name } = programmer;
79-
const command = { id: `${fqbn}-programmer--${id}` };
80-
const handler = {
81-
execute: () => this.boardsDataStore.selectProgrammer({ fqbn, selectedProgrammer: programmer }),
82-
isToggled: () => Programmer.equals(programmer, selectedProgrammer)
83-
};
84-
this.menuRegistry.registerMenuAction(programmersMenuPath, { commandId: command.id, label: name });
85-
this.commandRegistry.registerCommand(command, handler);
86-
this.toDisposeOnBoardChange.pushAll([
87-
Disposable.create(() => this.commandRegistry.unregisterCommand(command)),
88-
Disposable.create(() => this.menuRegistry.unregisterMenuAction(command.id))
89-
]);
90-
}
91-
}
92-
this.mainMenuManager.update();
9397
}
94-
}
98+
});
9599
}
96100

97101
protected unregisterSubmenu(menuPath: string[]): void {

0 commit comments

Comments
 (0)