mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-30 14:46:34 +00:00
Proxied more monitor methods to frontend
This commit is contained in:
parent
ee265aec90
commit
bf958fd8cf
@ -1,13 +1,103 @@
|
|||||||
import { Emitter } from "@theia/core";
|
import { Emitter, JsonRpcProxy, MessageService } from "@theia/core";
|
||||||
import { injectable } from "@theia/core/shared/inversify";
|
import { inject, injectable } from "@theia/core/shared/inversify";
|
||||||
import { MonitorManagerProxyClient } from "../common/protocol/monitor-service";
|
import { Board, Port } from "../common/protocol";
|
||||||
|
import { Monitor, MonitorManagerProxy, MonitorManagerProxyClient, MonitorSettings } from "../common/protocol/monitor-service";
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class MonitorManagerProxyClientImpl implements MonitorManagerProxyClient {
|
export class MonitorManagerProxyClientImpl implements MonitorManagerProxyClient {
|
||||||
protected readonly onWebSocketChangedEmitter = new Emitter<number>();
|
// When pluggable monitor messages are received from the backend
|
||||||
readonly onWebSocketChanged = this.onWebSocketChangedEmitter.event;
|
// this event is triggered.
|
||||||
|
// Ideally a frontend component is connected to this event
|
||||||
|
// to update the UI.
|
||||||
|
protected readonly onMessagesReceivedEmitter = new Emitter<{ messages: string[] }>();
|
||||||
|
readonly onMessagesReceived = this.onMessagesReceivedEmitter.event;
|
||||||
|
|
||||||
notifyWebSocketChanged(message: number): void {
|
// WebSocket used to handle pluggable monitor communication between
|
||||||
this.onWebSocketChangedEmitter.fire(message);
|
// frontend and backend.
|
||||||
|
private webSocket?: WebSocket;
|
||||||
|
private wsPort?: number;
|
||||||
|
|
||||||
|
getWebSocketPort(): number | undefined {
|
||||||
|
return this.wsPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@inject(MessageService)
|
||||||
|
protected messageService: MessageService,
|
||||||
|
|
||||||
|
// This is necessary to call the backend methods from the frontend
|
||||||
|
@inject(MonitorManagerProxy)
|
||||||
|
protected server: JsonRpcProxy<MonitorManagerProxy>
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects a localhost WebSocket using the specified port.
|
||||||
|
* @param addressPort port of the WebSocket
|
||||||
|
*/
|
||||||
|
connect(addressPort: number): void {
|
||||||
|
if (this.webSocket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.webSocket = new WebSocket(`ws://localhost:${addressPort}`);
|
||||||
|
} catch {
|
||||||
|
this.messageService.error('Unable to connect to websocket');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.webSocket.onmessage = (res) => {
|
||||||
|
const messages = JSON.parse(res.data);
|
||||||
|
this.onMessagesReceivedEmitter.fire({ messages });
|
||||||
|
}
|
||||||
|
this.wsPort = addressPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects the WebSocket if connected.
|
||||||
|
*/
|
||||||
|
disconnect(): void {
|
||||||
|
try {
|
||||||
|
this.webSocket?.close();
|
||||||
|
this.webSocket = undefined;
|
||||||
|
} catch {
|
||||||
|
this.messageService.error('Unable to close websocket');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async isWSConnected(): Promise<boolean> {
|
||||||
|
return !!this.webSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
async startMonitor(board: Board, port: Port, settings?: MonitorSettings): Promise<void> {
|
||||||
|
return this.server.startMonitor(board, port, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentSettings(board: Board, port: Port): MonitorSettings {
|
||||||
|
return this.server.getCurrentSettings(board, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
send(message: string): void {
|
||||||
|
if (!this.webSocket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.webSocket.send(JSON.stringify({
|
||||||
|
command: Monitor.Command.SEND_MESSAGE,
|
||||||
|
data: message,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
changeSettings(settings: MonitorSettings): void {
|
||||||
|
if (!this.webSocket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.webSocket.send(JSON.stringify({
|
||||||
|
command: Monitor.Command.CHANGE_SETTINGS,
|
||||||
|
// TODO: This might be wrong, verify if it works
|
||||||
|
data: settings,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,20 @@ export interface MonitorManagerProxy extends JsonRpcServer<MonitorManagerProxyCl
|
|||||||
startMonitor(board: Board, port: Port, settings?: MonitorSettings): Promise<void>;
|
startMonitor(board: Board, port: Port, settings?: MonitorSettings): Promise<void>;
|
||||||
changeMonitorSettings(board: Board, port: Port, settings: MonitorSettings): Promise<void>;
|
changeMonitorSettings(board: Board, port: Port, settings: MonitorSettings): Promise<void>;
|
||||||
stopMonitor(board: Board, port: Port): Promise<void>;
|
stopMonitor(board: Board, port: Port): Promise<void>;
|
||||||
getSupportedSettings(protocol: string, fqbn: string): Promise<MonitorSettings>;
|
getCurrentSettings(board: Board, port: Port): MonitorSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MonitorManagerProxyClient = Symbol('MonitorManagerProxyClient');
|
export const MonitorManagerProxyClient = Symbol('MonitorManagerProxyClient');
|
||||||
export interface MonitorManagerProxyClient {
|
export interface MonitorManagerProxyClient {
|
||||||
onWebSocketChanged: Event<number>;
|
onMessagesReceived: Event<{ messages: string[] }>;
|
||||||
notifyWebSocketChanged(message: number): void;
|
connect(addressPort: number): void;
|
||||||
|
disconnect(): void;
|
||||||
|
getWebSocketPort(): number | undefined;
|
||||||
|
isWSConnected(): Promise<boolean>;
|
||||||
|
startMonitor(board: Board, port: Port, settings?: MonitorSettings): Promise<void>;
|
||||||
|
getCurrentSettings(board: Board, port: Port): MonitorSettings;
|
||||||
|
send(message: string): void;
|
||||||
|
changeSettings(settings: MonitorSettings): void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MonitorSetting {
|
export interface MonitorSetting {
|
||||||
@ -29,4 +36,35 @@ export interface MonitorSetting {
|
|||||||
selectedValue: string;
|
selectedValue: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MonitorSettings = Record<string, MonitorSetting>;
|
export type MonitorSettings = Record<string, MonitorSetting>;
|
||||||
|
|
||||||
|
export namespace Monitor {
|
||||||
|
export enum Command {
|
||||||
|
SEND_MESSAGE = 'MONITOR_SEND_MESSAGE',
|
||||||
|
CHANGE_SETTINGS = 'MONITOR_CHANGE_SETTINGS',
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Message = {
|
||||||
|
command: Monitor.Command,
|
||||||
|
data: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Status { }
|
||||||
|
export type OK = Status;
|
||||||
|
export interface ErrorStatus extends Status {
|
||||||
|
readonly message: string;
|
||||||
|
}
|
||||||
|
export namespace Status {
|
||||||
|
export function isOK(status: Status & { message?: string }): status is OK {
|
||||||
|
return !!status && typeof status.message !== 'string';
|
||||||
|
}
|
||||||
|
export const OK: OK = {};
|
||||||
|
export const NOT_CONNECTED: ErrorStatus = { message: 'Not connected.' };
|
||||||
|
export const ALREADY_CONNECTED: ErrorStatus = {
|
||||||
|
message: 'Already connected.',
|
||||||
|
};
|
||||||
|
export const CONFIG_MISSING: ErrorStatus = {
|
||||||
|
message: 'Serial Config missing.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@ export class MonitorManagerProxyImpl implements MonitorManagerProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dispose(): void {
|
dispose(): void {
|
||||||
// NOOP
|
this.client?.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +36,8 @@ export class MonitorManagerProxyImpl implements MonitorManagerProxy {
|
|||||||
}
|
}
|
||||||
const status = await this.manager.startMonitor(board, port);
|
const status = await this.manager.startMonitor(board, port);
|
||||||
if (status === Status.ALREADY_CONNECTED || status === Status.OK) {
|
if (status === Status.ALREADY_CONNECTED || status === Status.OK) {
|
||||||
this.client.notifyWebSocketChanged(this.manager.getWebsocketAddressPort(board, port));
|
// Monitor started correctly, connect it with the frontend
|
||||||
|
this.client.connect(this.manager.getWebsocketAddressPort(board, port));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,15 +66,14 @@ export class MonitorManagerProxyImpl implements MonitorManagerProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the settings supported by the pluggable monitor for the specified
|
* Returns the current settings by the pluggable monitor connected to specified
|
||||||
* protocol, the fqbn is necessary since it's used to tell different monitors
|
* by board/port combination.
|
||||||
* using the same protocol.
|
* @param board board connected to port
|
||||||
* @param protocol protocol of a pluggable monitor
|
* @param port port monitored
|
||||||
* @param fqbn unique ID of a board
|
|
||||||
* @returns a map of MonitorSetting
|
* @returns a map of MonitorSetting
|
||||||
*/
|
*/
|
||||||
async getSupportedSettings(protocol: string, fqbn: string): Promise<MonitorSettings> {
|
getCurrentSettings(board: Board, port: Port): MonitorSettings {
|
||||||
return this.manager.portMonitorSettings(protocol, fqbn);
|
return this.manager.currentMonitorSettings(board, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
setClient(client: MonitorManagerProxyClient | undefined): void {
|
setClient(client: MonitorManagerProxyClient | undefined): void {
|
||||||
|
@ -321,29 +321,16 @@ export class MonitorService extends CoreClientAware implements Disposable {
|
|||||||
if (!this.onMessageReceived) {
|
if (!this.onMessageReceived) {
|
||||||
this.onMessageReceived = this.webSocketProvider.onMessageReceived(
|
this.onMessageReceived = this.webSocketProvider.onMessageReceived(
|
||||||
(msg: string) => {
|
(msg: string) => {
|
||||||
const message: SerialPlotter.Protocol.Message = JSON.parse(msg);
|
const message: Monitor.Message = JSON.parse(msg);
|
||||||
|
|
||||||
switch (message.command) {
|
switch (message.command) {
|
||||||
case SerialPlotter.Protocol.Command.PLOTTER_SEND_MESSAGE:
|
case Monitor.Command.SEND_MESSAGE:
|
||||||
this.send(message.data);
|
this.send(message.data);
|
||||||
break;
|
break
|
||||||
|
case Monitor.Command.CHANGE_SETTINGS:
|
||||||
case SerialPlotter.Protocol.Command.PLOTTER_SET_BAUDRATE:
|
const settings: MonitorSettings = JSON.parse(message.data);
|
||||||
this.theiaFEClient?.notifyBaudRateChanged(
|
this.changeSettings(settings);
|
||||||
parseInt(message.data, 10) as SerialConfig.BaudRate
|
break
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SerialPlotter.Protocol.Command.PLOTTER_SET_LINE_ENDING:
|
|
||||||
this.theiaFEClient?.notifyLineEndingChanged(message.data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SerialPlotter.Protocol.Command.PLOTTER_SET_INTERPOLATE:
|
|
||||||
this.theiaFEClient?.notifyInterpolateChanged(message.data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user