From c480348eb6db1648c44e062f38176b36d9233b7d Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Thu, 20 Feb 2020 11:44:43 -0800 Subject: [PATCH 01/13] Initial implementation of the tracker --- package-lock.json | 5 ++++ package.json | 3 ++- src/extension.ts | 15 ++++++++--- src/extension_utils/debugAdapter.ts | 39 +++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 src/extension_utils/debugAdapter.ts diff --git a/package-lock.json b/package-lock.json index cade389d5..2f77f1f85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29154,6 +29154,11 @@ } } }, + "vscode-debugprotocol": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.28.0.tgz", + "integrity": "sha512-QM4J8A13jBY9I7OPWXN0ZO1cqydnD4co2j/O81jIj6em8VkmJT4VyJQkq4HmwJe3af+u9+7IYCIEDrowgvKxTA==" + }, "vscode-extension-telemetry": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz", diff --git a/package.json b/package.json index 8c581bf6f..cde90ec4f 100644 --- a/package.json +++ b/package.json @@ -313,6 +313,7 @@ "svg-inline-react": "^3.1.0", "ts-jest": "^25.0.0", "util": "^0.12.1", + "vscode-debugprotocol": "^1.28.0", "vscode-extension-telemetry": "^0.1.1", "vscode-nls": "^4.1.0" }, @@ -322,4 +323,4 @@ "extensionDependencies": [ "ms-python.python" ] -} \ No newline at end of file +} diff --git a/src/extension.ts b/src/extension.ts index ef5da60a2..57849a55a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -23,6 +23,7 @@ import { SimulatorDebugConfigurationProvider } from "./simulatorDebugConfigurati import TelemetryAI from "./telemetry/telemetryAI"; import { UsbDetector } from "./usbDetector"; import { VSCODE_MESSAGES_TO_WEBVIEW, WEBVIEW_MESSAGES } from "./view/constants"; +import { DebugAdapterFactory } from "./extension_utils/debugAdapter"; let currentFileAbsPath: string = ""; let currentTextDocument: vscode.TextDocument; @@ -141,7 +142,6 @@ export async function activate(context: vscode.ExtensionContext) { } ); - currentPanel.webview.html = getWebviewContent(context); if (messageListener !== undefined) { @@ -451,7 +451,7 @@ export async function activate(context: vscode.ExtensionContext) { const runSimulatorCommand = async () => { // Prevent running new code if a debug session is active if (inDebugMode) { - console.log("debug mode not running simulator command") + console.log("debug mode not running simulator command"); vscode.window.showErrorMessage( CONSTANTS.ERROR.DEBUGGING_SESSION_IN_PROGESS ); @@ -570,7 +570,7 @@ export async function activate(context: vscode.ExtensionContext) { childProcess.stdout.on("data", data => { dataFromTheProcess = data.toString(); if (currentPanel) { - console.log("receiving message") + console.log("receiving message"); // Process the data from the process and send one state at a time dataFromTheProcess.split("\0").forEach(message => { if ( @@ -916,6 +916,13 @@ export async function activate(context: vscode.ExtensionContext) { utils.getPathToScript(context, "out/", "debug_user_code.py") ); + const debugAdapterFactory = new DebugAdapterFactory( + vscode.debug.activeDebugSession + ); + vscode.debug.registerDebugAdapterTrackerFactory( + "python", + debugAdapterFactory + ); // On Debug Session Start: Init comunication const debugSessionsStarted = vscode.debug.onDidStartDebugSession(() => { if (simulatorDebugConfiguration.deviceSimulatorExpressDebug) { @@ -1023,7 +1030,7 @@ const updateCurrentFileIfPython = async ( if ( currentTextDocument && utils.getActiveEditorFromPath(currentTextDocument.fileName) === - undefined + undefined ) { await vscode.window.showTextDocument( currentTextDocument, diff --git a/src/extension_utils/debugAdapter.ts b/src/extension_utils/debugAdapter.ts new file mode 100644 index 000000000..f5b1bd610 --- /dev/null +++ b/src/extension_utils/debugAdapter.ts @@ -0,0 +1,39 @@ +import { + DebugAdapterTracker, + DebugAdapterTrackerFactory, + DebugSession, + DebugConsole, + ProviderResult, +} from "vscode"; +import { DebugProtocol } from "vscode-debugprotocol"; + +export class DebugAdapter implements DebugAdapterTracker { + private readonly console: DebugConsole | undefined; + constructor(debugSession: DebugSession) { + this.console = debugSession.configuration.console; + } + onWillStartSession() { + console.log("--debugadapter onWillStartSession"); + } + onWillReceiveMessage(message: any): void { + console.log("--debugadapter onWillReceiveMessage"); + console.log(JSON.stringify(message)); + } + onExit() { + console.log("--debugadapter onExit"); + } +} + +export class DebugAdapterFactory implements DebugAdapterTrackerFactory { + private debugSession: DebugSession; + constructor(debugSession: DebugSession) { + console.log("New debug factory"); + this.debugSession = debugSession; + } + public createDebugAdapterTracker( + session: DebugSession + ): ProviderResult { + console.log("It created an adapter tracker"); + return new DebugAdapter(session); + } +} From f537d3575663255b4e600049ca3bfa9d5c727428 Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Thu, 20 Feb 2020 16:01:37 -0800 Subject: [PATCH 02/13] Create messaging service class --- src/extension.ts | 7 ++++++- src/extension_utils/debugAdapter.ts | 29 ++++++++++++++++++++++++++--- src/service/messagingService.ts | 16 ++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/service/messagingService.ts diff --git a/src/extension.ts b/src/extension.ts index 57849a55a..ff230746b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -24,6 +24,7 @@ import TelemetryAI from "./telemetry/telemetryAI"; import { UsbDetector } from "./usbDetector"; import { VSCODE_MESSAGES_TO_WEBVIEW, WEBVIEW_MESSAGES } from "./view/constants"; import { DebugAdapterFactory } from "./extension_utils/debugAdapter"; +import { MessagingService } from "./service/messagingService"; let currentFileAbsPath: string = ""; let currentTextDocument: vscode.TextDocument; @@ -36,6 +37,7 @@ let debuggerCommunicationHandler: DebuggerCommunicationServer; let firstTimeClosed: boolean = true; let shouldShowInvalidFileNamePopup: boolean = true; let shouldShowRunCodePopup: boolean = true; +const messagingService = new MessagingService(); let currentActiveDevice: string = DEFAULT_DEVICE; @@ -122,6 +124,7 @@ export async function activate(context: vscode.ExtensionContext) { const openWebview = () => { if (currentPanel) { + messagingService.setWebview(currentPanel.webview); currentPanel.reveal(vscode.ViewColumn.Beside); } else { currentPanel = vscode.window.createWebviewPanel( @@ -143,6 +146,7 @@ export async function activate(context: vscode.ExtensionContext) { ); currentPanel.webview.html = getWebviewContent(context); + messagingService.setWebview(currentPanel.webview); if (messageListener !== undefined) { messageListener.dispose(); @@ -917,7 +921,8 @@ export async function activate(context: vscode.ExtensionContext) { ); const debugAdapterFactory = new DebugAdapterFactory( - vscode.debug.activeDebugSession + vscode.debug.activeDebugSession, + messagingService ); vscode.debug.registerDebugAdapterTrackerFactory( "python", diff --git a/src/extension_utils/debugAdapter.ts b/src/extension_utils/debugAdapter.ts index f5b1bd610..3ac42eee1 100644 --- a/src/extension_utils/debugAdapter.ts +++ b/src/extension_utils/debugAdapter.ts @@ -4,13 +4,21 @@ import { DebugSession, DebugConsole, ProviderResult, + Webview, } from "vscode"; import { DebugProtocol } from "vscode-debugprotocol"; +import { MessagingService } from "../service/messagingService"; +import { DEBUG_COMMANDS } from "../view/constants"; export class DebugAdapter implements DebugAdapterTracker { private readonly console: DebugConsole | undefined; - constructor(debugSession: DebugSession) { + private readonly messagingService: MessagingService; + constructor( + debugSession: DebugSession, + messagingService: MessagingService + ) { this.console = debugSession.configuration.console; + this.messagingService = messagingService; } onWillStartSession() { console.log("--debugadapter onWillStartSession"); @@ -18,22 +26,37 @@ export class DebugAdapter implements DebugAdapterTracker { onWillReceiveMessage(message: any): void { console.log("--debugadapter onWillReceiveMessage"); console.log(JSON.stringify(message)); + if (message.command) { + // Only send pertinent debug messages + + if (message.command in DEBUG_COMMANDS) { + this.handleAdapterMessages(message.command); + } + } } onExit() { console.log("--debugadapter onExit"); } + handleAdapterMessages(command: DEBUG_COMMANDS) { + this.messagingService.sendMessageToWebview(command, {}); + } } export class DebugAdapterFactory implements DebugAdapterTrackerFactory { private debugSession: DebugSession; - constructor(debugSession: DebugSession) { + private messagingService: MessagingService; + constructor( + debugSession: DebugSession, + messagingService: MessagingService + ) { console.log("New debug factory"); this.debugSession = debugSession; + this.messagingService = messagingService; } public createDebugAdapterTracker( session: DebugSession ): ProviderResult { console.log("It created an adapter tracker"); - return new DebugAdapter(session); + return new DebugAdapter(session, this.messagingService); } } diff --git a/src/service/messagingService.ts b/src/service/messagingService.ts new file mode 100644 index 000000000..2c39ca209 --- /dev/null +++ b/src/service/messagingService.ts @@ -0,0 +1,16 @@ +import { Webview } from "vscode"; +export class MessagingService { + private currentWebviewTarget: Webview | undefined; + + public setWebview(webview: Webview) { + this.currentWebviewTarget = webview; + } + public sendMessageToWebview(debugCommand: string, state: Object) { + if (this.currentWebviewTarget) { + console.log(`Sending message ${debugCommand}`); + this.currentWebviewTarget.postMessage({ command: debugCommand }); + } else { + console.log(`The webview is not initialized`); + } + } +} From b616a7d55d400513cd633fb2b36c0e5c86ab255b Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Thu, 20 Feb 2020 17:06:26 -0800 Subject: [PATCH 03/13] Send stacktrace message from adapter --- src/view/App.tsx | 20 ++++++++++++++------ src/view/constants.ts | 4 ++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/view/App.tsx b/src/view/App.tsx index b0d26112d..9c4e0802a 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -3,7 +3,11 @@ import * as React from "react"; import "./App.css"; -import { DEVICE_LIST_KEY, VSCODE_MESSAGES_TO_WEBVIEW } from "./constants"; +import { + DEVICE_LIST_KEY, + VSCODE_MESSAGES_TO_WEBVIEW, + DEBUG_COMMANDS, +} from "./constants"; import { Device } from "./container/device/Device"; interface IState { @@ -48,11 +52,15 @@ class App extends React.Component<{}, IState> { handleMessage = (event: any): void => { const message = event.data; console.log(JSON.stringify(message)); - if ( - message.command === VSCODE_MESSAGES_TO_WEBVIEW.SET_DEVICE && - message.active_device !== this.state.currentDevice - ) { - this.setState({ currentDevice: message.active_device }); + switch (message.command) { + case VSCODE_MESSAGES_TO_WEBVIEW.SET_DEVICE: + if (message.active_device !== this.state.currentDevice) { + this.setState({ currentDevice: message.active_device }); + } + break; + case DEBUG_COMMANDS.CONTINUE: + case DEBUG_COMMANDS.STACK_TRACE: + break; } }; } diff --git a/src/view/constants.ts b/src/view/constants.ts index c754441e7..3b2159aa1 100644 --- a/src/view/constants.ts +++ b/src/view/constants.ts @@ -67,5 +67,9 @@ export enum WEBVIEW_MESSAGES { export enum VSCODE_MESSAGES_TO_WEBVIEW { SET_DEVICE = "set-device", } +export enum DEBUG_COMMANDS { + STACK_TRACE = "stackTrace", + CONTINUE = "continue", +} export default CONSTANTS; From 0dec72db897cbda3f58830742ff32c6db1419b77 Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Fri, 21 Feb 2020 08:01:54 -0800 Subject: [PATCH 04/13] Establish connection for debug adapter and webview with the messaging service --- src/extension_utils/debugAdapter.ts | 4 +++- src/view/App.tsx | 17 +++++++++++++++-- src/view/components/Button.tsx | 6 ++++++ src/view/constants.ts | 6 ++++++ src/view/context.ts | 7 +++++++ 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/view/context.ts diff --git a/src/extension_utils/debugAdapter.ts b/src/extension_utils/debugAdapter.ts index 3ac42eee1..d9715cbf9 100644 --- a/src/extension_utils/debugAdapter.ts +++ b/src/extension_utils/debugAdapter.ts @@ -28,8 +28,10 @@ export class DebugAdapter implements DebugAdapterTracker { console.log(JSON.stringify(message)); if (message.command) { // Only send pertinent debug messages + console.log("command exists") + console.log(message.command) - if (message.command in DEBUG_COMMANDS) { + if (Object.values(DEBUG_COMMANDS).includes(message.command)) { this.handleAdapterMessages(message.command); } } diff --git a/src/view/App.tsx b/src/view/App.tsx index 9c4e0802a..3b0be2803 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -7,17 +7,24 @@ import { DEVICE_LIST_KEY, VSCODE_MESSAGES_TO_WEBVIEW, DEBUG_COMMANDS, + VIEW_STATE, } from "./constants"; import { Device } from "./container/device/Device"; +import {ViewStateContext} from './context' interface IState { currentDevice: string; + viewState:VIEW_STATE; } const defaultState = { currentDevice: DEVICE_LIST_KEY.CPX, + viewState:VIEW_STATE.RUNNING }; + + + class App extends React.Component<{}, IState> { constructor() { super({}); @@ -43,15 +50,17 @@ class App extends React.Component<{}, IState> { return (
+ -
+
); } handleMessage = (event: any): void => { const message = event.data; - console.log(JSON.stringify(message)); + console.log( + "blabla"+JSON.stringify(message)); switch (message.command) { case VSCODE_MESSAGES_TO_WEBVIEW.SET_DEVICE: if (message.active_device !== this.state.currentDevice) { @@ -59,7 +68,11 @@ class App extends React.Component<{}, IState> { } break; case DEBUG_COMMANDS.CONTINUE: + this.setState({viewState:VIEW_STATE.RUNNING}) + break; case DEBUG_COMMANDS.STACK_TRACE: + this.setState({viewState:VIEW_STATE.PAUSE}) + break; } }; diff --git a/src/view/components/Button.tsx b/src/view/components/Button.tsx index db5034b9d..4b1f1d080 100644 --- a/src/view/components/Button.tsx +++ b/src/view/components/Button.tsx @@ -1,5 +1,7 @@ import * as React from "react"; import "../styles/Button.css"; +import {ViewStateContext} from '../context' +import { VIEW_STATE } from "../constants"; export interface IButtonProps { label: string; @@ -15,6 +17,9 @@ const Button: React.FC = props => { const iconSvg: SVGElement = props.image as SVGElement; const buttonStyle = { width: props.width }; const tabIndex = props.focusable ? 0 : -1; + const isButtonDisabled = (React.useContext(ViewStateContext) === VIEW_STATE.PAUSE) + console.log(React.useContext(ViewStateContext)) + console.log(isButtonDisabled) return ( diff --git a/src/view/constants.ts b/src/view/constants.ts index 3b2159aa1..18e90f77f 100644 --- a/src/view/constants.ts +++ b/src/view/constants.ts @@ -55,6 +55,12 @@ export enum DEVICE_LIST_KEY { MICROBIT = "micro:bit", } +// Pauses on Debug mode alter the state of the view +export enum VIEW_STATE{ + PAUSE="debug-pause", + RUNNING="running" +} + // export enum WEBVIEW_MESSAGES { SWITCH_DEVICE = "switch-device", diff --git a/src/view/context.ts b/src/view/context.ts new file mode 100644 index 000000000..014156a4f --- /dev/null +++ b/src/view/context.ts @@ -0,0 +1,7 @@ +import * as React from "react"; +import { VIEW_STATE } from "./constants"; + +// View is running by default + +export const ViewStateContext = React.createContext( + VIEW_STATE.RUNNING ) \ No newline at end of file From 6dbfc9d681209ee6191238bb9a0e3a1962810778 Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Fri, 21 Feb 2020 14:57:22 -0800 Subject: [PATCH 05/13] Debug adapter sends start and stop message to webview --- src/debugger/debugAdapter.ts | 38 +++++++++++ src/debugger/debugAdapterFactory.ts | 25 ++++++++ src/extension.ts | 2 +- src/extension_utils/debugAdapter.ts | 64 ------------------- src/service/messagingService.ts | 16 ++++- src/view/App.tsx | 29 ++++----- src/view/components/Button.tsx | 7 +- src/view/components/cpx/CpxSimulator.tsx | 4 -- .../components/microbit/MicrobitSimulator.tsx | 3 - src/view/constants.ts | 8 ++- 10 files changed, 99 insertions(+), 97 deletions(-) create mode 100644 src/debugger/debugAdapter.ts create mode 100644 src/debugger/debugAdapterFactory.ts delete mode 100644 src/extension_utils/debugAdapter.ts diff --git a/src/debugger/debugAdapter.ts b/src/debugger/debugAdapter.ts new file mode 100644 index 000000000..ba9f2e4ec --- /dev/null +++ b/src/debugger/debugAdapter.ts @@ -0,0 +1,38 @@ +import { DebugAdapterTracker, DebugSession, DebugConsole } from "vscode"; +import { MessagingService } from "../service/messagingService"; +import { DEBUG_COMMANDS } from "../view/constants"; + +export class DebugAdapter implements DebugAdapterTracker { + private readonly console: DebugConsole | undefined; + private readonly messagingService: MessagingService; + constructor( + debugSession: DebugSession, + messagingService: MessagingService + ) { + this.console = debugSession.configuration.console; + this.messagingService = messagingService; + } + onWillStartSession() { + // To Implement + } + onWillReceiveMessage(message: any): void { + if (message.command) { + // Only send pertinent debug messages + switch (message.command) { + case DEBUG_COMMANDS.CONTINUE: + this.messagingService.sendStartMessage(); + break; + case DEBUG_COMMANDS.STACK_TRACE: + this.messagingService.sendStopMessage(); + } + } + } + // A debugger error should unlock the webview + onError() { + this.messagingService.sendStartMessage(); + } + // Device is always running when exiting debugging mode + onExit() { + this.messagingService.sendStartMessage(); + } +} diff --git a/src/debugger/debugAdapterFactory.ts b/src/debugger/debugAdapterFactory.ts new file mode 100644 index 000000000..35e2ee285 --- /dev/null +++ b/src/debugger/debugAdapterFactory.ts @@ -0,0 +1,25 @@ +import { + DebugAdapterTracker, + DebugAdapterTrackerFactory, + DebugSession, + ProviderResult, +} from "vscode"; +import { MessagingService } from "../service/messagingService"; +import { DebugAdapter } from "./debugAdapter"; + +export class DebugAdapterFactory implements DebugAdapterTrackerFactory { + private debugSession: DebugSession; + private messagingService: MessagingService; + constructor( + debugSession: DebugSession, + messagingService: MessagingService + ) { + this.debugSession = debugSession; + this.messagingService = messagingService; + } + public createDebugAdapterTracker( + session: DebugSession + ): ProviderResult { + return new DebugAdapter(session, this.messagingService); + } +} diff --git a/src/extension.ts b/src/extension.ts index f217b6721..83a20d126 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -23,7 +23,7 @@ import { SimulatorDebugConfigurationProvider } from "./simulatorDebugConfigurati import TelemetryAI from "./telemetry/telemetryAI"; import { UsbDetector } from "./usbDetector"; import { VSCODE_MESSAGES_TO_WEBVIEW, WEBVIEW_MESSAGES } from "./view/constants"; -import { DebugAdapterFactory } from "./extension_utils/debugAdapter"; +import { DebugAdapterFactory } from "./debugger/debugAdapterFactory"; import { MessagingService } from "./service/messagingService"; let currentFileAbsPath: string = ""; diff --git a/src/extension_utils/debugAdapter.ts b/src/extension_utils/debugAdapter.ts deleted file mode 100644 index d9715cbf9..000000000 --- a/src/extension_utils/debugAdapter.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { - DebugAdapterTracker, - DebugAdapterTrackerFactory, - DebugSession, - DebugConsole, - ProviderResult, - Webview, -} from "vscode"; -import { DebugProtocol } from "vscode-debugprotocol"; -import { MessagingService } from "../service/messagingService"; -import { DEBUG_COMMANDS } from "../view/constants"; - -export class DebugAdapter implements DebugAdapterTracker { - private readonly console: DebugConsole | undefined; - private readonly messagingService: MessagingService; - constructor( - debugSession: DebugSession, - messagingService: MessagingService - ) { - this.console = debugSession.configuration.console; - this.messagingService = messagingService; - } - onWillStartSession() { - console.log("--debugadapter onWillStartSession"); - } - onWillReceiveMessage(message: any): void { - console.log("--debugadapter onWillReceiveMessage"); - console.log(JSON.stringify(message)); - if (message.command) { - // Only send pertinent debug messages - console.log("command exists") - console.log(message.command) - - if (Object.values(DEBUG_COMMANDS).includes(message.command)) { - this.handleAdapterMessages(message.command); - } - } - } - onExit() { - console.log("--debugadapter onExit"); - } - handleAdapterMessages(command: DEBUG_COMMANDS) { - this.messagingService.sendMessageToWebview(command, {}); - } -} - -export class DebugAdapterFactory implements DebugAdapterTrackerFactory { - private debugSession: DebugSession; - private messagingService: MessagingService; - constructor( - debugSession: DebugSession, - messagingService: MessagingService - ) { - console.log("New debug factory"); - this.debugSession = debugSession; - this.messagingService = messagingService; - } - public createDebugAdapterTracker( - session: DebugSession - ): ProviderResult { - console.log("It created an adapter tracker"); - return new DebugAdapter(session, this.messagingService); - } -} diff --git a/src/service/messagingService.ts b/src/service/messagingService.ts index 2c39ca209..6814b3677 100644 --- a/src/service/messagingService.ts +++ b/src/service/messagingService.ts @@ -1,16 +1,26 @@ import { Webview } from "vscode"; +import { VSCODE_MESSAGES_TO_WEBVIEW } from "../view/constants"; export class MessagingService { private currentWebviewTarget: Webview | undefined; public setWebview(webview: Webview) { this.currentWebviewTarget = webview; } + + // Send a message to webview if it exists public sendMessageToWebview(debugCommand: string, state: Object) { if (this.currentWebviewTarget) { - console.log(`Sending message ${debugCommand}`); this.currentWebviewTarget.postMessage({ command: debugCommand }); - } else { - console.log(`The webview is not initialized`); } } + public sendStartMessage() { + this.currentWebviewTarget.postMessage({ + command: VSCODE_MESSAGES_TO_WEBVIEW.RUN_DEVICE, + }); + } + public sendStopMessage() { + this.currentWebviewTarget.postMessage({ + command: VSCODE_MESSAGES_TO_WEBVIEW.PAUSE_DEVICE, + }); + } } diff --git a/src/view/App.tsx b/src/view/App.tsx index 3b0be2803..bcc812456 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -10,21 +10,18 @@ import { VIEW_STATE, } from "./constants"; import { Device } from "./container/device/Device"; -import {ViewStateContext} from './context' +import { ViewStateContext } from "./context"; interface IState { currentDevice: string; - viewState:VIEW_STATE; + viewState: VIEW_STATE; } const defaultState = { currentDevice: DEVICE_LIST_KEY.CPX, - viewState:VIEW_STATE.RUNNING + viewState: VIEW_STATE.RUNNING, }; - - - class App extends React.Component<{}, IState> { constructor() { super({}); @@ -50,28 +47,30 @@ class App extends React.Component<{}, IState> { return (
- - -
+ + + +
); } handleMessage = (event: any): void => { const message = event.data; - console.log( - "blabla"+JSON.stringify(message)); + switch (message.command) { case VSCODE_MESSAGES_TO_WEBVIEW.SET_DEVICE: if (message.active_device !== this.state.currentDevice) { this.setState({ currentDevice: message.active_device }); } break; - case DEBUG_COMMANDS.CONTINUE: - this.setState({viewState:VIEW_STATE.RUNNING}) + case VSCODE_MESSAGES_TO_WEBVIEW.RUN_DEVICE: + this.setState({ viewState: VIEW_STATE.RUNNING }); break; - case DEBUG_COMMANDS.STACK_TRACE: - this.setState({viewState:VIEW_STATE.PAUSE}) + case VSCODE_MESSAGES_TO_WEBVIEW.PAUSE_DEVICE: + this.setState({ viewState: VIEW_STATE.PAUSE }); break; } diff --git a/src/view/components/Button.tsx b/src/view/components/Button.tsx index 4b1f1d080..7ff3e103d 100644 --- a/src/view/components/Button.tsx +++ b/src/view/components/Button.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import "../styles/Button.css"; -import {ViewStateContext} from '../context' +import { ViewStateContext } from "../context"; import { VIEW_STATE } from "../constants"; export interface IButtonProps { @@ -17,9 +17,8 @@ const Button: React.FC = props => { const iconSvg: SVGElement = props.image as SVGElement; const buttonStyle = { width: props.width }; const tabIndex = props.focusable ? 0 : -1; - const isButtonDisabled = (React.useContext(ViewStateContext) === VIEW_STATE.PAUSE) - console.log(React.useContext(ViewStateContext)) - console.log(isButtonDisabled) + const isButtonDisabled = + React.useContext(ViewStateContext) === VIEW_STATE.PAUSE; return ( From b6abfd566b66f8df1108c0d2430e6d6c36bbc597 Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Fri, 21 Feb 2020 15:04:50 -0800 Subject: [PATCH 07/13] Reformatting --- src/debugger/debugAdapter.ts | 2 +- src/debuggerCommunicationServer.ts | 4 ++-- src/extension.ts | 4 ++-- src/view/App.tsx | 4 ++-- src/view/context.ts | 3 +-- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/debugger/debugAdapter.ts b/src/debugger/debugAdapter.ts index ba9f2e4ec..8f0b79273 100644 --- a/src/debugger/debugAdapter.ts +++ b/src/debugger/debugAdapter.ts @@ -1,4 +1,4 @@ -import { DebugAdapterTracker, DebugSession, DebugConsole } from "vscode"; +import { DebugAdapterTracker, DebugConsole, DebugSession } from "vscode"; import { MessagingService } from "../service/messagingService"; import { DEBUG_COMMANDS } from "../view/constants"; diff --git a/src/debuggerCommunicationServer.ts b/src/debuggerCommunicationServer.ts index 307f475ae..adc3eeb9d 100644 --- a/src/debuggerCommunicationServer.ts +++ b/src/debuggerCommunicationServer.ts @@ -26,7 +26,7 @@ export class DebuggerCommunicationServer { private simulatorWebview: WebviewPanel | undefined; private currentActiveDevice; private isWaitingResponse = false; - private currentCall: Array = []; + private currentCall: Function[] = []; constructor( webviewPanel: WebviewPanel | undefined, @@ -92,7 +92,7 @@ export class DebuggerCommunicationServer { socket.on(DEBUGGER_MESSAGES.LISTENER.RECEIVED_STATE, () => { this.isWaitingResponse = false; if (this.currentCall.length > 0) { - let currentCall = this.currentCall.shift(); + const currentCall = this.currentCall.shift(); currentCall(); } }); diff --git a/src/extension.ts b/src/extension.ts index 83a20d126..6290b21cd 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -16,15 +16,15 @@ import { TelemetryEventName, } from "./constants"; import { CPXWorkspace } from "./cpxWorkspace"; +import { DebugAdapterFactory } from "./debugger/debugAdapterFactory"; import { DebuggerCommunicationServer } from "./debuggerCommunicationServer"; import * as utils from "./extension_utils/utils"; import { SerialMonitor } from "./serialMonitor"; +import { MessagingService } from "./service/messagingService"; import { SimulatorDebugConfigurationProvider } from "./simulatorDebugConfigurationProvider"; import TelemetryAI from "./telemetry/telemetryAI"; import { UsbDetector } from "./usbDetector"; import { VSCODE_MESSAGES_TO_WEBVIEW, WEBVIEW_MESSAGES } from "./view/constants"; -import { DebugAdapterFactory } from "./debugger/debugAdapterFactory"; -import { MessagingService } from "./service/messagingService"; let currentFileAbsPath: string = ""; let currentTextDocument: vscode.TextDocument; diff --git a/src/view/App.tsx b/src/view/App.tsx index bcc812456..49bc59b93 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -4,10 +4,10 @@ import * as React from "react"; import "./App.css"; import { - DEVICE_LIST_KEY, - VSCODE_MESSAGES_TO_WEBVIEW, DEBUG_COMMANDS, + DEVICE_LIST_KEY, VIEW_STATE, + VSCODE_MESSAGES_TO_WEBVIEW, } from "./constants"; import { Device } from "./container/device/Device"; import { ViewStateContext } from "./context"; diff --git a/src/view/context.ts b/src/view/context.ts index 014156a4f..24fafc556 100644 --- a/src/view/context.ts +++ b/src/view/context.ts @@ -3,5 +3,4 @@ import { VIEW_STATE } from "./constants"; // View is running by default -export const ViewStateContext = React.createContext( - VIEW_STATE.RUNNING ) \ No newline at end of file +export const ViewStateContext = React.createContext(VIEW_STATE.RUNNING); From 1f977c4101a87040e419edac3a930e8a7d234ae3 Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Fri, 21 Feb 2020 16:37:19 -0800 Subject: [PATCH 08/13] Pause input if on breakpoint --- src/view/components/toolbar/InputSlider.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/view/components/toolbar/InputSlider.tsx b/src/view/components/toolbar/InputSlider.tsx index 260be15c9..2ed12a64b 100644 --- a/src/view/components/toolbar/InputSlider.tsx +++ b/src/view/components/toolbar/InputSlider.tsx @@ -2,10 +2,11 @@ // Licensed under the MIT license. import * as React from "react"; -import { WEBVIEW_MESSAGES } from "../../constants"; +import { WEBVIEW_MESSAGES, VIEW_STATE } from "../../constants"; import "../../styles/InputSlider.css"; import { sendMessage } from "../../utils/MessageUtils"; import { ISliderProps } from "../../viewUtils"; +import { ViewStateContext } from "../../context"; class InputSlider extends React.Component { constructor(props: ISliderProps) { @@ -24,20 +25,10 @@ class InputSlider extends React.Component { case "reset-state": this.setState({ value: 0 }); break; - case "set-state": - console.log( - "Setting the state: " + JSON.stringify(message.state) - ); - break; - default: - console.log("Invalid message received from the extension."); - this.setState({ value: 0 }); - break; } }; componentDidMount() { - console.log("Mounted"); window.addEventListener("message", this.handleMessage); } @@ -46,6 +37,7 @@ class InputSlider extends React.Component { window.removeEventListener("message", this.handleMessage); } render() { + const isInputDisabled = this.context === VIEW_STATE.PAUSE; return (
{this.props.axisLabel} @@ -78,6 +70,7 @@ class InputSlider extends React.Component { value={this.state.value} aria-label={`${this.props.type} sensor slider`} defaultValue={this.props.minValue.toLocaleString()} + disabled={isInputDisabled} /> {this.props.minLabel} @@ -131,5 +124,6 @@ class InputSlider extends React.Component { return valueInt; }; } +InputSlider.contextType = ViewStateContext; export default InputSlider; From 44daa1384640a64cf9d50e168664678ad097eb4d Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Mon, 24 Feb 2020 10:20:55 -0800 Subject: [PATCH 09/13] Freeze buttons on svg --- package-lock.json | 5 --- package.json | 1 - .../components/microbit/MicrobitImage.tsx | 40 +++++++++++++++++-- src/view/components/microbit/Microbit_svg.tsx | 2 +- src/view/styles/Microbit.css | 5 +-- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index f45d1d7dd..7b8613ef0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30942,11 +30942,6 @@ } } }, - "vscode-debugprotocol": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.28.0.tgz", - "integrity": "sha512-QM4J8A13jBY9I7OPWXN0ZO1cqydnD4co2j/O81jIj6em8VkmJT4VyJQkq4HmwJe3af+u9+7IYCIEDrowgvKxTA==" - }, "vscode-extension-telemetry": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz", diff --git a/package.json b/package.json index b69b30630..d1e6d3add 100644 --- a/package.json +++ b/package.json @@ -313,7 +313,6 @@ "svg-inline-react": "^3.1.0", "ts-jest": "^25.0.0", "util": "^0.12.1", - "vscode-debugprotocol": "^1.28.0", "vscode-extension-telemetry": "^0.1.1", "vscode-nls": "^4.1.0" }, diff --git a/src/view/components/microbit/MicrobitImage.tsx b/src/view/components/microbit/MicrobitImage.tsx index df62aa509..b3344f70e 100644 --- a/src/view/components/microbit/MicrobitImage.tsx +++ b/src/view/components/microbit/MicrobitImage.tsx @@ -3,7 +3,9 @@ import * as React from "react"; import "../../styles/Microbit.css"; -import { MicrobitSvg } from "./Microbit_svg"; +import { MicrobitSvg, IRefObject } from "./Microbit_svg"; +import { ViewStateContext } from "../../context"; +import { VIEW_STATE } from "../../constants"; interface EventTriggers { onMouseUp: (event: Event, buttonKey: string) => void; @@ -15,6 +17,11 @@ interface IProps { leds: number[][]; } +const BUTTON_CLASSNAME = { + ACTIVE: "sim-button-outer", + DEACTIVATED: "sim-button-deactivated", +}; + // Displays the SVG and call necessary svg modification. export class MicrobitImage extends React.Component { private svgRef: React.RefObject = React.createRef(); @@ -31,17 +38,28 @@ export class MicrobitImage extends React.Component { componentDidUpdate() { if (this.svgRef.current) { updateAllLeds(this.props.leds, this.svgRef.current.getLeds()); + if (this.context === VIEW_STATE.PAUSE) { + disableAllButtons(this.svgRef.current.getButtons()); + } else if (this.context === VIEW_STATE.RUNNING) { + setupAllButtons( + this.props.eventTriggers, + this.svgRef.current.getButtons() + ); + } } } render() { return ; } } + +MicrobitImage.contextType = ViewStateContext; const setupButton = ( - buttonElement: HTMLElement, + buttonElement: SVGRectElement, eventTriggers: EventTriggers, key: string ) => { + buttonElement.setAttribute("class", BUTTON_CLASSNAME.ACTIVE); buttonElement.onmousedown = e => { eventTriggers.onMouseDown(e, key); }; @@ -51,14 +69,30 @@ const setupButton = ( buttonElement.onmouseleave = e => { eventTriggers.onMouseLeave(e, key); }; + console.log("buttons should be enabled"); }; -const setupAllButtons = (eventTriggers: EventTriggers, buttonRefs: Object) => { +const setupAllButtons = ( + eventTriggers: EventTriggers, + buttonRefs: IRefObject +) => { for (const [key, ref] of Object.entries(buttonRefs)) { if (ref.current) { setupButton(ref.current, eventTriggers, key); } } }; +const disableAllButtons = (buttonRefs: IRefObject) => { + for (const [key, ref] of Object.entries(buttonRefs)) { + if (ref.current) { + // to implement + ref.current.onmousedown = null; + ref.current.onmouseup = null; + ref.current.onmouseleave = null; + ref.current.setAttribute("class", BUTTON_CLASSNAME.DEACTIVATED); + console.log("buttons should be disabled"); + } + } +}; const updateAllLeds = ( leds: number[][], ledRefs: Array>> diff --git a/src/view/components/microbit/Microbit_svg.tsx b/src/view/components/microbit/Microbit_svg.tsx index 1cb00bfd4..3cfe352e1 100644 --- a/src/view/components/microbit/Microbit_svg.tsx +++ b/src/view/components/microbit/Microbit_svg.tsx @@ -4,7 +4,7 @@ // Adapted from : https://makecode.microbit.org/#editor import * as React from "react"; -interface IRefObject { +export interface IRefObject { [key: string]: React.RefObject; } /* tslint:disable */ diff --git a/src/view/styles/Microbit.css b/src/view/styles/Microbit.css index 8c4f20f2c..251839d5e 100644 --- a/src/view/styles/Microbit.css +++ b/src/view/styles/Microbit.css @@ -22,6 +22,7 @@ svg.sim.grayscale { .sim-button:active { fill: orange; } + .sim-board, .sim-display, sim-button { @@ -146,10 +147,6 @@ sim-button { .sim-pin:focus, .sim-thermometer:focus, .sim-shake:focus, -.sim-light-level-button:focus { - stroke: #4d90fe; - stroke-width: 5px !important; -} .no-drag, .sim-text, .sim-text-pin { From 13472b9f47476ab4fe16a69b41248f874554f0ae Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Tue, 25 Feb 2020 08:24:43 -0800 Subject: [PATCH 10/13] Remove unused imports --- src/debuggerCommunicationServer.ts | 2 +- src/view/App.tsx | 1 - src/view/components/microbit/MicrobitImage.tsx | 8 ++++---- src/view/components/toolbar/InputSlider.tsx | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/debuggerCommunicationServer.ts b/src/debuggerCommunicationServer.ts index 1d73b8c29..20627b260 100644 --- a/src/debuggerCommunicationServer.ts +++ b/src/debuggerCommunicationServer.ts @@ -26,7 +26,7 @@ export class DebuggerCommunicationServer { private simulatorWebview: WebviewPanel | undefined; private currentActiveDevice; private isPendingResponse = false; - private pendingCallbacks: Array = []; + private pendingCallbacks: Function[] = []; constructor( webviewPanel: WebviewPanel | undefined, diff --git a/src/view/App.tsx b/src/view/App.tsx index 49bc59b93..670fc211a 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -4,7 +4,6 @@ import * as React from "react"; import "./App.css"; import { - DEBUG_COMMANDS, DEVICE_LIST_KEY, VIEW_STATE, VSCODE_MESSAGES_TO_WEBVIEW, diff --git a/src/view/components/microbit/MicrobitImage.tsx b/src/view/components/microbit/MicrobitImage.tsx index b3344f70e..5f55bd214 100644 --- a/src/view/components/microbit/MicrobitImage.tsx +++ b/src/view/components/microbit/MicrobitImage.tsx @@ -2,10 +2,10 @@ // Licensed under the MIT license. import * as React from "react"; -import "../../styles/Microbit.css"; -import { MicrobitSvg, IRefObject } from "./Microbit_svg"; -import { ViewStateContext } from "../../context"; import { VIEW_STATE } from "../../constants"; +import { ViewStateContext } from "../../context"; +import "../../styles/Microbit.css"; +import { IRefObject, MicrobitSvg } from "./Microbit_svg"; interface EventTriggers { onMouseUp: (event: Event, buttonKey: string) => void; @@ -82,7 +82,7 @@ const setupAllButtons = ( } }; const disableAllButtons = (buttonRefs: IRefObject) => { - for (const [key, ref] of Object.entries(buttonRefs)) { + for (const [, ref] of Object.entries(buttonRefs)) { if (ref.current) { // to implement ref.current.onmousedown = null; diff --git a/src/view/components/toolbar/InputSlider.tsx b/src/view/components/toolbar/InputSlider.tsx index 2ed12a64b..db917a845 100644 --- a/src/view/components/toolbar/InputSlider.tsx +++ b/src/view/components/toolbar/InputSlider.tsx @@ -2,11 +2,11 @@ // Licensed under the MIT license. import * as React from "react"; -import { WEBVIEW_MESSAGES, VIEW_STATE } from "../../constants"; +import { VIEW_STATE, WEBVIEW_MESSAGES } from "../../constants"; +import { ViewStateContext } from "../../context"; import "../../styles/InputSlider.css"; import { sendMessage } from "../../utils/MessageUtils"; import { ISliderProps } from "../../viewUtils"; -import { ViewStateContext } from "../../context"; class InputSlider extends React.Component { constructor(props: ISliderProps) { From af212b4a233cd7a5c09d21998a4c2f7b2a4588d3 Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Tue, 25 Feb 2020 12:24:14 -0800 Subject: [PATCH 11/13] Function renaming in messaging service --- src/service/messagingService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/messagingService.ts b/src/service/messagingService.ts index 6814b3677..9e37f20a8 100644 --- a/src/service/messagingService.ts +++ b/src/service/messagingService.ts @@ -18,7 +18,7 @@ export class MessagingService { command: VSCODE_MESSAGES_TO_WEBVIEW.RUN_DEVICE, }); } - public sendStopMessage() { + public sendPauseMessage() { this.currentWebviewTarget.postMessage({ command: VSCODE_MESSAGES_TO_WEBVIEW.PAUSE_DEVICE, }); From 6f983b7c7510b7a0c7e0728de9bd9eca170c1d03 Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Tue, 25 Feb 2020 16:47:38 -0800 Subject: [PATCH 12/13] Rename function call --- src/debugger/debugAdapter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debugger/debugAdapter.ts b/src/debugger/debugAdapter.ts index 8f0b79273..d801ac098 100644 --- a/src/debugger/debugAdapter.ts +++ b/src/debugger/debugAdapter.ts @@ -23,7 +23,7 @@ export class DebugAdapter implements DebugAdapterTracker { this.messagingService.sendStartMessage(); break; case DEBUG_COMMANDS.STACK_TRACE: - this.messagingService.sendStopMessage(); + this.messagingService.sendPauseMessage(); } } } From 3dd3d112844c7a2ccf2f1c99845d031adefcd60c Mon Sep 17 00:00:00 2001 From: xnkevinnguyen Date: Tue, 25 Feb 2020 17:10:44 -0800 Subject: [PATCH 13/13] Remove console.log --- src/view/App.tsx | 1 - src/view/components/microbit/MicrobitImage.tsx | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/view/App.tsx b/src/view/App.tsx index 670fc211a..eb9da7b02 100644 --- a/src/view/App.tsx +++ b/src/view/App.tsx @@ -70,7 +70,6 @@ class App extends React.Component<{}, IState> { break; case VSCODE_MESSAGES_TO_WEBVIEW.PAUSE_DEVICE: this.setState({ viewState: VIEW_STATE.PAUSE }); - break; } }; diff --git a/src/view/components/microbit/MicrobitImage.tsx b/src/view/components/microbit/MicrobitImage.tsx index 5f55bd214..d06f4d0e4 100644 --- a/src/view/components/microbit/MicrobitImage.tsx +++ b/src/view/components/microbit/MicrobitImage.tsx @@ -69,7 +69,6 @@ const setupButton = ( buttonElement.onmouseleave = e => { eventTriggers.onMouseLeave(e, key); }; - console.log("buttons should be enabled"); }; const setupAllButtons = ( eventTriggers: EventTriggers, @@ -89,7 +88,6 @@ const disableAllButtons = (buttonRefs: IRefObject) => { ref.current.onmouseup = null; ref.current.onmouseleave = null; ref.current.setAttribute("class", BUTTON_CLASSNAME.DEACTIVATED); - console.log("buttons should be disabled"); } } };