Skip to content

Commit f8331d9

Browse files
author
Akos Kitta
committed
init
Signed-off-by: Akos Kitta <[email protected]>
1 parent f22be3c commit f8331d9

21 files changed

+439
-379
lines changed

Diff for: arduino-ide-extension/src/browser/contributions/add-zip-library.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ import URI from '@theia/core/lib/common/uri';
44
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
55
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
66
import { ArduinoMenus } from '../menu/arduino-menus';
7-
import {
8-
Installable,
9-
LibraryService,
10-
ResponseServiceClient,
11-
} from '../../common/protocol';
7+
import { LibraryService, ResponseServiceClient } from '../../common/protocol';
8+
import { ExecuteWithProgress } from '../../common/progressible';
129
import {
1310
SketchContribution,
1411
Command,
@@ -88,7 +85,7 @@ export class AddZipLibrary extends SketchContribution {
8885

8986
private async doInstall(zipUri: string, overwrite?: boolean): Promise<void> {
9087
try {
91-
await Installable.doWithProgress({
88+
await ExecuteWithProgress.doWithProgress({
9289
messageService: this.messageService,
9390
progressText:
9491
nls.localize('arduino/common/processing', 'Processing') +

Diff for: arduino-ide-extension/src/browser/contributions/burn-bootloader.ts

+28-27
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import { nls } from '@theia/core/lib/common';
1313
@injectable()
1414
export class BurnBootloader extends CoreServiceContribution {
1515
@inject(BoardsDataStore)
16-
protected readonly boardsDataStore: BoardsDataStore;
16+
private readonly boardsDataStore: BoardsDataStore;
1717

1818
@inject(BoardsServiceProvider)
19-
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
19+
private readonly boardsServiceClientImpl: BoardsServiceProvider;
2020

2121
override registerCommands(registry: CommandRegistry): void {
2222
registry.registerCommand(BurnBootloader.Commands.BURN_BOOTLOADER, {
@@ -35,32 +35,33 @@ export class BurnBootloader extends CoreServiceContribution {
3535
});
3636
}
3737

38-
async burnBootloader(): Promise<void> {
38+
private async burnBootloader(): Promise<void> {
39+
const { boardsConfig } = this.boardsServiceClientImpl;
40+
const port = boardsConfig.selectedPort;
41+
const [fqbn, { selectedProgrammer: programmer }, verify, verbose] =
42+
await Promise.all([
43+
this.boardsDataStore.appendConfigToFqbn(
44+
boardsConfig.selectedBoard?.fqbn
45+
),
46+
this.boardsDataStore.getData(boardsConfig.selectedBoard?.fqbn),
47+
this.preferences.get('arduino.upload.verify'),
48+
this.preferences.get('arduino.upload.verbose'),
49+
]);
3950
try {
40-
const { boardsConfig } = this.boardsServiceClientImpl;
41-
const port = boardsConfig.selectedPort;
42-
const [fqbn, { selectedProgrammer: programmer }, verify, verbose] =
43-
await Promise.all([
44-
this.boardsDataStore.appendConfigToFqbn(
45-
boardsConfig.selectedBoard?.fqbn
46-
),
47-
this.boardsDataStore.getData(boardsConfig.selectedBoard?.fqbn),
48-
this.preferences.get('arduino.upload.verify'),
49-
this.preferences.get('arduino.upload.verbose'),
50-
]);
51-
52-
const board = {
53-
...boardsConfig.selectedBoard,
54-
name: boardsConfig.selectedBoard?.name || '',
55-
fqbn,
56-
};
57-
this.outputChannelManager.getChannel('Arduino').clear();
58-
await this.coreService.burnBootloader({
59-
board,
60-
programmer,
61-
port,
62-
verify,
63-
verbose,
51+
await this.doWithProgress({
52+
progressText: nls.localize(
53+
'arduino/bootloader/burningBootloader',
54+
'Burning bootloader...'
55+
),
56+
task: (progressId, coreService) =>
57+
coreService.burnBootloader({
58+
fqbn,
59+
programmer,
60+
port,
61+
verify,
62+
verbose,
63+
progressId,
64+
}),
6465
});
6566
this.messageService.info(
6667
nls.localize(

Diff for: arduino-ide-extension/src/browser/contributions/contribution.ts

+34-5
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ import {
4949
Sketch,
5050
CoreService,
5151
CoreError,
52+
ResponseServiceClient,
5253
} from '../../common/protocol';
5354
import { ArduinoPreferences } from '../arduino-preferences';
5455
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
5556
import { CoreErrorHandler } from './core-error-handler';
5657
import { nls } from '@theia/core';
5758
import { OutputChannelManager } from '../theia/output/output-channel';
5859
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
60+
import { ExecuteWithProgress } from '../../common/progressible';
5961

6062
export {
6163
Command,
@@ -167,16 +169,19 @@ export abstract class SketchContribution extends Contribution {
167169
}
168170

169171
@injectable()
170-
export class CoreServiceContribution extends SketchContribution {
171-
@inject(CoreService)
172-
protected readonly coreService: CoreService;
173-
172+
export abstract class CoreServiceContribution extends SketchContribution {
174173
@inject(CoreErrorHandler)
175-
protected readonly coreErrorHandler: CoreErrorHandler;
174+
protected readonly coreErrorHandler: CoreErrorHandler; // TODO: make this `private`.
175+
176+
@inject(CoreService)
177+
private readonly coreService: CoreService;
176178

177179
@inject(ClipboardService)
178180
private readonly clipboardService: ClipboardService;
179181

182+
@inject(ResponseServiceClient)
183+
private readonly responseService: ResponseServiceClient;
184+
180185
protected handleError(error: unknown): void {
181186
this.coreErrorHandler.tryHandle(error);
182187
this.tryToastErrorMessage(error);
@@ -214,6 +219,30 @@ export class CoreServiceContribution extends SketchContribution {
214219
throw error;
215220
}
216221
}
222+
223+
protected async doWithProgress<T>(options: {
224+
progressText: string;
225+
keepOutput?: boolean;
226+
task: (progressId: string, coreService: CoreService) => Promise<T>;
227+
}): Promise<T> {
228+
const { progressText, keepOutput, task } = options;
229+
if (!keepOutput) {
230+
this.resetOutput();
231+
}
232+
const result = await ExecuteWithProgress.doWithProgress({
233+
messageService: this.messageService,
234+
responseService: this.responseService,
235+
progressText,
236+
run: ({ progressId }) => task(progressId, this.coreService),
237+
});
238+
return result;
239+
}
240+
241+
private resetOutput(): void {
242+
const channel = this.outputChannelManager.getChannel('Arduino');
243+
channel.clear();
244+
channel.show({ preserveFocus: true });
245+
}
217246
}
218247

219248
export namespace Contribution {

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

+74-92
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,29 @@ import {
1616
import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog';
1717
import { DisposableCollection, nls } from '@theia/core/lib/common';
1818
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
19+
import { VerifySketch } from './verify-sketch';
1920

2021
@injectable()
2122
export class UploadSketch extends CoreServiceContribution {
2223
@inject(MenuModelRegistry)
23-
protected readonly menuRegistry: MenuModelRegistry;
24+
private readonly menuRegistry: MenuModelRegistry;
2425

2526
@inject(BoardsDataStore)
26-
protected readonly boardsDataStore: BoardsDataStore;
27+
private readonly boardsDataStore: BoardsDataStore;
2728

2829
@inject(BoardsServiceProvider)
29-
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
30+
private readonly boardsServiceClientImpl: BoardsServiceProvider;
3031

3132
@inject(UserFieldsDialog)
32-
protected readonly userFieldsDialog: UserFieldsDialog;
33+
private readonly userFieldsDialog: UserFieldsDialog;
3334

34-
protected cachedUserFields: Map<string, BoardUserField[]> = new Map();
35+
private boardRequiresUserFields = false;
36+
private readonly cachedUserFields: Map<string, BoardUserField[]> = new Map();
37+
private readonly menuActionsDisposables = new DisposableCollection();
3538

36-
protected readonly onDidChangeEmitter = new Emitter<Readonly<void>>();
37-
readonly onDidChange = this.onDidChangeEmitter.event;
38-
39-
protected uploadInProgress = false;
40-
protected boardRequiresUserFields = false;
41-
42-
protected readonly menuActionsDisposables = new DisposableCollection();
39+
private readonly onDidChangeEmitter = new Emitter<void>();
40+
private readonly onDidChange = this.onDidChangeEmitter.event;
41+
private uploadInProgress = false;
4342

4443
protected override init(): void {
4544
super.init();
@@ -130,7 +129,6 @@ export class UploadSketch extends CoreServiceContribution {
130129

131130
override registerMenus(registry: MenuModelRegistry): void {
132131
this.menuActionsDisposables.dispose();
133-
134132
this.menuActionsDisposables.push(
135133
registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, {
136134
commandId: UploadSketch.Commands.UPLOAD_SKETCH.id,
@@ -153,7 +151,7 @@ export class UploadSketch extends CoreServiceContribution {
153151
new PlaceholderMenuNode(
154152
ArduinoMenus.SKETCH__MAIN_GROUP,
155153
// commandId: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.id,
156-
UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.label!,
154+
UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.label,
157155
{ order: '2' }
158156
)
159157
)
@@ -193,13 +191,31 @@ export class UploadSketch extends CoreServiceContribution {
193191
}
194192

195193
async uploadSketch(usingProgrammer = false): Promise<void> {
196-
// even with buttons disabled, better to double check if an upload is already in progress
197194
if (this.uploadInProgress) {
198195
return;
199196
}
200197

201-
const sketch = await this.sketchServiceClient.currentSketch();
202-
if (!CurrentSketch.isValid(sketch)) {
198+
const ref = await this.commandService.executeCommand<VerifySketch.Ref>(
199+
VerifySketch.Commands.VERIFY_SKETCH.id,
200+
false
201+
);
202+
203+
if (!ref) {
204+
return;
205+
}
206+
207+
const options = await this.options(usingProgrammer, ref);
208+
if (!options) {
209+
return;
210+
}
211+
212+
if (options.userFields.length === 0 && this.boardRequiresUserFields) {
213+
this.messageService.error(
214+
nls.localize(
215+
'arduino/sketch/userFieldsNotFoundError',
216+
"Can't find user fields for connected board"
217+
)
218+
);
203219
return;
204220
}
205221

@@ -209,81 +225,14 @@ export class UploadSketch extends CoreServiceContribution {
209225
this.uploadInProgress = true;
210226
this.coreErrorHandler.reset();
211227
this.onDidChangeEmitter.fire();
212-
const { boardsConfig } = this.boardsServiceClientImpl;
213-
const [
214-
fqbn,
215-
{ selectedProgrammer },
216-
verify,
217-
uploadVerbose,
218-
sourceOverride,
219-
optimizeForDebug,
220-
compileVerbose,
221-
] = await Promise.all([
222-
this.boardsDataStore.appendConfigToFqbn(
223-
boardsConfig.selectedBoard?.fqbn
224-
),
225-
this.boardsDataStore.getData(boardsConfig.selectedBoard?.fqbn),
226-
this.preferences.get('arduino.upload.verify'),
227-
this.preferences.get('arduino.upload.verbose'),
228-
this.sourceOverride(),
229-
this.commandService.executeCommand<boolean>(
230-
'arduino-is-optimize-for-debug'
231-
),
232-
this.preferences.get('arduino.compile.verbose'),
233-
]);
234-
235-
const verbose = { compile: compileVerbose, upload: uploadVerbose };
236-
const board = {
237-
...boardsConfig.selectedBoard,
238-
name: boardsConfig.selectedBoard?.name || '',
239-
fqbn,
240-
};
241-
let options: CoreService.Upload.Options | undefined = undefined;
242-
const { selectedPort } = boardsConfig;
243-
const port = selectedPort;
244-
const userFields =
245-
this.cachedUserFields.get(this.selectedFqbnAddress()) ?? [];
246-
if (userFields.length === 0 && this.boardRequiresUserFields) {
247-
this.messageService.error(
248-
nls.localize(
249-
'arduino/sketch/userFieldsNotFoundError',
250-
"Can't find user fields for connected board"
251-
)
252-
);
253-
return;
254-
}
228+
await this.doWithProgress({
229+
progressText: nls.localize('arduino/sketch/uploading', 'Uploading...'),
230+
task: (progressId, coreService) => {
231+
return coreService.upload({ ...options, progressId });
232+
},
233+
keepOutput: true,
234+
});
255235

256-
if (usingProgrammer) {
257-
const programmer = selectedProgrammer;
258-
options = {
259-
sketch,
260-
board,
261-
optimizeForDebug: Boolean(optimizeForDebug),
262-
programmer,
263-
port,
264-
verbose,
265-
verify,
266-
sourceOverride,
267-
userFields,
268-
};
269-
} else {
270-
options = {
271-
sketch,
272-
board,
273-
optimizeForDebug: Boolean(optimizeForDebug),
274-
port,
275-
verbose,
276-
verify,
277-
sourceOverride,
278-
userFields,
279-
};
280-
}
281-
this.outputChannelManager.getChannel('Arduino').clear();
282-
if (usingProgrammer) {
283-
await this.coreService.uploadUsingProgrammer(options);
284-
} else {
285-
await this.coreService.upload(options);
286-
}
287236
this.messageService.info(
288237
nls.localize('arduino/sketch/doneUploading', 'Done uploading.'),
289238
{ timeout: 3000 }
@@ -295,14 +244,47 @@ export class UploadSketch extends CoreServiceContribution {
295244
this.onDidChangeEmitter.fire();
296245
}
297246
}
247+
248+
private async options(
249+
usingProgrammer: boolean,
250+
verifyRef: VerifySketch.Ref
251+
): Promise<CoreService.Options.Upload | undefined> {
252+
const sketch = await this.sketchServiceClient.currentSketch();
253+
if (!CurrentSketch.isValid(sketch)) {
254+
return undefined;
255+
}
256+
const userFields = this.userFields();
257+
const { boardsConfig } = this.boardsServiceClientImpl;
258+
const [fqbn, { selectedProgrammer: programmer }, verify, verbose] =
259+
await Promise.all([
260+
verifyRef.fqbn.decorated,
261+
this.boardsDataStore.getData(verifyRef.fqbn.original),
262+
this.preferences.get('arduino.upload.verify'),
263+
this.preferences.get('arduino.upload.verbose'),
264+
]);
265+
const port = boardsConfig.selectedPort;
266+
return {
267+
sketch,
268+
fqbn,
269+
...(usingProgrammer && { programmer }),
270+
port,
271+
verbose,
272+
verify,
273+
userFields,
274+
};
275+
}
276+
277+
private userFields() {
278+
return this.cachedUserFields.get(this.selectedFqbnAddress()) ?? [];
279+
}
298280
}
299281

300282
export namespace UploadSketch {
301283
export namespace Commands {
302284
export const UPLOAD_SKETCH: Command = {
303285
id: 'arduino-upload-sketch',
304286
};
305-
export const UPLOAD_WITH_CONFIGURATION: Command = {
287+
export const UPLOAD_WITH_CONFIGURATION: Command & { label: string } = {
306288
id: 'arduino-upload-with-configuration-sketch',
307289
label: nls.localize(
308290
'arduino/sketch/configureAndUpload',

0 commit comments

Comments
 (0)