Skip to content

Commit e77c972

Browse files
author
Akos Kitta
committed
init: programmers
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
1 parent 07692fe commit e77c972

File tree

10 files changed

+151
-64
lines changed

10 files changed

+151
-64
lines changed

arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { ColorContribution } from '@theia/core/lib/browser/color-application-con
3636
import { ColorRegistry } from '@theia/core/lib/browser/color-registry';
3737
import { ArduinoDaemon } from '../common/protocol/arduino-daemon';
3838
import { ConfigService } from '../common/protocol/config-service';
39-
import { BoardsConfigStore } from './boards/boards-config-store';
39+
import { BoardsDataStore } from './boards/boards-data-store';
4040
import { MainMenuManager } from '../common/main-menu-manager';
4141
import { FileSystemExt } from '../common/protocol/filesystem-ext';
4242
import { ArduinoMenus } from './menu/arduino-menus';
@@ -130,8 +130,8 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
130130
@inject(ConfigService)
131131
protected readonly configService: ConfigService;
132132

133-
@inject(BoardsConfigStore)
134-
protected readonly boardsConfigStore: BoardsConfigStore;
133+
@inject(BoardsDataStore)
134+
protected readonly boardsDataStore: BoardsDataStore;
135135

136136
@inject(MainMenuManager)
137137
protected readonly mainMenuManager: MainMenuManager;

arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ import {
8282
} from '@theia/core/lib/browser/connection-status-service';
8383
import { ConfigServiceClientImpl } from './config-service-client-impl';
8484
import { CoreServiceClientImpl } from './core-service-client-impl';
85-
import { BoardsDetailsMenuUpdater } from './boards/boards-details-menu-updater';
86-
import { BoardsConfigStore } from './boards/boards-config-store';
85+
import { BoardsDataMenuUpdater } from './boards/boards-details-menu-updater';
86+
import { BoardsDataStore } from './boards/boards-data-store';
8787
import { ILogger } from '@theia/core';
8888
import { FileSystemExt, FileSystemExtPath } from '../common/protocol/filesystem-ext';
8989
import { WorkspaceFrontendContribution as TheiaWorkspaceFrontendContribution, FileMenuContribution as TheiaFileMenuContribution } from '@theia/workspace/lib/browser';
@@ -183,9 +183,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
183183
}).inSingletonScope();
184184

185185
// To be able to track, and update the menu based on the core settings (aka. board details) of the currently selected board.
186-
bind(FrontendApplicationContribution).to(BoardsDetailsMenuUpdater).inSingletonScope();
187-
bind(BoardsConfigStore).toSelf().inSingletonScope();
188-
bind(FrontendApplicationContribution).toService(BoardsConfigStore);
186+
bind(FrontendApplicationContribution).to(BoardsDataMenuUpdater).inSingletonScope();
187+
bind(BoardsDataStore).toSelf().inSingletonScope();
188+
bind(FrontendApplicationContribution).toService(BoardsDataStore);
189189
// Logger for the Arduino daemon
190190
bind(ILogger).toDynamicValue(ctx => {
191191
const parentLogger = ctx.container.get<ILogger>(ILogger);

arduino-ide-extension/src/browser/boards/boards-config-store.ts renamed to arduino-ide-extension/src/browser/boards/boards-data-store.ts

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { injectable, inject, named } from 'inversify';
22
import { ILogger } from '@theia/core/lib/common/logger';
3+
import { deepClone } from '@theia/core/lib/common/objects';
34
import { MaybePromise } from '@theia/core/lib/common/types';
45
import { Event, Emitter } from '@theia/core/lib/common/event';
5-
import { deepClone, notEmpty } from '@theia/core/lib/common/objects';
66
import { FrontendApplicationContribution, LocalStorageService } from '@theia/core/lib/browser';
7-
import { BoardsService, ConfigOption, Installable, BoardDetails } from '../../common/protocol';
7+
import { notEmpty } from '../../common/utils';
88
import { BoardsServiceClientImpl } from './boards-service-client-impl';
9+
import { BoardsService, ConfigOption, Installable, BoardDetails, Programmer } from '../../common/protocol';
910

1011
@injectable()
11-
export class BoardsConfigStore implements FrontendApplicationContribution {
12+
export class BoardsDataStore implements FrontendApplicationContribution {
1213

1314
@inject(ILogger)
1415
@named('store')
@@ -60,39 +61,59 @@ export class BoardsConfigStore implements FrontendApplicationContribution {
6061
fqbn: string,
6162
boardsPackageVersion: MaybePromise<Installable.Version | undefined> = this.getBoardsPackageVersion(fqbn)): Promise<string> {
6263

63-
const configOptions = await this.getConfig(fqbn, boardsPackageVersion);
64+
const { configOptions } = await this.getData(fqbn, boardsPackageVersion);
6465
return ConfigOption.decorate(fqbn, configOptions);
6566
}
6667

67-
async getConfig(
68+
async getData(
6869
fqbn: string,
69-
boardsPackageVersion: MaybePromise<Installable.Version | undefined> = this.getBoardsPackageVersion(fqbn)): Promise<ConfigOption[]> {
70+
boardsPackageVersion: MaybePromise<Installable.Version | undefined> = this.getBoardsPackageVersion(fqbn)): Promise<BoardsDataStore.Data> {
7071

7172
const version = await boardsPackageVersion;
7273
if (!version) {
73-
return [];
74+
return BoardsDataStore.Data.EMPTY;
7475
}
7576
const key = this.getStorageKey(fqbn, version);
76-
let configOptions = await this.storageService.getData<ConfigOption[] | undefined>(key, undefined);
77-
if (configOptions) {
78-
return configOptions;
77+
let data = await this.storageService.getData<BoardsDataStore.Data | undefined>(key, undefined);
78+
if (data) {
79+
if (data.programmers !== undefined) { // to be backward compatible. We did not save the `programmers` into the `localStorage`.
80+
return data;
81+
}
7982
}
8083

81-
const details = await this.getBoardDetailsSafe(fqbn);
82-
if (!details) {
83-
return [];
84+
const boardDetails = await this.getBoardDetailsSafe(fqbn);
85+
if (!boardDetails) {
86+
return BoardsDataStore.Data.EMPTY;
8487
}
8588

86-
configOptions = details.configOptions;
87-
await this.storageService.setData(key, configOptions);
88-
return configOptions;
89+
data = { configOptions: boardDetails.configOptions, programmers: boardDetails.programmers };
90+
await this.storageService.setData(key, data);
91+
return data;
92+
}
93+
94+
async selectProgrammer(
95+
{ fqbn, programmer }: { fqbn: string, programmer: Programmer },
96+
boardsPackageVersion: MaybePromise<Installable.Version | undefined> = this.getBoardsPackageVersion(fqbn)): Promise<boolean> {
97+
98+
const { configOptions, programmers } = deepClone(await this.getData(fqbn, boardsPackageVersion));
99+
if (!programmers.find(p => Programmer.equals(programmer, p))) {
100+
return false;
101+
}
102+
103+
const version = await boardsPackageVersion;
104+
if (!version) {
105+
return false;
106+
}
107+
await this.setData({ fqbn, data: { configOptions, programmers }, version });
108+
this.fireChanged();
109+
return true;
89110
}
90111

91-
async setSelected(
112+
async selectConfigOption(
92113
{ fqbn, option, selectedValue }: { fqbn: string, option: string, selectedValue: string },
93114
boardsPackageVersion: MaybePromise<Installable.Version | undefined> = this.getBoardsPackageVersion(fqbn)): Promise<boolean> {
94115

95-
const configOptions = deepClone(await this.getConfig(fqbn, boardsPackageVersion));
116+
const { configOptions, programmers } = deepClone(await this.getData(fqbn, boardsPackageVersion));
96117
const configOption = configOptions.find(c => c.option === option);
97118
if (!configOption) {
98119
return false;
@@ -113,16 +134,16 @@ export class BoardsConfigStore implements FrontendApplicationContribution {
113134
if (!version) {
114135
return false;
115136
}
116-
await this.setConfig({ fqbn, configOptions, version });
137+
await this.setData({ fqbn, data: { configOptions, programmers }, version });
117138
this.fireChanged();
118139
return true;
119140
}
120141

121-
protected async setConfig(
122-
{ fqbn, configOptions, version }: { fqbn: string, configOptions: ConfigOption[], version: Installable.Version }): Promise<void> {
142+
protected async setData(
143+
{ fqbn, data, version }: { fqbn: string, data: BoardsDataStore.Data, version: Installable.Version }): Promise<void> {
123144

124145
const key = this.getStorageKey(fqbn, version);
125-
return this.storageService.setData(key, configOptions);
146+
return this.storageService.setData(key, data);
126147
}
127148

128149
protected getStorageKey(fqbn: string, version: Installable.Version): string {
@@ -159,3 +180,16 @@ export class BoardsConfigStore implements FrontendApplicationContribution {
159180
}
160181

161182
}
183+
184+
export namespace BoardsDataStore {
185+
export interface Data {
186+
readonly configOptions: ConfigOption[];
187+
readonly programmers: Programmer[];
188+
}
189+
export namespace Data {
190+
export const EMPTY: Data = {
191+
configOptions: [],
192+
programmers: []
193+
};
194+
}
195+
}

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposa
55
import { BoardsServiceClientImpl } from './boards-service-client-impl';
66
import { Board, ConfigOption } from '../../common/protocol';
77
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
8-
import { BoardsConfigStore } from './boards-config-store';
8+
import { BoardsDataStore } from './boards-data-store';
99
import { MainMenuManager } from '../../common/main-menu-manager';
1010
import { ArduinoMenus } from '../menu/arduino-menus';
1111

1212
@injectable()
13-
export class BoardsDetailsMenuUpdater implements FrontendApplicationContribution {
13+
export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
1414

1515
@inject(CommandRegistry)
1616
protected readonly commandRegistry: CommandRegistry;
@@ -21,16 +21,16 @@ export class BoardsDetailsMenuUpdater implements FrontendApplicationContribution
2121
@inject(MainMenuManager)
2222
protected readonly mainMenuManager: MainMenuManager;
2323

24-
@inject(BoardsConfigStore)
25-
protected readonly boardsConfigStore: BoardsConfigStore;
24+
@inject(BoardsDataStore)
25+
protected readonly boardsDataStore: BoardsDataStore;
2626

2727
@inject(BoardsServiceClientImpl)
2828
protected readonly boardsServiceClient: BoardsServiceClientImpl;
2929

3030
protected readonly toDisposeOnBoardChange = new DisposableCollection();
3131

3232
onStart(): void {
33-
this.boardsConfigStore.onChanged(() => this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard));
33+
this.boardsDataStore.onChanged(() => this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard));
3434
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) => this.updateMenuActions(selectedBoard));
3535
this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard);
3636
}
@@ -41,8 +41,8 @@ export class BoardsDetailsMenuUpdater implements FrontendApplicationContribution
4141
this.mainMenuManager.update();
4242
const { fqbn } = selectedBoard;
4343
if (fqbn) {
44-
const configOptions = await this.boardsConfigStore.getConfig(fqbn);
45-
const boardsConfigMenuPath = [...ArduinoMenus.TOOLS, 'z_boardsConfig']; // `z_` is for ordering.
44+
const { configOptions, programmers } = await this.boardsDataStore.getData(fqbn);
45+
const boardsConfigMenuPath = [...ArduinoMenus.TOOLS, 'z01_boardsConfig']; // `z_` is for ordering.
4646
for (const { label, option, values } of configOptions.sort(ConfigOption.LABEL_COMPARATOR)) {
4747
const menuPath = [...boardsConfigMenuPath, `${option}`];
4848
const commands = new Map<string, Disposable & { label: string }>()
@@ -51,7 +51,7 @@ export class BoardsDetailsMenuUpdater implements FrontendApplicationContribution
5151
const command = { id };
5252
const selectedValue = value.value;
5353
const handler = {
54-
execute: () => this.boardsConfigStore.setSelected({ fqbn, option, selectedValue }),
54+
execute: () => this.boardsDataStore.selectConfigOption({ fqbn, option, selectedValue }),
5555
isToggled: () => value.selected
5656
};
5757
commands.set(id, Object.assign(this.commandRegistry.registerCommand(command, handler), { label: value.label }));
@@ -67,6 +67,18 @@ export class BoardsDetailsMenuUpdater implements FrontendApplicationContribution
6767
})
6868
]);
6969
}
70+
const programmersMenuPath = [...ArduinoMenus.TOOLS, 'z02_programmers'];
71+
for (const programmer of programmers) {
72+
const { id, name } = programmer;
73+
const menuPath = [...programmersMenuPath, `${name}`];
74+
const command = { id: `${fqbn}-programmer--${id}` };
75+
const handler = { execute: () => this.boardsDataStore.selectProgrammer({ fqbn, programmer }) };
76+
this.menuRegistry.registerMenuAction(menuPath, { commandId: command.id, label: name });
77+
this.toDisposeOnBoardChange.pushAll([
78+
this.commandRegistry.registerCommand(command, handler),
79+
Disposable.create(() => this.menuRegistry.unregisterMenuAction(command, menuPath))
80+
]);
81+
}
7082
this.mainMenuManager.update();
7183
}
7284
}

arduino-ide-extension/src/browser/boards/quick-open/boards-quick-open-service.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
import { naturalCompare } from '../../../common/utils';
1818
import { BoardsService, Port, Board, ConfigOption, ConfigValue } from '../../../common/protocol';
1919
import { CoreServiceClientImpl } from '../../core-service-client-impl';
20-
import { BoardsConfigStore } from '../boards-config-store';
20+
import { BoardsDataStore } from '../boards-data-store';
2121
import { BoardsServiceClientImpl, AvailableBoard } from '../boards-service-client-impl';
2222

2323
@injectable()
@@ -41,8 +41,8 @@ export class BoardsQuickOpenService implements QuickOpenContribution, QuickOpenM
4141
@inject(BoardsServiceClientImpl)
4242
protected readonly boardsServiceClient: BoardsServiceClientImpl;
4343

44-
@inject(BoardsConfigStore)
45-
protected readonly configStore: BoardsConfigStore;
44+
@inject(BoardsDataStore)
45+
protected readonly boardsDataStore: BoardsDataStore;
4646

4747
@inject(CoreServiceClientImpl)
4848
protected coreServiceClient: CoreServiceClientImpl;
@@ -52,7 +52,7 @@ export class BoardsQuickOpenService implements QuickOpenContribution, QuickOpenM
5252
// Attached boards plus the user's config.
5353
protected availableBoards: AvailableBoard[] = [];
5454
// Only for the `selected` one from the `availableBoards`. Note: the `port` of the `selected` is optional.
55-
protected boardConfigs: ConfigOption[] = [];
55+
protected data: BoardsDataStore.Data = BoardsDataStore.Data.EMPTY;
5656
protected allBoards: Board.Detailed[] = []
5757
protected selectedBoard?: (AvailableBoard & { port: Port });
5858

@@ -86,7 +86,7 @@ export class BoardsQuickOpenService implements QuickOpenContribution, QuickOpenM
8686
placeholder += 'No board selected.';
8787
}
8888
placeholder += 'Type to filter boards';
89-
if (this.boardConfigs.length) {
89+
if (this.data.configOptions.length) {
9090
placeholder += ' or use the ↓↑ keys to adjust the board settings...';
9191
} else {
9292
placeholder += '...';
@@ -129,7 +129,7 @@ export class BoardsQuickOpenService implements QuickOpenContribution, QuickOpenM
129129

130130
// Show the config only if the `input` is empty.
131131
if (!lookFor.trim().length) {
132-
toAccept.push(...this.boardConfigs.map((config, i) => {
132+
toAccept.push(...this.data.configOptions.map((config, i) => {
133133
let group: QuickOpenGroupItemOptions | undefined = undefined;
134134
if (i === 0) {
135135
group = { groupLabel: 'Board Settings', showBorder: true };
@@ -157,14 +157,14 @@ export class BoardsQuickOpenService implements QuickOpenContribution, QuickOpenM
157157
protected async update(availableBoards: AvailableBoard[]): Promise<void> {
158158
// `selectedBoard` is not an attached board, we need to show the board settings for it (TODO: clarify!)
159159
const selectedBoard = availableBoards.filter(AvailableBoard.hasPort).find(({ selected }) => selected);
160-
const [configs, boards] = await Promise.all([
161-
selectedBoard && selectedBoard.fqbn ? this.configStore.getConfig(selectedBoard.fqbn) : Promise.resolve([]),
160+
const [data, boards] = await Promise.all([
161+
selectedBoard && selectedBoard.fqbn ? this.boardsDataStore.getData(selectedBoard.fqbn) : Promise.resolve(BoardsDataStore.Data.EMPTY),
162162
this.boardsService.allBoards({})
163163
]);
164164
this.allBoards = Board.decorateBoards(selectedBoard, boards)
165165
.filter(board => !availableBoards.some(availableBoard => Board.sameAs(availableBoard, board)));
166166
this.availableBoards = availableBoards;
167-
this.boardConfigs = configs;
167+
this.data = data;
168168
this.selectedBoard = selectedBoard;
169169

170170
if (this.isOpen) {
@@ -280,7 +280,7 @@ export class BoardsQuickOpenService implements QuickOpenContribution, QuickOpenM
280280
return;
281281
}
282282
const { fqbn } = this.selectedBoard;
283-
this.configStore.setSelected({
283+
this.boardsDataStore.selectConfigOption({
284284
fqbn,
285285
option: config.option,
286286
selectedValue: value.value

arduino-ide-extension/src/browser/contributions/upload-sketch.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { inject, injectable } from 'inversify';
22
import { CoreService } from '../../common/protocol';
33
import { MonitorConnection } from '../monitor/monitor-connection';
4-
import { BoardsConfigStore } from '../boards/boards-config-store';
4+
import { BoardsDataStore } from '../boards/boards-data-store';
55
import { BoardsServiceClientImpl } from '../boards/boards-service-client-impl';
66
import { ArduinoMenus } from '../menu/arduino-menus';
77
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
@@ -16,8 +16,8 @@ export class UploadSketch extends SketchContribution {
1616
@inject(MonitorConnection)
1717
protected readonly monitorConnection: MonitorConnection;
1818

19-
@inject(BoardsConfigStore)
20-
protected readonly boardsConfigStore: BoardsConfigStore;
19+
@inject(BoardsDataStore)
20+
protected readonly boardsDataStore: BoardsDataStore;
2121

2222
@inject(BoardsServiceClientImpl)
2323
protected readonly boardsServiceClientImpl: BoardsServiceClientImpl;
@@ -77,7 +77,7 @@ export class UploadSketch extends SketchContribution {
7777
if (!boardsConfig.selectedBoard.fqbn) {
7878
throw new Error(`No core is installed for the '${boardsConfig.selectedBoard.name}' board. Please install the core.`);
7979
}
80-
const fqbn = await this.boardsConfigStore.appendConfigToFqbn(boardsConfig.selectedBoard.fqbn);
80+
const fqbn = await this.boardsDataStore.appendConfigToFqbn(boardsConfig.selectedBoard.fqbn);
8181
await this.coreService.upload({
8282
sketchUri: sketch.uri,
8383
fqbn,

0 commit comments

Comments
 (0)