mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-16 15:56:34 +00:00
Implemented non-attached boards
This commit is contained in:
parent
d787de3ed9
commit
be20365a6b
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -12,6 +12,7 @@ import { ConnectedBoards } from './components/connected-boards';
|
||||
import { CoreService } from '../common/protocol/core-service';
|
||||
import { WorkspaceServiceExt } from './workspace-service-ext';
|
||||
import { ToolOutputServiceClient } from '../common/protocol/tool-output-service';
|
||||
import { ConfirmDialog } from '@theia/core/lib/browser';
|
||||
|
||||
|
||||
@injectable()
|
||||
@ -65,6 +66,10 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr
|
||||
isVisible: widget => this.isArduinoEditor(widget),
|
||||
isEnabled: widget => this.isArduinoEditor(widget),
|
||||
execute: async widget => {
|
||||
if (widget instanceof EditorWidget) {
|
||||
await widget.saveable.save();
|
||||
}
|
||||
|
||||
const uri = this.toUri(widget);
|
||||
if (uri) {
|
||||
const result = await this.coreService.compile({ uri: uri.toString() });
|
||||
@ -76,10 +81,19 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr
|
||||
isVisible: widget => this.isArduinoEditor(widget),
|
||||
isEnabled: widget => this.isArduinoEditor(widget),
|
||||
execute: async widget => {
|
||||
if (widget instanceof EditorWidget) {
|
||||
await widget.saveable.save();
|
||||
}
|
||||
|
||||
const uri = this.toUri(widget);
|
||||
if (uri) {
|
||||
const result = await this.coreService.upload({ uri: uri.toString() });
|
||||
console.log('upload result', result);
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.coreService.upload({ uri: uri.toString() });
|
||||
} catch (e) {
|
||||
new ConfirmDialog({ title: "Error during upload", msg: e.toString(), ok: "Ok" }).open();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,7 +1,6 @@
|
||||
import * as React from 'react';
|
||||
// TODO: make this `async`.
|
||||
// import { Async } from 'react-select/lib/Async';
|
||||
import { BoardsService, AttachedBoard } from '../../common/protocol/boards-service';
|
||||
import { BoardsService, Board } from '../../common/protocol/boards-service';
|
||||
import { SelectBoardDialog } from './select-board-dialog';
|
||||
|
||||
export class ConnectedBoards extends React.Component<ConnectedBoards.Props, ConnectedBoards.State> {
|
||||
static TOOLBAR_ID: 'connected-boards-toolbar';
|
||||
@ -12,23 +11,28 @@ export class ConnectedBoards extends React.Component<ConnectedBoards.Props, Conn
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
let label = "no board available";
|
||||
if (this.state.boardsLoading) {
|
||||
label = "Loading ...";
|
||||
} else if (!!this.state.current) {
|
||||
label = this.state.current.name;
|
||||
}
|
||||
|
||||
let content = [];
|
||||
if (!!this.state.boards) {
|
||||
if (!!this.state.boards && this.state.boards.length > 0) {
|
||||
content = this.state.boards.map((b, i) => <option value={i} key={i}>{b.name}</option>);
|
||||
} else {
|
||||
let label;
|
||||
if (this.state.boardsLoading) {
|
||||
label = "Loading ...";
|
||||
} else {
|
||||
label = "No board attached";
|
||||
}
|
||||
content = [ <option key="loading" value="0">{label}</option> ];
|
||||
}
|
||||
|
||||
return <div className={ConnectedBoards.Styles.CONNECTED_BOARDS_CLASS}>
|
||||
<select disabled={!this.state.boards} onChange={this.onBoardSelect.bind(this)}>
|
||||
<select disabled={!this.state.boards} onChange={this.onBoardSelect.bind(this)} value={this.state.selection}>
|
||||
<optgroup label="Attached boards">
|
||||
{ content }
|
||||
</optgroup>
|
||||
<optgroup label="_________">
|
||||
{ !!this.state.otherBoard && <option value="selected-other" key="selected-other">{this.state.otherBoard.name} (not attached)</option> }
|
||||
<option value="select-other" key="select-other">Select other Board</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>;
|
||||
}
|
||||
@ -38,26 +42,38 @@ export class ConnectedBoards extends React.Component<ConnectedBoards.Props, Conn
|
||||
}
|
||||
|
||||
protected async reloadBoards() {
|
||||
this.setState({ boardsLoading: true, boards: undefined, current: undefined });
|
||||
this.setState({ boardsLoading: true, boards: undefined, selection: undefined });
|
||||
const { boards } = await this.props.boardsService.getAttachedBoards()
|
||||
this.setState({ boards, boardsLoading: false });
|
||||
|
||||
if (boards) {
|
||||
this.selectBoard(boards[0]);
|
||||
this.setState({ selection: "0" });
|
||||
await this.props.boardsService.selectBoard(boards[0]);
|
||||
}
|
||||
}
|
||||
|
||||
protected async onBoardSelect(evt: React.ChangeEvent<HTMLSelectElement>) {
|
||||
const selectedBoard = (this.state.boards || [])[parseInt(evt.target.value, 10)];
|
||||
const selection = evt.target.value;
|
||||
if (selection === "select-other" || selection === "selected-other") {
|
||||
let selectedBoard = this.state.otherBoard;
|
||||
if (selection === "select-other" || !selectedBoard) {
|
||||
selectedBoard = await new SelectBoardDialog(this.props.boardsService).open();
|
||||
}
|
||||
if (!selectedBoard) {
|
||||
return;
|
||||
}
|
||||
this.selectBoard(selectedBoard);
|
||||
|
||||
await this.props.boardsService.selectBoard(selectedBoard);
|
||||
this.setState({otherBoard: selectedBoard, selection: "selected-other"});
|
||||
return;
|
||||
}
|
||||
|
||||
protected async selectBoard(board: AttachedBoard) {
|
||||
await this.props.boardsService.selectBoard(board);
|
||||
this.setState({ current: board });
|
||||
const selectedBoard = (this.state.boards || [])[parseInt(selection, 10)];
|
||||
if (!selectedBoard) {
|
||||
return;
|
||||
}
|
||||
await this.props.boardsService.selectBoard(selectedBoard);
|
||||
this.setState({selection});
|
||||
}
|
||||
|
||||
}
|
||||
@ -70,8 +86,9 @@ export namespace ConnectedBoards {
|
||||
|
||||
export interface State {
|
||||
boardsLoading: boolean;
|
||||
boards?: AttachedBoard[];
|
||||
current?: AttachedBoard;
|
||||
boards?: Board[];
|
||||
otherBoard?: Board;
|
||||
selection?: string;
|
||||
}
|
||||
|
||||
export namespace Styles {
|
||||
|
@ -0,0 +1,103 @@
|
||||
import { AbstractDialog, ReactRenderer, Message } from "@theia/core/lib/browser";
|
||||
import { Board, BoardsService } from "../../common/protocol/boards-service";
|
||||
import * as React from 'react';
|
||||
|
||||
interface BoardGroup {
|
||||
name: string
|
||||
boards: Board[]
|
||||
}
|
||||
|
||||
class DialogContentRenderer extends ReactRenderer {
|
||||
protected availableBoards: BoardGroup[] = [ ];
|
||||
protected searchTerm = "";
|
||||
|
||||
constructor(protected readonly boardsService: BoardsService, protected readonly onSelect: (b: Board) => void) {
|
||||
super();
|
||||
this.search();
|
||||
}
|
||||
|
||||
doRender(): React.ReactNode {
|
||||
return <React.Fragment>
|
||||
<input type="text" placeholder="Search ..." onChange={this.onSearchChange.bind(this)} value={this.searchTerm} />
|
||||
<select size={10} onChange={this.onChange.bind(this)}>
|
||||
{ this.availableBoards.map((b, i) => (
|
||||
<optgroup key={"pkg" + i} label={b.name}>
|
||||
{ b.boards.map((brd, j) => <option key={j} value={`${i}::${j}`}>{brd.name}</option>) }
|
||||
</optgroup>
|
||||
)) }
|
||||
</select>
|
||||
</React.Fragment>;
|
||||
}
|
||||
|
||||
protected onChange(evt: React.ChangeEvent<HTMLSelectElement>) {
|
||||
const [grp, brd] = evt.target.value.split("::");
|
||||
|
||||
const grpidx = parseInt(grp, 10);
|
||||
const brdidx = parseInt(brd, 10);
|
||||
|
||||
const board = this.availableBoards[grpidx].boards[brdidx];
|
||||
this.onSelect(board);
|
||||
}
|
||||
|
||||
protected onSearchChange(evt: React.ChangeEvent<HTMLInputElement>) {
|
||||
this.searchTerm = evt.target.value;
|
||||
this.search();
|
||||
}
|
||||
|
||||
protected async search() {
|
||||
const { items } = await this.boardsService.search({query: this.searchTerm });
|
||||
this.availableBoards = items.map(pkg => {
|
||||
const result: BoardGroup = {
|
||||
name: pkg.name,
|
||||
boards: pkg.boards.filter(b => b.name.toLocaleLowerCase().includes(this.searchTerm.toLocaleLowerCase()))
|
||||
}
|
||||
return result;
|
||||
}).filter(grp => !!grp.boards).sort((a, b) => {
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name === b.name) return 0;
|
||||
return 1;
|
||||
});
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class SelectBoardDialog extends AbstractDialog<Board> {
|
||||
protected result: Board;
|
||||
protected readonly contentRenderer: DialogContentRenderer;
|
||||
|
||||
constructor(boardsService: BoardsService) {
|
||||
super({ title: 'Select other board' });
|
||||
|
||||
this.contentNode.classList.add(SelectBoardDialog.Styles.DIALOG_CLASS);
|
||||
this.contentRenderer = new DialogContentRenderer(boardsService, b => this.result = b);
|
||||
this.contentRenderer.render();
|
||||
this.contentNode.appendChild(this.contentRenderer.host);
|
||||
|
||||
this.appendCloseButton();
|
||||
this.appendAcceptButton("Select");
|
||||
}
|
||||
|
||||
get value(): Board {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
onUpdateRequest(msg: Message) {
|
||||
super.onUpdateRequest(msg);
|
||||
this.contentRenderer.render();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.contentRenderer.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace SelectBoardDialog {
|
||||
export namespace Styles {
|
||||
export const DIALOG_CLASS = "select-board-dialog";
|
||||
export const SELECTOR_CLASS = "selector";
|
||||
}
|
||||
}
|
@ -1 +1,2 @@
|
||||
@import './list-widget.css';
|
||||
@import './select-board-dialog.css';
|
@ -0,0 +1,13 @@
|
||||
|
||||
.select-board-dialog {
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.select-board-dialog input {
|
||||
width: calc(100% - 8px);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.select-board-dialog select {
|
||||
width: 100%;
|
||||
}
|
@ -3,24 +3,25 @@ import { ArduinoComponent } from "./arduino-component";
|
||||
export const BoardsServicePath = '/services/boards-service';
|
||||
export const BoardsService = Symbol('BoardsService');
|
||||
export interface BoardsService {
|
||||
getAttachedBoards(): Promise<{ boards: AttachedBoard[] }>;
|
||||
selectBoard(board: AttachedBoard): Promise<void>;
|
||||
getSelectBoard(): Promise<AttachedBoard | undefined>;
|
||||
getAttachedBoards(): Promise<{ boards: Board[] }>;
|
||||
selectBoard(board: Board): Promise<void>;
|
||||
getSelectBoard(): Promise<Board | undefined>;
|
||||
|
||||
search(options: { query?: string }): Promise<{ items: Board[] }>;
|
||||
install(board: Board): Promise<void>;
|
||||
search(options: { query?: string }): Promise<{ items: BoardPackage[] }>;
|
||||
install(item: BoardPackage): Promise<void>;
|
||||
}
|
||||
|
||||
export interface Board extends ArduinoComponent {
|
||||
export interface BoardPackage extends ArduinoComponent {
|
||||
id: string;
|
||||
boards: Board[];
|
||||
}
|
||||
|
||||
export interface AttachedBoard {
|
||||
export interface Board {
|
||||
name: string
|
||||
fqbn?: string
|
||||
}
|
||||
|
||||
export interface AttachedSerialBoard extends AttachedBoard {
|
||||
export interface AttachedSerialBoard extends Board {
|
||||
port: string;
|
||||
serialNumber: string;
|
||||
productID: string;
|
||||
@ -28,7 +29,7 @@ export interface AttachedSerialBoard extends AttachedBoard {
|
||||
}
|
||||
|
||||
export namespace AttachedSerialBoard {
|
||||
export function is(b: AttachedBoard): b is AttachedSerialBoard {
|
||||
export function is(b: Board): b is AttachedSerialBoard {
|
||||
return 'port' in b
|
||||
&& 'serialNumber' in b
|
||||
&& 'productID' in b
|
||||
@ -36,14 +37,14 @@ export namespace AttachedSerialBoard {
|
||||
}
|
||||
}
|
||||
|
||||
export interface AttachedNetworkBoard extends AttachedBoard {
|
||||
export interface AttachedNetworkBoard extends Board {
|
||||
info: string;
|
||||
address: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
export namespace AttachedNetworkBoard {
|
||||
export function is(b: AttachedBoard): b is AttachedNetworkBoard {
|
||||
export function is(b: Board): b is AttachedNetworkBoard {
|
||||
return 'name' in b
|
||||
&& 'info' in b
|
||||
&& 'address' in b
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { BoardsService, Board, AttachedBoard, AttachedSerialBoard, AttachedNetworkBoard } from '../common/protocol/boards-service';
|
||||
import { BoardsService, AttachedSerialBoard, AttachedNetworkBoard, BoardPackage, Board } from '../common/protocol/boards-service';
|
||||
import { PlatformSearchReq, PlatformSearchResp, PlatformInstallReq, PlatformInstallResp, PlatformListReq, PlatformListResp } from './cli-protocol/core_pb';
|
||||
import { CoreClientProvider } from './core-client-provider';
|
||||
import { BoardListReq, BoardListResp } from './cli-protocol/board_pb';
|
||||
@ -10,16 +10,16 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
@inject(CoreClientProvider)
|
||||
protected readonly coreClientProvider: CoreClientProvider;
|
||||
|
||||
protected selectedBoard: AttachedBoard | undefined;
|
||||
protected selectedBoard: Board | undefined;
|
||||
|
||||
public async getAttachedBoards(): Promise<{ boards: AttachedBoard[] }> {
|
||||
public async getAttachedBoards(): Promise<{ boards: Board[] }> {
|
||||
const { client, instance } = await this.coreClientProvider.getClient();
|
||||
|
||||
const req = new BoardListReq();
|
||||
req.setInstance(instance);
|
||||
const resp = await new Promise<BoardListResp>((resolve, reject) => client.boardList(req, (err, resp) => (!!err ? reject : resolve)(!!err ? err : resp)));
|
||||
|
||||
const serialBoards: AttachedBoard[] = resp.getSerialList().map(b => <AttachedSerialBoard>{
|
||||
const serialBoards: Board[] = resp.getSerialList().map(b => <AttachedSerialBoard>{
|
||||
name: b.getName() || "unknown",
|
||||
fqbn: b.getFqbn(),
|
||||
port: b.getPort(),
|
||||
@ -27,7 +27,7 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
productID: b.getProductid(),
|
||||
vendorID: b.getVendorid()
|
||||
});
|
||||
const networkBoards: AttachedBoard[] = resp.getNetworkList().map(b => <AttachedNetworkBoard>{
|
||||
const networkBoards: Board[] = resp.getNetworkList().map(b => <AttachedNetworkBoard>{
|
||||
name: b.getName(),
|
||||
fqbn: b.getFqbn(),
|
||||
address: b.getAddress(),
|
||||
@ -38,15 +38,15 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
return { boards: serialBoards.concat(networkBoards) };
|
||||
}
|
||||
|
||||
async selectBoard(board: AttachedBoard): Promise<void> {
|
||||
async selectBoard(board: Board): Promise<void> {
|
||||
this.selectedBoard = board;
|
||||
}
|
||||
|
||||
async getSelectBoard(): Promise<AttachedBoard | undefined> {
|
||||
async getSelectBoard(): Promise<Board | undefined> {
|
||||
return this.selectedBoard;
|
||||
}
|
||||
|
||||
async search(options: { query?: string }): Promise<{ items: Board[] }> {
|
||||
async search(options: { query?: string }): Promise<{ items: BoardPackage[] }> {
|
||||
const { client, instance } = await this.coreClientProvider.getClient();
|
||||
|
||||
const installedPlatformsReq = new PlatformListReq();
|
||||
@ -55,7 +55,6 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
client.platformList(installedPlatformsReq, (err, resp) => (!!err ? reject : resolve)(!!err ? err : resp))
|
||||
);
|
||||
const installedPlatforms = installedPlatformsResp.getInstalledPlatformList();
|
||||
console.info("Installed platforms", installedPlatforms);
|
||||
|
||||
const req = new PlatformSearchReq();
|
||||
req.setSearchArgs(options.query || "");
|
||||
@ -69,15 +68,16 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
installedVersion = matchingPlatform.getInstalled();
|
||||
}
|
||||
|
||||
const result: Board = {
|
||||
const result: BoardPackage = {
|
||||
id: item.getId(),
|
||||
name: item.getName(),
|
||||
author: item.getAuthor(),
|
||||
availableVersions: [ item.getVersion() ],
|
||||
description: item.getParagragh(),
|
||||
description: item.getBoardsList().map(b => b.getName()).join(", "),
|
||||
installable: true,
|
||||
summary: item.getSentence(),
|
||||
summary: "Boards included in this package:",
|
||||
installedVersion,
|
||||
boards: item.getBoardsList().map(b => <Board>{ name: b.getName(), fqbn: b.getFqbn() }),
|
||||
}
|
||||
return result;
|
||||
});
|
||||
@ -85,18 +85,18 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
return { items };
|
||||
}
|
||||
|
||||
async install(board: Board): Promise<void> {
|
||||
async install(pkg: BoardPackage): Promise<void> {
|
||||
const { client, instance } = await this.coreClientProvider.getClient();
|
||||
|
||||
const [ platform, boardName ] = board.id.split(":");
|
||||
const [ platform, boardName ] = pkg.id.split(":");
|
||||
|
||||
const req = new PlatformInstallReq();
|
||||
req.setInstance(instance);
|
||||
req.setArchitecture(boardName);
|
||||
req.setPlatformPackage(platform);
|
||||
req.setVersion(board.availableVersions[0]);
|
||||
req.setVersion(pkg.availableVersions[0]);
|
||||
|
||||
console.info("Starting board installation", board);
|
||||
console.info("Starting board installation", pkg);
|
||||
const resp = client.platformInstall(req);
|
||||
resp.on('data', (r: PlatformInstallResp) => {
|
||||
const prog = r.getProgress();
|
||||
@ -108,7 +108,7 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
resp.on('end', resolve);
|
||||
resp.on('error', reject);
|
||||
});
|
||||
console.info("Board installation done", board);
|
||||
console.info("Board installation done", pkg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -320,11 +320,10 @@ export class SearchOutput extends jspb.Message {
|
||||
getAuthor(): string;
|
||||
setAuthor(value: string): void;
|
||||
|
||||
getSentence(): string;
|
||||
setSentence(value: string): void;
|
||||
|
||||
getParagragh(): string;
|
||||
setParagragh(value: string): void;
|
||||
clearBoardsList(): void;
|
||||
getBoardsList(): Array<SearchOutputBoard>;
|
||||
setBoardsList(value: Array<SearchOutputBoard>): void;
|
||||
addBoards(value?: SearchOutputBoard, index?: number): SearchOutputBoard;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
@ -343,8 +342,32 @@ export namespace SearchOutput {
|
||||
version: string,
|
||||
name: string,
|
||||
author: string,
|
||||
sentence: string,
|
||||
paragragh: string,
|
||||
boardsList: Array<SearchOutputBoard.AsObject>,
|
||||
}
|
||||
}
|
||||
|
||||
export class SearchOutputBoard extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): void;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): void;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SearchOutputBoard.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SearchOutputBoard): SearchOutputBoard.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: SearchOutputBoard, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): SearchOutputBoard;
|
||||
static deserializeBinaryFromReader(message: SearchOutputBoard, reader: jspb.BinaryReader): SearchOutputBoard;
|
||||
}
|
||||
|
||||
export namespace SearchOutputBoard {
|
||||
export type AsObject = {
|
||||
name: string,
|
||||
fqbn: string,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ goog.exportSymbol('proto.arduino.PlatformUninstallResp', null, global);
|
||||
goog.exportSymbol('proto.arduino.PlatformUpgradeReq', null, global);
|
||||
goog.exportSymbol('proto.arduino.PlatformUpgradeResp', null, global);
|
||||
goog.exportSymbol('proto.arduino.SearchOutput', null, global);
|
||||
goog.exportSymbol('proto.arduino.SearchOutputBoard', null, global);
|
||||
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
@ -2050,12 +2051,19 @@ proto.arduino.PlatformSearchResp.prototype.clearSearchOutputList = function() {
|
||||
* @constructor
|
||||
*/
|
||||
proto.arduino.SearchOutput = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, proto.arduino.SearchOutput.repeatedFields_, null);
|
||||
};
|
||||
goog.inherits(proto.arduino.SearchOutput, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
proto.arduino.SearchOutput.displayName = 'proto.arduino.SearchOutput';
|
||||
}
|
||||
/**
|
||||
* List of repeated fields within this message type.
|
||||
* @private {!Array<number>}
|
||||
* @const
|
||||
*/
|
||||
proto.arduino.SearchOutput.repeatedFields_ = [5];
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
@ -2089,8 +2097,8 @@ proto.arduino.SearchOutput.toObject = function(includeInstance, msg) {
|
||||
version: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
name: jspb.Message.getFieldWithDefault(msg, 3, ""),
|
||||
author: jspb.Message.getFieldWithDefault(msg, 4, ""),
|
||||
sentence: jspb.Message.getFieldWithDefault(msg, 5, ""),
|
||||
paragragh: jspb.Message.getFieldWithDefault(msg, 6, "")
|
||||
boardsList: jspb.Message.toObjectList(msg.getBoardsList(),
|
||||
proto.arduino.SearchOutputBoard.toObject, includeInstance)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@ -2144,12 +2152,9 @@ proto.arduino.SearchOutput.deserializeBinaryFromReader = function(msg, reader) {
|
||||
msg.setAuthor(value);
|
||||
break;
|
||||
case 5:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setSentence(value);
|
||||
break;
|
||||
case 6:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setParagragh(value);
|
||||
var value = new proto.arduino.SearchOutputBoard;
|
||||
reader.readMessage(value,proto.arduino.SearchOutputBoard.deserializeBinaryFromReader);
|
||||
msg.addBoards(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
@ -2208,18 +2213,12 @@ proto.arduino.SearchOutput.serializeBinaryToWriter = function(message, writer) {
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getSentence();
|
||||
f = message.getBoardsList();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
writer.writeRepeatedMessage(
|
||||
5,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getParagragh();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
6,
|
||||
f
|
||||
f,
|
||||
proto.arduino.SearchOutputBoard.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -2286,32 +2285,202 @@ proto.arduino.SearchOutput.prototype.setAuthor = function(value) {
|
||||
|
||||
|
||||
/**
|
||||
* optional string Sentence = 5;
|
||||
* @return {string}
|
||||
* repeated SearchOutputBoard Boards = 5;
|
||||
* @return {!Array<!proto.arduino.SearchOutputBoard>}
|
||||
*/
|
||||
proto.arduino.SearchOutput.prototype.getSentence = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
|
||||
proto.arduino.SearchOutput.prototype.getBoardsList = function() {
|
||||
return /** @type{!Array<!proto.arduino.SearchOutputBoard>} */ (
|
||||
jspb.Message.getRepeatedWrapperField(this, proto.arduino.SearchOutputBoard, 5));
|
||||
};
|
||||
|
||||
|
||||
/** @param {string} value */
|
||||
proto.arduino.SearchOutput.prototype.setSentence = function(value) {
|
||||
jspb.Message.setProto3StringField(this, 5, value);
|
||||
/** @param {!Array<!proto.arduino.SearchOutputBoard>} value */
|
||||
proto.arduino.SearchOutput.prototype.setBoardsList = function(value) {
|
||||
jspb.Message.setRepeatedWrapperField(this, 5, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string Paragragh = 6;
|
||||
* @param {!proto.arduino.SearchOutputBoard=} opt_value
|
||||
* @param {number=} opt_index
|
||||
* @return {!proto.arduino.SearchOutputBoard}
|
||||
*/
|
||||
proto.arduino.SearchOutput.prototype.addBoards = function(opt_value, opt_index) {
|
||||
return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.arduino.SearchOutputBoard, opt_index);
|
||||
};
|
||||
|
||||
|
||||
proto.arduino.SearchOutput.prototype.clearBoardsList = function() {
|
||||
this.setBoardsList([]);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.arduino.SearchOutputBoard = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.arduino.SearchOutputBoard, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
proto.arduino.SearchOutputBoard.displayName = 'proto.arduino.SearchOutputBoard';
|
||||
}
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto suitable for use in Soy templates.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
|
||||
* @param {boolean=} opt_includeInstance Whether to include the JSPB instance
|
||||
* for transitional soy proto support: http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.arduino.SearchOutputBoard.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.arduino.SearchOutputBoard.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Whether to include the JSPB
|
||||
* instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.arduino.SearchOutputBoard} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.arduino.SearchOutputBoard.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
name: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
fqbn: jspb.Message.getFieldWithDefault(msg, 2, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.arduino.SearchOutputBoard}
|
||||
*/
|
||||
proto.arduino.SearchOutputBoard.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.arduino.SearchOutputBoard;
|
||||
return proto.arduino.SearchOutputBoard.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.arduino.SearchOutputBoard} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.arduino.SearchOutputBoard}
|
||||
*/
|
||||
proto.arduino.SearchOutputBoard.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setName(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setFqbn(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.arduino.SearchOutputBoard.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.arduino.SearchOutputBoard.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.arduino.SearchOutputBoard} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.arduino.SearchOutputBoard.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getName();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getFqbn();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string name = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.arduino.SearchOutput.prototype.getParagragh = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
|
||||
proto.arduino.SearchOutputBoard.prototype.getName = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/** @param {string} value */
|
||||
proto.arduino.SearchOutput.prototype.setParagragh = function(value) {
|
||||
jspb.Message.setProto3StringField(this, 6, value);
|
||||
proto.arduino.SearchOutputBoard.prototype.setName = function(value) {
|
||||
jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string fqbn = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.arduino.SearchOutputBoard.prototype.getFqbn = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/** @param {string} value */
|
||||
proto.arduino.SearchOutputBoard.prototype.setFqbn = function(value) {
|
||||
jspb.Message.setProto3StringField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { inject, injectable } from 'inversify';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common/filesystem';
|
||||
import { CoreService } from '../common/protocol/core-service';
|
||||
import { CompileReq, CompileResp } from './cli-protocol/compile_pb';
|
||||
import { BoardsService, AttachedSerialBoard } from '../common/protocol/boards-service';
|
||||
import { BoardsService, AttachedSerialBoard, AttachedNetworkBoard } from '../common/protocol/boards-service';
|
||||
import { CoreClientProvider } from './core-client-provider';
|
||||
import * as path from 'path';
|
||||
import { ToolOutputServiceServer } from '../common/protocol/tool-output-service';
|
||||
@ -51,17 +51,25 @@ export class CoreServiceImpl implements CoreService {
|
||||
compilerReq.setQuiet(false);
|
||||
|
||||
const result = client.compile(compilerReq);
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
try {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
result.on('data', (cr: CompileResp) => {
|
||||
this.toolOutputService.publishNewOutput("compile", new Buffer(cr.getOutStream_asU8()).toString());
|
||||
console.error(cr.getErrStream().toString());
|
||||
this.toolOutputService.publishNewOutput("compile error", new Buffer(cr.getErrStream_asU8()).toString());
|
||||
});
|
||||
result.on('error', error => reject(error));
|
||||
result.on('end', () => resolve());
|
||||
});
|
||||
this.toolOutputService.publishNewOutput("compile", "Compilation complete\n");
|
||||
} catch (e) {
|
||||
this.toolOutputService.publishNewOutput("compile error", `Compilation error: ${e}\n`);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
async upload(options: CoreService.Upload.Options): Promise<void> {
|
||||
await this.compile({uri: options.uri});
|
||||
|
||||
console.log('upload', options);
|
||||
const { uri } = options;
|
||||
const sketchFilePath = await this.fileSystem.getFsPath(options.uri);
|
||||
@ -86,11 +94,15 @@ export class CoreServiceImpl implements CoreService {
|
||||
req.setFqbn(currentBoard.fqbn);
|
||||
if (AttachedSerialBoard.is(currentBoard)) {
|
||||
req.setPort(currentBoard.port);
|
||||
} else {
|
||||
} else if (AttachedNetworkBoard.is(currentBoard)) {
|
||||
throw new Error("can only upload to serial boards");
|
||||
} else {
|
||||
throw new Error("board is not attached");
|
||||
}
|
||||
const result = client.upload(req);
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
|
||||
try {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
result.on('data', (cr: UploadResp) => {
|
||||
this.toolOutputService.publishNewOutput("upload", new Buffer(cr.getOutStream_asU8()).toString());
|
||||
this.toolOutputService.publishNewOutput("upload error", new Buffer(cr.getErrStream_asU8()).toString());
|
||||
@ -98,6 +110,11 @@ export class CoreServiceImpl implements CoreService {
|
||||
result.on('error', error => reject(error));
|
||||
result.on('end', () => resolve());
|
||||
});
|
||||
this.toolOutputService.publishNewOutput("upload", "Upload complete\n");
|
||||
} catch (e) {
|
||||
this.toolOutputService.publishNewOutput("upload error", `Uplaod error: ${e}\n`);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,10 @@ export class ToolOutputServiceServerImpl implements ToolOutputServiceServer {
|
||||
protected clients: ToolOutputServiceClient[] = [];
|
||||
|
||||
publishNewOutput(tool: string, chunk: string): void {
|
||||
if (!chunk) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.clients.forEach(c => c.onNewOutput(tool, chunk));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user