Changed MonitorWidget and children to use new monitor proxy

This commit is contained in:
Silvano Cerza 2022-03-10 17:04:07 +01:00 committed by Alberto Iannaccone
parent 6b7b33356d
commit 7889f40834
3 changed files with 96 additions and 71 deletions

View File

@ -9,14 +9,16 @@ import {
Widget, Widget,
MessageLoop, MessageLoop,
} from '@theia/core/lib/browser/widgets'; } from '@theia/core/lib/browser/widgets';
import { SerialConfig } from '../../../common/protocol/serial-service';
import { ArduinoSelect } from '../../widgets/arduino-select'; import { ArduinoSelect } from '../../widgets/arduino-select';
import { SerialModel } from '../serial-model';
import { SerialConnectionManager } from '../serial-connection-manager';
import { SerialMonitorSendInput } from './serial-monitor-send-input'; import { SerialMonitorSendInput } from './serial-monitor-send-input';
import { SerialMonitorOutput } from './serial-monitor-send-output'; import { SerialMonitorOutput } from './serial-monitor-send-output';
import { BoardsServiceProvider } from '../../boards/boards-service-provider'; import { BoardsServiceProvider } from '../../boards/boards-service-provider';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import {
MonitorManagerProxyClient,
MonitorSettings,
} from '../../../common/protocol';
import { MonitorModel } from '../../monitor-model';
@injectable() @injectable()
export class MonitorWidget extends ReactWidget { export class MonitorWidget extends ReactWidget {
@ -26,11 +28,11 @@ export class MonitorWidget extends ReactWidget {
); );
static readonly ID = 'serial-monitor'; static readonly ID = 'serial-monitor';
@inject(SerialModel) @inject(MonitorModel)
protected readonly serialModel: SerialModel; protected readonly monitorModel: MonitorModel;
@inject(SerialConnectionManager) @inject(MonitorManagerProxyClient)
protected readonly serialConnection: SerialConnectionManager; protected readonly monitorManagerProxy: MonitorManagerProxyClient;
@inject(BoardsServiceProvider) @inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider; protected readonly boardsServiceProvider: BoardsServiceProvider;
@ -57,17 +59,27 @@ export class MonitorWidget extends ReactWidget {
this.scrollOptions = undefined; this.scrollOptions = undefined;
this.toDispose.push(this.clearOutputEmitter); this.toDispose.push(this.clearOutputEmitter);
this.toDispose.push( this.toDispose.push(
Disposable.create(() => this.serialConnection.closeWStoBE()) Disposable.create(() => this.monitorManagerProxy.disconnect())
);
this.toDispose.push(
this.boardsServiceProvider.onBoardsConfigChanged(
async ({ selectedBoard, selectedPort }) => {
if (selectedBoard && selectedBoard.fqbn && selectedPort) {
await this.monitorManagerProxy.startMonitor(
selectedBoard,
selectedPort
);
}
}
)
); );
} }
@postConstruct() @postConstruct()
protected init(): void { protected init(): void {
this.update(); this.update();
this.toDispose.push( this.toDispose.push(this.monitorModel.onChange(() => this.update()));
this.serialConnection.onConnectionChanged(() => this.clearConsole())
);
this.toDispose.push(this.serialModel.onChange(() => this.update()));
} }
clearConsole(): void { clearConsole(): void {
@ -79,11 +91,6 @@ export class MonitorWidget extends ReactWidget {
super.dispose(); super.dispose();
} }
protected onAfterAttach(msg: Message): void {
super.onAfterAttach(msg);
this.serialConnection.openWSToBE();
}
onCloseRequest(msg: Message): void { onCloseRequest(msg: Message): void {
this.closing = true; this.closing = true;
super.onCloseRequest(msg); super.onCloseRequest(msg);
@ -119,7 +126,7 @@ export class MonitorWidget extends ReactWidget {
}; };
protected get lineEndings(): OptionsType< protected get lineEndings(): OptionsType<
SerialMonitorOutput.SelectOption<SerialModel.EOL> SerialMonitorOutput.SelectOption<MonitorModel.EOL>
> { > {
return [ return [
{ {
@ -144,32 +151,61 @@ export class MonitorWidget extends ReactWidget {
]; ];
} }
protected get baudRates(): OptionsType< private getCurrentSettings(): MonitorSettings {
SerialMonitorOutput.SelectOption<SerialConfig.BaudRate> const board = this.boardsServiceProvider.boardsConfig.selectedBoard;
> { const port = this.boardsServiceProvider.boardsConfig.selectedPort;
const baudRates: Array<SerialConfig.BaudRate> = [ if (!board || !port) {
300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, return {};
]; }
return baudRates.map((baudRate) => ({ return this.monitorManagerProxy.getCurrentSettings(board, port);
label: baudRate + ' baud', }
value: baudRate,
})); //////////////////////////////////////////////////
////////////////////IMPORTANT/////////////////////
//////////////////////////////////////////////////
// baudRates and selectedBaudRates as of now are hardcoded
// like this to retrieve the baudrate settings from the ones
// received by the monitor.
// We're doing it like since the frontend as of now doesn't
// support a fully customizable list of options that would
// be require to support pluggable monitors completely.
// As soon as the frontend UI is updated to support
// any custom settings this methods MUST be removed and
// made generic.
//
// This breaks if the user tries to open a monitor that
// doesn't support the baudrate setting.
protected get baudRates(): string[] {
const settings = this.getCurrentSettings();
const baudRateSettings = settings['baudrate'];
if (!baudRateSettings) {
return [];
}
return baudRateSettings.values;
}
protected get selectedBaudRate(): string {
const settings = this.getCurrentSettings();
const baudRateSettings = settings['baudrate'];
if (!baudRateSettings) {
return '';
}
return baudRateSettings.selectedValue;
} }
protected render(): React.ReactNode { protected render(): React.ReactNode {
const { baudRates, lineEndings } = this; const { baudRates, lineEndings } = this;
const lineEnding = const lineEnding =
lineEndings.find((item) => item.value === this.serialModel.lineEnding) || lineEndings.find((item) => item.value === this.monitorModel.lineEnding) ||
lineEndings[1]; // Defaults to `\n`. lineEndings[1]; // Defaults to `\n`.
const baudRate = const baudRate = baudRates.find((item) => item === this.selectedBaudRate);
baudRates.find((item) => item.value === this.serialModel.baudRate) ||
baudRates[4]; // Defaults to `9600`.
return ( return (
<div className="serial-monitor"> <div className="serial-monitor">
<div className="head"> <div className="head">
<div className="send"> <div className="send">
<SerialMonitorSendInput <SerialMonitorSendInput
serialConnection={this.serialConnection} boardsServiceProvider={this.boardsServiceProvider}
monitorManagerProxy={this.monitorManagerProxy}
resolveFocus={this.onFocusResolved} resolveFocus={this.onFocusResolved}
onSend={this.onSend} onSend={this.onSend}
/> />
@ -196,8 +232,8 @@ export class MonitorWidget extends ReactWidget {
</div> </div>
<div className="body"> <div className="body">
<SerialMonitorOutput <SerialMonitorOutput
serialModel={this.serialModel} monitorModel={this.monitorModel}
serialConnection={this.serialConnection} monitorManagerProxy={this.monitorManagerProxy}
clearConsoleEvent={this.clearOutputEmitter.event} clearConsoleEvent={this.clearOutputEmitter.event}
height={Math.floor(this.widgetHeight - 50)} height={Math.floor(this.widgetHeight - 50)}
/> />
@ -208,18 +244,18 @@ export class MonitorWidget extends ReactWidget {
protected readonly onSend = (value: string) => this.doSend(value); protected readonly onSend = (value: string) => this.doSend(value);
protected async doSend(value: string): Promise<void> { protected async doSend(value: string): Promise<void> {
this.serialConnection.send(value); this.monitorManagerProxy.send(value);
} }
protected readonly onChangeLineEnding = ( protected readonly onChangeLineEnding = (
option: SerialMonitorOutput.SelectOption<SerialModel.EOL> option: SerialMonitorOutput.SelectOption<MonitorModel.EOL>
) => { ) => {
this.serialModel.lineEnding = option.value; this.monitorModel.lineEnding = option.value;
}; };
protected readonly onChangeBaudRate = ( protected readonly onChangeBaudRate = (value: string) => {
option: SerialMonitorOutput.SelectOption<SerialConfig.BaudRate> const settings = this.getCurrentSettings();
) => { settings['baudrate'].selectedValue = value;
this.serialModel.baudRate = option.value; this.monitorManagerProxy.changeSettings(settings);
}; };
} }

View File

@ -3,12 +3,13 @@ import { Key, KeyCode } from '@theia/core/lib/browser/keys';
import { Board } from '../../../common/protocol/boards-service'; import { Board } from '../../../common/protocol/boards-service';
import { isOSX } from '@theia/core/lib/common/os'; import { isOSX } from '@theia/core/lib/common/os';
import { DisposableCollection, nls } from '@theia/core/lib/common'; import { DisposableCollection, nls } from '@theia/core/lib/common';
import { SerialConnectionManager } from '../serial-connection-manager'; import { MonitorManagerProxyClient } from '../../../common/protocol';
import { SerialPlotter } from '../plotter/protocol'; import { BoardsServiceProvider } from '../../boards/boards-service-provider';
export namespace SerialMonitorSendInput { export namespace SerialMonitorSendInput {
export interface Props { export interface Props {
readonly serialConnection: SerialConnectionManager; readonly boardsServiceProvider: BoardsServiceProvider;
readonly monitorManagerProxy: MonitorManagerProxyClient;
readonly onSend: (text: string) => void; readonly onSend: (text: string) => void;
readonly resolveFocus: (element: HTMLElement | undefined) => void; readonly resolveFocus: (element: HTMLElement | undefined) => void;
} }
@ -33,21 +34,9 @@ export class SerialMonitorSendInput extends React.Component<
} }
componentDidMount(): void { componentDidMount(): void {
this.props.serialConnection.isBESerialConnected().then((connected) => { this.props.monitorManagerProxy.isWSConnected().then((connected) => {
this.setState({ connected }); this.setState({ connected });
}); });
this.toDisposeBeforeUnmount.pushAll([
this.props.serialConnection.onRead(({ messages }) => {
if (
messages.command ===
SerialPlotter.Protocol.Command.MIDDLEWARE_CONFIG_CHANGED &&
'connected' in messages.data
) {
this.setState({ connected: messages.data.connected });
}
}),
]);
} }
componentWillUnmount(): void { componentWillUnmount(): void {
@ -70,14 +59,15 @@ export class SerialMonitorSendInput extends React.Component<
} }
protected get placeholder(): string { protected get placeholder(): string {
const serialConfig = this.props.serialConnection.getConfig(); const board = this.props.boardsServiceProvider.boardsConfig.selectedBoard;
if (!this.state.connected || !serialConfig) { const port = this.props.boardsServiceProvider.boardsConfig.selectedPort;
if (!this.state.connected || !board || !port) {
return nls.localize( return nls.localize(
'arduino/serial/notConnected', 'arduino/serial/notConnected',
'Not connected. Select a board and a port to connect automatically.' 'Not connected. Select a board and a port to connect automatically.'
); );
} }
const { board, port } = serialConfig;
return nls.localize( return nls.localize(
'arduino/serial/message', 'arduino/serial/message',
"Message ({0} + Enter to send message to '{1}' on '{2}')", "Message ({0} + Enter to send message to '{1}' on '{2}')",

View File

@ -2,10 +2,10 @@ import * as React from 'react';
import { Event } from '@theia/core/lib/common/event'; import { Event } from '@theia/core/lib/common/event';
import { DisposableCollection } from '@theia/core/lib/common/disposable'; import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { areEqual, FixedSizeList as List } from 'react-window'; import { areEqual, FixedSizeList as List } from 'react-window';
import { SerialModel } from '../serial-model';
import { SerialConnectionManager } from '../serial-connection-manager';
import dateFormat = require('dateformat'); import dateFormat = require('dateformat');
import { messagesToLines, truncateLines } from './monitor-utils'; import { messagesToLines, truncateLines } from './monitor-utils';
import { MonitorManagerProxyClient } from '../../../common/protocol';
import { MonitorModel } from '../../monitor-model';
export type Line = { message: string; timestamp?: Date; lineLen: number }; export type Line = { message: string; timestamp?: Date; lineLen: number };
@ -24,7 +24,7 @@ export class SerialMonitorOutput extends React.Component<
this.listRef = React.createRef(); this.listRef = React.createRef();
this.state = { this.state = {
lines: [], lines: [],
timestamp: this.props.serialModel.timestamp, timestamp: this.props.monitorModel.timestamp,
charCount: 0, charCount: 0,
}; };
} }
@ -58,14 +58,13 @@ export class SerialMonitorOutput extends React.Component<
componentDidMount(): void { componentDidMount(): void {
this.scrollToBottom(); this.scrollToBottom();
this.toDisposeBeforeUnmount.pushAll([ this.toDisposeBeforeUnmount.pushAll([
this.props.serialConnection.onRead(({ messages }) => { this.props.monitorManagerProxy.onMessagesReceived(({ messages }) => {
const [newLines, totalCharCount] = messagesToLines( const [newLines, totalCharCount] = messagesToLines(
messages, messages,
this.state.lines, this.state.lines,
this.state.charCount this.state.charCount
); );
const [lines, charCount] = truncateLines(newLines, totalCharCount); const [lines, charCount] = truncateLines(newLines, totalCharCount);
this.setState({ this.setState({
lines, lines,
charCount, charCount,
@ -75,9 +74,9 @@ export class SerialMonitorOutput extends React.Component<
this.props.clearConsoleEvent(() => this.props.clearConsoleEvent(() =>
this.setState({ lines: [], charCount: 0 }) this.setState({ lines: [], charCount: 0 })
), ),
this.props.serialModel.onChange(({ property }) => { this.props.monitorModel.onChange(({ property }) => {
if (property === 'timestamp') { if (property === 'timestamp') {
const { timestamp } = this.props.serialModel; const { timestamp } = this.props.monitorModel;
this.setState({ timestamp }); this.setState({ timestamp });
} }
if (property === 'autoscroll') { if (property === 'autoscroll') {
@ -93,7 +92,7 @@ export class SerialMonitorOutput extends React.Component<
} }
scrollToBottom = ((): void => { scrollToBottom = ((): void => {
if (this.listRef.current && this.props.serialModel.autoscroll) { if (this.listRef.current && this.props.monitorModel.autoscroll) {
this.listRef.current.scrollToItem(this.state.lines.length, 'end'); this.listRef.current.scrollToItem(this.state.lines.length, 'end');
} }
}).bind(this); }).bind(this);
@ -128,8 +127,8 @@ const Row = React.memo(_Row, areEqual);
export namespace SerialMonitorOutput { export namespace SerialMonitorOutput {
export interface Props { export interface Props {
readonly serialModel: SerialModel; readonly monitorModel: MonitorModel;
readonly serialConnection: SerialConnectionManager; readonly monitorManagerProxy: MonitorManagerProxyClient;
readonly clearConsoleEvent: Event<void>; readonly clearConsoleEvent: Event<void>;
readonly height: number; readonly height: number;
} }