Skip to content
This repository has been archived by the owner on Dec 23, 2021. It is now read-only.

Commit

Permalink
Improvements from bug bash comments (#56)
Browse files Browse the repository at this point in the history
[PBI:30845]

* Resetting to switch state to off

* Changing the wording for code deployement to device

* Indicating which file is selected for deployement in the output panel

* Allowing Python processes to be spawned only if a file as been selected

* Killing the process when closing the webview
  • Loading branch information
Christellah authored Jul 18, 2019
1 parent addc1b1 commit 67357da
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 157 deletions.
8 changes: 7 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,18 @@ export const CONSTANTS = {
),
DEPLOY_SUCCESS: localize(
"info.deploySuccess",
"\n[INFO] Code successfully deployed\n"
"\n[INFO] Code successfully copied! Your Circuit Playground Express should be loading and ready to go shortly.\n"
),
EXTENSION_ACTIVATED: localize(
"info.extensionActivated",
"Congratulations, your extension Adafruit_Simulator is now active!"
),
FILE_SELECTED: (filePath: string) => {
return localize(
"info.fileSelected",
`[INFO] File selected : ${filePath} \n`
);
},
FIRST_TIME_WEBVIEW: localize(
"info.firstTimeWebview",
'To reopen the simulator click on the "Open Simulator" button on the upper right corner of the text editor, or select the command "Open Simulator" from command palette.'
Expand Down
279 changes: 142 additions & 137 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export function activate(context: vscode.ExtensionContext) {
currentPanel.onDidDispose(
() => {
currentPanel = undefined;
killProcessIfRunning();
if (firstTimeClosed) {
vscode.window.showInformationMessage(
CONSTANTS.INFO.FIRST_TIME_WEBVIEW
Expand Down Expand Up @@ -217,78 +218,80 @@ export function activate(context: vscode.ExtensionContext) {

logToOutputChannel(outChannel, CONSTANTS.INFO.DEPLOY_SIMULATOR);

const activeTextEditor: vscode.TextEditor | undefined =
vscode.window.activeTextEditor;
killProcessIfRunning();

updateCurrentFileIfPython(activeTextEditor);
updateCurrentFileIfPython(vscode.window.activeTextEditor);

if (currentFileAbsPath === "") {
logToOutputChannel(outChannel, CONSTANTS.ERROR.NO_FILE_TO_RUN, true);
}

killProcessIfRunning();

childProcess = cp.spawn("python", [
utils.getPathToScript(context, "out", "process_user_code.py"),
currentFileAbsPath
]);

let dataFromTheProcess = "";
let oldMessage = "";
} else {
logToOutputChannel(
outChannel,
CONSTANTS.INFO.FILE_SELECTED(currentFileAbsPath)
);

// Data received from Python process
childProcess.stdout.on("data", data => {
dataFromTheProcess = data.toString();
if (currentPanel) {
// Process the data from the process and send one state at a time
dataFromTheProcess.split("\0").forEach(message => {
if (currentPanel && message.length > 0 && message != oldMessage) {
oldMessage = message;
let messageToWebview;
// Check the message is a JSON
try {
messageToWebview = JSON.parse(message);
// Check the JSON is a state
switch (messageToWebview.type) {
case "state":
console.log(
`Process state output = ${messageToWebview.data}`
);
currentPanel.webview.postMessage({
command: "set-state",
state: JSON.parse(messageToWebview.data)
});
break;

default:
console.log(
`Non-state JSON output from the process : ${messageToWebview}`
);
break;
childProcess = cp.spawn("python", [
utils.getPathToScript(context, "out", "process_user_code.py"),
currentFileAbsPath
]);

let dataFromTheProcess = "";
let oldMessage = "";

// Data received from Python process
childProcess.stdout.on("data", data => {
dataFromTheProcess = data.toString();
if (currentPanel) {
// Process the data from the process and send one state at a time
dataFromTheProcess.split("\0").forEach(message => {
if (currentPanel && message.length > 0 && message != oldMessage) {
oldMessage = message;
let messageToWebview;
// Check the message is a JSON
try {
messageToWebview = JSON.parse(message);
// Check the JSON is a state
switch (messageToWebview.type) {
case "state":
console.log(
`Process state output = ${messageToWebview.data}`
);
currentPanel.webview.postMessage({
command: "set-state",
state: JSON.parse(messageToWebview.data)
});
break;

default:
console.log(
`Non-state JSON output from the process : ${messageToWebview}`
);
break;
}
} catch (err) {
console.log(`Non-JSON output from the process : ${message}`);
}
} catch (err) {
console.log(`Non-JSON output from the process : ${message}`);
}
}
});
}
});

// Std error output
childProcess.stderr.on("data", data => {
console.error(`Error from the Python process through stderr: ${data}`);
TelemetryAI.trackFeatureUsage(TelemetryEventName.ERROR_PYTHON_PROCESS);
logToOutputChannel(outChannel, CONSTANTS.ERROR.STDERR(data), true);
if (currentPanel) {
console.log("Sending clearing state command");
currentPanel.webview.postMessage({ command: "reset-state" });
}
});
});
}
});

// Std error output
childProcess.stderr.on("data", data => {
console.error(`Error from the Python process through stderr: ${data}`);
TelemetryAI.trackFeatureUsage(TelemetryEventName.ERROR_PYTHON_PROCESS);
logToOutputChannel(outChannel, CONSTANTS.ERROR.STDERR(data), true);
if (currentPanel) {
console.log("Sending clearing state command");
currentPanel.webview.postMessage({ command: "reset-state" });
}
});

// When the process is done
childProcess.on("end", (code: number) => {
console.info(`Command execution exited with code: ${code}`);
});
// When the process is done
childProcess.on("end", (code: number) => {
console.info(`Command execution exited with code: ${code}`);
});
}
};

// Send message to the webview
Expand All @@ -304,86 +307,88 @@ export function activate(context: vscode.ExtensionContext) {

logToOutputChannel(outChannel, CONSTANTS.INFO.DEPLOY_DEVICE);

const activeTextEditor: vscode.TextEditor | undefined =
vscode.window.activeTextEditor;

updateCurrentFileIfPython(activeTextEditor);
updateCurrentFileIfPython(vscode.window.activeTextEditor);

if (currentFileAbsPath === "") {
logToOutputChannel(outChannel, CONSTANTS.ERROR.NO_FILE_TO_RUN, true);
}

const deviceProcess = cp.spawn("python", [
utils.getPathToScript(context, "out", "device.py"),
currentFileAbsPath
]);

let dataFromTheProcess = "";

// Data received from Python process
deviceProcess.stdout.on("data", data => {
dataFromTheProcess = data.toString();
console.log(`Device output = ${dataFromTheProcess}`);
let messageToWebview;
try {
messageToWebview = JSON.parse(dataFromTheProcess);
// Check the JSON is a state
switch (messageToWebview.type) {
case "complete":
TelemetryAI.trackFeatureUsage(
TelemetryEventName.SUCCESS_COMMAND_DEPLOY_DEVICE
);
logToOutputChannel(outChannel, CONSTANTS.INFO.DEPLOY_SUCCESS);
break;

case "no-device":
TelemetryAI.trackFeatureUsage(
TelemetryEventName.ERROR_DEPLOY_WITHOUT_DEVICE
);
vscode.window
.showErrorMessage(
CONSTANTS.ERROR.NO_DEVICE,
...[DialogResponses.HELP]
)
.then((selection: vscode.MessageItem | undefined) => {
if (selection === DialogResponses.HELP) {
TelemetryAI.trackFeatureUsage(
TelemetryEventName.CLICK_DIALOG_HELP_DEPLOY_TO_DEVICE
);
open(CONSTANTS.LINKS.HELP);
}
});
break;
} else {
logToOutputChannel(
outChannel,
CONSTANTS.INFO.FILE_SELECTED(currentFileAbsPath)
);

default:
console.log(
`Non-state JSON output from the process : ${messageToWebview}`
);
break;
const deviceProcess = cp.spawn("python", [
utils.getPathToScript(context, "out", "device.py"),
currentFileAbsPath
]);

let dataFromTheProcess = "";

// Data received from Python process
deviceProcess.stdout.on("data", data => {
dataFromTheProcess = data.toString();
console.log(`Device output = ${dataFromTheProcess}`);
let messageToWebview;
try {
messageToWebview = JSON.parse(dataFromTheProcess);
// Check the JSON is a state
switch (messageToWebview.type) {
case "complete":
TelemetryAI.trackFeatureUsage(
TelemetryEventName.SUCCESS_COMMAND_DEPLOY_DEVICE
);
logToOutputChannel(outChannel, CONSTANTS.INFO.DEPLOY_SUCCESS);
break;

case "no-device":
TelemetryAI.trackFeatureUsage(
TelemetryEventName.ERROR_DEPLOY_WITHOUT_DEVICE
);
vscode.window
.showErrorMessage(
CONSTANTS.ERROR.NO_DEVICE,
...[DialogResponses.HELP]
)
.then((selection: vscode.MessageItem | undefined) => {
if (selection === DialogResponses.HELP) {
TelemetryAI.trackFeatureUsage(
TelemetryEventName.CLICK_DIALOG_HELP_DEPLOY_TO_DEVICE
);
open(CONSTANTS.LINKS.HELP);
}
});
break;

default:
console.log(
`Non-state JSON output from the process : ${messageToWebview}`
);
break;
}
} catch (err) {
console.log(
`Non-JSON output from the process : ${dataFromTheProcess}`
);
}
} catch (err) {
console.log(
`Non-JSON output from the process : ${dataFromTheProcess}`
);
}
});
});

// Std error output
deviceProcess.stderr.on("data", data => {
TelemetryAI.trackFeatureUsage(
TelemetryEventName.ERROR_PYTHON_DEVICE_PROCESS,
{ error: `${data}` }
);
console.error(
`Error from the Python device process through stderr: ${data}`
);
logToOutputChannel(outChannel, `[ERROR] ${data} \n`, true);
});
// Std error output
deviceProcess.stderr.on("data", data => {
TelemetryAI.trackFeatureUsage(
TelemetryEventName.ERROR_PYTHON_DEVICE_PROCESS,
{ error: `${data}` }
);
console.error(
`Error from the Python device process through stderr: ${data}`
);
logToOutputChannel(outChannel, `[ERROR] ${data} \n`, true);
});

// When the process is done
deviceProcess.on("end", (code: number) => {
console.info(`Command execution exited with code: ${code}`);
});
// When the process is done
deviceProcess.on("end", (code: number) => {
console.info(`Command execution exited with code: ${code}`);
});
}
};

const runDevice: vscode.Disposable = vscode.commands.registerCommand(
Expand Down
19 changes: 2 additions & 17 deletions src/view/components/Simulator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@

import * as React from "react";
import { BUTTON_NEUTRAL, BUTTON_PRESSED } from "./cpx/Cpx_svg_style";
import Cpx from "./cpx/Cpx";
import svg from "./cpx/Svg_utils";
import Cpx, { updateSwitch } from "./cpx/Cpx";

interface IState {
pixels: Array<Array<number>>;
Expand Down Expand Up @@ -184,23 +183,9 @@ class Simulator extends React.Component<any, IState> {
}

private handleSwitchClick(button: HTMLElement) {
const switchInner = (window.document.getElementById(
"SWITCH_INNER"
) as unknown) as SVGElement;

svg.addClass(switchInner, "sim-slide-switch-inner");

const switchIsOn: boolean = !this.state.switch;

if (switchIsOn) {
svg.addClass(switchInner, "on");
switchInner.setAttribute("transform", "translate(-5,0)");
} else {
svg.removeClass(switchInner, "on");
switchInner.removeAttribute("transform");
}
updateSwitch(switchIsOn);
this.setState({ switch: switchIsOn });
button.setAttribute("aria-pressed", switchIsOn.toString());
return { switch: switchIsOn };
}
}
Expand Down
Loading

0 comments on commit 67357da

Please sign in to comment.