Skip to content

Commit

Permalink
Refine disconnect behavior
Browse files Browse the repository at this point in the history
Signed-off-by: paulober <[email protected]>
  • Loading branch information
paulober committed Jan 17, 2025
1 parent c3c88cd commit 7aa0bdb
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 36 deletions.
121 changes: 90 additions & 31 deletions src/activator.mts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Stubs, {
} from "./stubs.mjs";
import Settings, { SettingsKey } from "./settings.mjs";
import Logger from "./logger.mjs";
import { basename, dirname, join } from "path";
import { basename, dirname, extname, join } from "path";
import { PicoRemoteFileSystem } from "./filesystem.mjs";
import { Terminal } from "./terminal.mjs";
import { fileURLToPath } from "url";
Expand Down Expand Up @@ -64,6 +64,8 @@ export default class Activator {
private outputRedirectionTarget?: string;
private commandExecuting = false;

private disableExtWarning = false;

constructor() {
this.logger = new Logger("Activator");
}
Expand Down Expand Up @@ -426,14 +428,51 @@ export default class Activator {
// [Command] Connect
disposable = vscode.commands.registerCommand(
commandPrefix + "connect",
() => {
/*this.comDevice = await this.settings?.getComDevice();
if (this.comDevice !== undefined) {
this.ui?.init();
// TODO: verify that this does allow smooth transition between serialport devices
await PicoMpyCom.getInstance().openSerialPort(this.comDevice);
}*/
this.setupAutoConnect();
async () => {
/*
this.comDevice = await this.settings?.getComDevice();
if (this.comDevice === undefined) {
if (this.settings?.getBoolean(SettingsKey.autoConnect)) {
void vscode.window.showErrorMessage(
"No COM device found! Starting auto connect..."
);
}
} else {
this.ui?.init();
// TODO: check if this is a smooth transition between serialport devices
await PicoMpyCom.getInstance().openSerialPort(this.comDevice);
}
this.setupAutoConnect();
*/
if (!this.setupAutoConnect()) {
// auto connect is probably disable and no manual com device is set
const boards = await PicoMpyCom.getSerialPorts();
if (boards.length > 1) {
const comDevice = await vscode.window.showQuickPick(boards, {
placeHolder: "Select the board to connect to",
canPickMany: false,
ignoreFocusOut: false,
title: "Connect to Micropython board",
});

if (comDevice !== undefined) {
this.comDevice = comDevice;
await PicoMpyCom.getInstance().openSerialPort(comDevice);
}

return;
} else {
if (boards.length === 1) {
this.comDevice = boards[0];
await PicoMpyCom.getInstance().openSerialPort(boards[0]);
} else {
void vscode.window.showWarningMessage(
"No board running MicroPython has been found."
);
await this.checkForUSBMSDs();
}
}
}
}
);
context.subscriptions.push(disposable);
Expand All @@ -442,9 +481,14 @@ export default class Activator {
disposable = vscode.commands.registerCommand(
commandPrefix + "disconnect",
async () => {
clearInterval(this.autoConnectTimer);
this.intentionalDisconnect = true;
await PicoMpyCom.getInstance().closeSerialPort();
if (!PicoMpyCom.getInstance().isPortDisconnected()) {
clearInterval(this.autoConnectTimer);
this.intentionalDisconnect = true;
this.ui?.setDisconnecting();
// wait 1500ms
await new Promise(resolve => setTimeout(resolve, 1500));
await PicoMpyCom.getInstance().closeSerialPort();
}
}
);
context.subscriptions.push(disposable);
Expand Down Expand Up @@ -478,6 +522,26 @@ export default class Activator {
return;
}
}

// check file extension
if (
!this.disableExtWarning &&
![".py", ".mpy"].includes(extname(file))
) {
// warn it's not a python file do you still want to run it
const choice = await vscode.window.showWarningMessage(
"The selected file is not a Python file. " +
"Do you still want to run it?",
"Yes",
"No",
"Yes, don't show this again"
);

if (choice !== "Yes") {
return;
}
}

const forceDisableSoftReset =
this.settings?.getBoolean(SettingsKey.noSoftResetOnRun) ?? false;

Expand Down Expand Up @@ -1097,23 +1161,16 @@ export default class Activator {
// [Command] Toggle connection
disposable = vscode.commands.registerCommand(
commandPrefix + "toggleConnect",
async () => {
() => {
// don't allow reconnect before port has been closed properly
if (this.intentionalDisconnect) {
return;
}

if (!PicoMpyCom.getInstance().isPortDisconnected()) {
clearInterval(this.autoConnectTimer);
this.intentionalDisconnect = true;
await PicoMpyCom.getInstance().closeSerialPort();
void vscode.commands.executeCommand(commandPrefix + "disconnect");
} else {
this.comDevice = await this.settings?.getComDevice();
if (this.comDevice === undefined) {
void vscode.window.showErrorMessage(
"No COM device found! Starting auto connect..."
);
} else {
this.ui?.init();
// TODO: check if this is a smooth transition between serialport devices
await PicoMpyCom.getInstance().openSerialPort(this.comDevice);
}
this.setupAutoConnect();
void vscode.commands.executeCommand(commandPrefix + "connect");
}
}
);
Expand Down Expand Up @@ -1785,17 +1842,17 @@ export default class Activator {
*/
private intentionalDisconnect = false;

private setupAutoConnect(): void {
private setupAutoConnect(): boolean {
if (this.intentionalDisconnect) {
this.intentionalDisconnect = false;
// TODO: maybe also remove listeners here

return;
return false;
}
if (this.settings === undefined) {
this.logger.error("Settings not provided for setupAutoConnect");

return;
return false;
}
// if disconnected: check in a reasonable interval if a port is available and then connect
// else: just subscribe to the closed event once and if it is triggered start the disconnected
Expand All @@ -1818,7 +1875,7 @@ export default class Activator {
0 &&
!this.settings.getBoolean(SettingsKey.autoConnect)
) {
return;
return false;
}

const onAutoConnect = (): void => {
Expand Down Expand Up @@ -1898,6 +1955,8 @@ export default class Activator {
onAutoConnect();
// setup interval
this.autoConnectTimer = setInterval(onAutoConnect, 1500);

return true;
}

private async checkForUSBMSDs(): Promise<void> {
Expand Down
11 changes: 7 additions & 4 deletions src/flash.mts
Original file line number Diff line number Diff line change
Expand Up @@ -149,18 +149,21 @@ export async function flashPicoInteractively(

if (devices !== undefined) {
const result = await window.showInformationMessage(
"Found a connected Pico in BOOTSEL mode. Before you can use it with " +
"this extension, you need to flash the MicroPython firmware to it. " +
"Do you want to flash it now? (Raspberry Pi boards only)",
"Found a connected Pico in BOOTSEL mode. Before using it with " +
"this extension, you need to flash the MicroPython firmware. " +
"Do you want to flash it now? " +
"(Auto-flash for Raspberry Pi boards only)",
"Yes",
"Flash manually",
"Search only for MicroPython boards"
"Don't ask again"
);

if (result !== "Yes") {
if (result === "Flash manually") {
// open micropython download website
void env.openExternal(Uri.parse("https://micropython.org/download/"));

// TODO: maybe also search for drive and open it in system file explorer
}

//this.noCheckForUSBMSDs = true;
Expand Down
6 changes: 5 additions & 1 deletion src/ui.mts
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,15 @@ export default class UI {
this.lastState = connected;
this.setButton(
"status",
connected ? "check" : "chrome-close",
connected ? "check" : "debug-disconnect",
connected ? "Pico Connected" : "Pico Disconnected"
);
}

public setDisconnecting(): void {
this.setButton("status", "watch", "Closing port...");
}

public getState(): boolean {
return this.lastState;
}
Expand Down

0 comments on commit 7aa0bdb

Please sign in to comment.