mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-08 11:56:36 +00:00
Implemented naive reconnecting.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
parent
2be54944bf
commit
8971dc4c5f
@ -137,7 +137,7 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
@inject(QuickOpenService)
|
@inject(QuickOpenService)
|
||||||
protected readonly quickOpenService: QuickOpenService;
|
protected readonly quickOpenService: QuickOpenService;
|
||||||
|
|
||||||
@inject(ArduinoWorkspaceService)
|
@inject(ArduinoWorkspaceService)
|
||||||
protected readonly workspaceService: ArduinoWorkspaceService;
|
protected readonly workspaceService: ArduinoWorkspaceService;
|
||||||
|
|
||||||
@inject(ConfigService)
|
@inject(ConfigService)
|
||||||
@ -164,6 +164,8 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
updateStatusBar(this.boardsServiceClient.boardsConfig);
|
updateStatusBar(this.boardsServiceClient.boardsConfig);
|
||||||
|
|
||||||
this.registerSketchesInMenu(this.menuRegistry);
|
this.registerSketchesInMenu(this.menuRegistry);
|
||||||
|
|
||||||
|
this.boardsService.getAttachedBoards().then(({ boards }) => this.boardsServiceClient.tryReconnect(boards));
|
||||||
}
|
}
|
||||||
|
|
||||||
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
registerToolbarItems(registry: TabBarToolbarRegistry): void {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import { injectable, inject, postConstruct } from 'inversify';
|
import { injectable, inject, postConstruct } from 'inversify';
|
||||||
import { Emitter, ILogger } from '@theia/core';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { BoardsServiceClient, AttachedBoardsChangeEvent, BoardInstalledEvent, AttachedSerialBoard } from '../../common/protocol/boards-service';
|
import { ILogger } from '@theia/core/lib/common/logger';
|
||||||
|
import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
|
||||||
|
import { RecursiveRequired } from '../../common/types';
|
||||||
|
import { BoardsServiceClient, AttachedBoardsChangeEvent, BoardInstalledEvent, AttachedSerialBoard, Board } from '../../common/protocol/boards-service';
|
||||||
import { BoardsConfig } from './boards-config';
|
import { BoardsConfig } from './boards-config';
|
||||||
import { LocalStorageService } from '@theia/core/lib/browser';
|
import { MaybePromise } from '@theia/core';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class BoardsServiceClientImpl implements BoardsServiceClient {
|
export class BoardsServiceClientImpl implements BoardsServiceClient {
|
||||||
@ -13,10 +16,18 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
|
|||||||
@inject(LocalStorageService)
|
@inject(LocalStorageService)
|
||||||
protected storageService: LocalStorageService;
|
protected storageService: LocalStorageService;
|
||||||
|
|
||||||
protected readonly onAttachedBoardsChangedEmitter = new Emitter<AttachedBoardsChangeEvent>();
|
|
||||||
protected readonly onBoardInstalledEmitter = new Emitter<BoardInstalledEvent>();
|
protected readonly onBoardInstalledEmitter = new Emitter<BoardInstalledEvent>();
|
||||||
|
protected readonly onAttachedBoardsChangedEmitter = new Emitter<AttachedBoardsChangeEvent>();
|
||||||
protected readonly onSelectedBoardsConfigChangedEmitter = new Emitter<BoardsConfig.Config>();
|
protected readonly onSelectedBoardsConfigChangedEmitter = new Emitter<BoardsConfig.Config>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for the auto-reconnecting. Sometimes, the attached board gets disconnected after uploading something to it.
|
||||||
|
* It happens with certain boards on Windows. For example, the `MKR1000` boards is selected on post `COM5` on Windows,
|
||||||
|
* perform an upload, the board automatically disconnects and reconnects, but on another port, `COM10`.
|
||||||
|
* We have to listen on such changes and auto-reconnect the same board on another port.
|
||||||
|
* See: https://arduino.slack.com/archives/CJJHJCJSJ/p1568645417013000?thread_ts=1568640504.009400&cid=CJJHJCJSJ
|
||||||
|
*/
|
||||||
|
protected latestValidBoardsConfig: RecursiveRequired<BoardsConfig.Config> | undefined = undefined;
|
||||||
protected _boardsConfig: BoardsConfig.Config = {};
|
protected _boardsConfig: BoardsConfig.Config = {};
|
||||||
|
|
||||||
readonly onBoardsChanged = this.onAttachedBoardsChangedEmitter.event;
|
readonly onBoardsChanged = this.onAttachedBoardsChangedEmitter.event;
|
||||||
@ -30,7 +41,8 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
|
|||||||
|
|
||||||
notifyAttachedBoardsChanged(event: AttachedBoardsChangeEvent): void {
|
notifyAttachedBoardsChanged(event: AttachedBoardsChangeEvent): void {
|
||||||
this.logger.info('Attached boards changed: ', JSON.stringify(event));
|
this.logger.info('Attached boards changed: ', JSON.stringify(event));
|
||||||
const detachedBoards = AttachedBoardsChangeEvent.diff(event).detached.filter(AttachedSerialBoard.is).map(({ port }) => port);
|
const { detached, attached } = AttachedBoardsChangeEvent.diff(event);
|
||||||
|
const detachedBoards = detached.filter(AttachedSerialBoard.is).map(({ port }) => port);
|
||||||
const { selectedPort, selectedBoard } = this.boardsConfig;
|
const { selectedPort, selectedBoard } = this.boardsConfig;
|
||||||
this.onAttachedBoardsChangedEmitter.fire(event);
|
this.onAttachedBoardsChangedEmitter.fire(event);
|
||||||
// Dynamically unset the port if the selected board was an attached one and we detached it.
|
// Dynamically unset the port if the selected board was an attached one and we detached it.
|
||||||
@ -40,6 +52,37 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
|
|||||||
selectedPort: undefined
|
selectedPort: undefined
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// Try to reconnect.
|
||||||
|
this.tryReconnect(attached);
|
||||||
|
}
|
||||||
|
|
||||||
|
async tryReconnect(attachedBoards: MaybePromise<Array<Board>>): Promise<boolean> {
|
||||||
|
const boards = await attachedBoards;
|
||||||
|
if (this.latestValidBoardsConfig && !this.canUploadTo(this.boardsConfig)) {
|
||||||
|
for (const board of boards.filter(AttachedSerialBoard.is)) {
|
||||||
|
if (this.latestValidBoardsConfig.selectedBoard.fqbn === board.fqbn
|
||||||
|
&& this.latestValidBoardsConfig.selectedBoard.name === board.name
|
||||||
|
&& this.latestValidBoardsConfig.selectedPort === board.port) {
|
||||||
|
|
||||||
|
this.boardsConfig = this.latestValidBoardsConfig;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we could not find an exact match, we compare the board FQBN-name pairs and ignore the port, as it might have changed.
|
||||||
|
// See documentation on `latestValidBoardsConfig`.
|
||||||
|
for (const board of boards.filter(AttachedSerialBoard.is)) {
|
||||||
|
if (this.latestValidBoardsConfig.selectedBoard.fqbn === board.fqbn
|
||||||
|
&& this.latestValidBoardsConfig.selectedBoard.name === board.name) {
|
||||||
|
|
||||||
|
this.boardsConfig = {
|
||||||
|
...this.latestValidBoardsConfig,
|
||||||
|
selectedPort: board.port
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyBoardInstalled(event: BoardInstalledEvent): void {
|
notifyBoardInstalled(event: BoardInstalledEvent): void {
|
||||||
@ -50,6 +93,9 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
|
|||||||
set boardsConfig(config: BoardsConfig.Config) {
|
set boardsConfig(config: BoardsConfig.Config) {
|
||||||
this.logger.info('Board config changed: ', JSON.stringify(config));
|
this.logger.info('Board config changed: ', JSON.stringify(config));
|
||||||
this._boardsConfig = config;
|
this._boardsConfig = config;
|
||||||
|
if (this.canUploadTo(this._boardsConfig)) {
|
||||||
|
this.latestValidBoardsConfig = this._boardsConfig;
|
||||||
|
}
|
||||||
this.saveState().then(() => this.onSelectedBoardsConfigChangedEmitter.fire(this._boardsConfig));
|
this.saveState().then(() => this.onSelectedBoardsConfigChangedEmitter.fire(this._boardsConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,14 +104,22 @@ export class BoardsServiceClientImpl implements BoardsServiceClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected saveState(): Promise<void> {
|
protected saveState(): Promise<void> {
|
||||||
return this.storageService.setData('boards-config', this.boardsConfig);
|
return this.storageService.setData('latest-valid-boards-config', this.latestValidBoardsConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async loadState(): Promise<void> {
|
protected async loadState(): Promise<void> {
|
||||||
const boardsConfig = await this.storageService.getData<BoardsConfig.Config>('boards-config');
|
const storedValidBoardsConfig = await this.storageService.getData<RecursiveRequired<BoardsConfig.Config>>('latest-valid-boards-config');
|
||||||
if (boardsConfig) {
|
if (storedValidBoardsConfig) {
|
||||||
this.boardsConfig = boardsConfig;
|
this.latestValidBoardsConfig = storedValidBoardsConfig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected canVerify(config: BoardsConfig.Config | undefined): config is BoardsConfig.Config & { selectedBoard: Board } {
|
||||||
|
return !!config && !!config.selectedBoard;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected canUploadTo(config: BoardsConfig.Config | undefined): config is RecursiveRequired<BoardsConfig.Config> {
|
||||||
|
return this.canVerify(config) && !!config.selectedPort && !!config.selectedBoard.fqbn;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
3
arduino-ide-extension/src/common/types.ts
Normal file
3
arduino-ide-extension/src/common/types.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export type RecursiveRequired<T> = {
|
||||||
|
[P in keyof T]-?: RecursiveRequired<T[P]>;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user