Fix debug server not closing properly, fix set breakpoints before project path is set (#183)

This commit is contained in:
Francois Belair
2020-09-08 09:56:00 -04:00
committed by GitHub
parent d3914bceaf
commit d2d7813312
7 changed files with 52 additions and 35 deletions

View File

@@ -21,7 +21,7 @@ experience as comfortable as possible:
- Ctrl + click on a variable or method call to jump to its definition - Ctrl + click on a variable or method call to jump to its definition
- Full documentation of the Godot Engine's API supported - Full documentation of the Godot Engine's API supported
- Run a Godot project from VS Code - Run a Godot project from VS Code
- Debug your Godot project from VS Code with breakpoints, step-in/out/over, variable watch, call stack, and active scene tree - Debug your GDScript-based Godot project from VS Code with breakpoints, step-in/out/over, variable watch, call stack, and active scene tree
![Showing the documentation on hover feature](img/godot-tools.png) ![Showing the documentation on hover feature](img/godot-tools.png)
@@ -50,13 +50,15 @@ for Godot by following these steps:
You can use the following settings to configure Godot Tools: You can use the following settings to configure Godot Tools:
- `editor_path` - The absolute path to the Godot editor executable. - `editor_path` - The absolute path to the Godot editor executable. _Under Mac OS, this is the executable inside of Godot.app._
- `gdscript_lsp_server_port` - The WebSocket server port of the GDScript language server. - `gdscript_lsp_server_port` - The WebSocket server port of the GDScript language server.
- `check_status` - Check the GDScript language server connection status. - `check_status` - Check the GDScript language server connection status.
#### Debugger #### GDScript Debugger
To configure the debugger: The debugger is for GDScript projects. To debug C# projects, use [C# Tools for Godot](https://github.com/godotengine/godot-csharp-vscode).
To configure the GDScript debugger:
1. Open the command palette: 1. Open the command palette:
2. `>Debug: Open launch.json` 2. `>Debug: Open launch.json`

View File

@@ -81,8 +81,13 @@
"title": "Godot Tools configuration", "title": "Godot Tools configuration",
"properties": { "properties": {
"godot_tools.gdscript_lsp_server_protocol": { "godot_tools.gdscript_lsp_server_protocol": {
"type": ["string"], "type": [
"enum": ["ws", "tcp"], "string"
],
"enum": [
"ws",
"tcp"
],
"default": "tcp", "default": "tcp",
"enumDescriptions": [ "enumDescriptions": [
"Using WebSocket protocol to connect to Godot 3.2 and Godot 3.2.1", "Using WebSocket protocol to connect to Godot 3.2 and Godot 3.2.1",
@@ -148,7 +153,7 @@
"debuggers": [ "debuggers": [
{ {
"type": "godot", "type": "godot",
"label": "Godot Debug", "label": "GDScript Godot Debug",
"program": "./out/debugger/debug_adapter.js", "program": "./out/debugger/debug_adapter.js",
"runtime": "node", "runtime": "node",
"configurationAttributes": { "configurationAttributes": {
@@ -194,7 +199,7 @@
}, },
"initialConfigurations": [ "initialConfigurations": [
{ {
"name": "Godot", "name": "GDScript Godot",
"type": "godot", "type": "godot",
"request": "launch", "request": "launch",
"project": "${workspaceFolder}", "project": "${workspaceFolder}",
@@ -206,7 +211,7 @@
], ],
"configurationSnippets": [ "configurationSnippets": [
{ {
"label": "Godot Debug: Launch", "label": "GDScript Godot Debug: Launch",
"description": "A new configuration for debugging a Godot project.", "description": "A new configuration for debugging a Godot project.",
"body": { "body": {
"type": "godot", "type": "godot",

View File

@@ -25,13 +25,13 @@ interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
export class GodotDebugSession extends LoggingDebugSession { export class GodotDebugSession extends LoggingDebugSession {
private all_scopes: GodotVariable[]; private all_scopes: GodotVariable[];
private configuration_done = new Subject();
private controller?: ServerController; private controller?: ServerController;
private debug_data = new GodotDebugData(); private debug_data = new GodotDebugData();
private exception = false; private exception = false;
private got_scope = new Subject(); private got_scope = new Subject();
private ongoing_inspections: bigint[] = []; private ongoing_inspections: bigint[] = [];
private previous_inspections: bigint[] = []; private previous_inspections: bigint[] = [];
private configuration_done = new Subject();
public constructor() { public constructor() {
super(); super();
@@ -83,6 +83,13 @@ export class GodotDebugSession extends LoggingDebugSession {
this.debug_data.scene_tree = scene_tree_provider; this.debug_data.scene_tree = scene_tree_provider;
} }
public configurationDoneRequest(
response: DebugProtocol.ConfigurationDoneResponse,
args: DebugProtocol.ConfigurationDoneArguments
) {
this.configuration_done.notify();
}
public set_scopes( public set_scopes(
locals: GodotVariable[], locals: GodotVariable[],
members: GodotVariable[], members: GodotVariable[],
@@ -128,14 +135,6 @@ export class GodotDebugSession extends LoggingDebugSession {
} }
} }
protected configurationDoneRequest(
response: DebugProtocol.ConfigurationDoneResponse,
args: DebugProtocol.ConfigurationDoneArguments
): void {
super.configurationDoneRequest(response, args);
this.configuration_done.notify();
}
protected continueRequest( protected continueRequest(
response: DebugProtocol.ContinueResponse, response: DebugProtocol.ContinueResponse,
args: DebugProtocol.ContinueArguments args: DebugProtocol.ContinueArguments
@@ -225,9 +224,9 @@ export class GodotDebugSession extends LoggingDebugSession {
response: DebugProtocol.LaunchResponse, response: DebugProtocol.LaunchResponse,
args: LaunchRequestArguments args: LaunchRequestArguments
) { ) {
await this.configuration_done.wait(2000); await this.configuration_done.wait(1000);
this.exception = false;
this.debug_data.project_path = args.project; this.debug_data.project_path = args.project;
this.exception = false;
Mediator.notify("start", [ Mediator.notify("start", [
args.project, args.project,
args.address, args.address,

View File

@@ -152,13 +152,13 @@ export class Mediator {
case "stop": case "stop":
this.controller?.stop(); this.controller?.stop();
this.session?.sendEvent(new TerminatedEvent(false)); this.session?.sendEvent(new TerminatedEvent());
break; break;
case "error": case "error":
this.controller?.set_exception(parameters[0]); this.controller?.set_exception(parameters[0]);
this.controller?.stop(); this.controller?.stop();
this.session?.sendEvent(new TerminatedEvent(false)); this.session?.sendEvent(new TerminatedEvent());
break; break;
} }
} }

View File

@@ -23,7 +23,7 @@ export class InspectorProvider implements TreeDataProvider<RemoteProperty> {
public clean_up() { public clean_up() {
if (this.tree) { if (this.tree) {
this.tree = undefined; this.tree = undefined;
this._on_did_change_tree_data.fire(this.tree); this._on_did_change_tree_data.fire(undefined);
} }
} }
@@ -37,7 +37,7 @@ export class InspectorProvider implements TreeDataProvider<RemoteProperty> {
this.tree.label = element_name; this.tree.label = element_name;
this.tree.collapsibleState = TreeItemCollapsibleState.Expanded; this.tree.collapsibleState = TreeItemCollapsibleState.Expanded;
this.tree.description = class_name; this.tree.description = class_name;
this._on_did_change_tree_data.fire(this.tree); this._on_did_change_tree_data.fire(undefined);
} }
public getChildren( public getChildren(
@@ -133,7 +133,8 @@ export class InspectorProvider implements TreeDataProvider<RemoteProperty> {
if (value) { if (value) {
let sub_variables = let sub_variables =
typeof value["sub_values"] === "function" && value instanceof ObjectId === false typeof value["sub_values"] === "function" &&
value instanceof ObjectId === false
? value.sub_values() ? value.sub_values()
: Array.isArray(value) : Array.isArray(value)
? value.map((va, i) => { ? value.map((va, i) => {

View File

@@ -22,7 +22,7 @@ export class SceneTreeProvider implements TreeDataProvider<SceneNode> {
public fill_tree(tree: SceneNode) { public fill_tree(tree: SceneNode) {
this.tree = tree; this.tree = tree;
this._on_did_change_tree_data.fire(this.tree); this._on_did_change_tree_data.fire(undefined);
} }
public getChildren(element?: SceneNode): ProviderResult<SceneNode[]> { public getChildren(element?: SceneNode): ProviderResult<SceneNode[]> {

View File

@@ -24,6 +24,7 @@ export class ServerController {
private server?: net.Server; private server?: net.Server;
private socket?: net.Socket; private socket?: net.Socket;
private stepping_out = false; private stepping_out = false;
private terminated = false;
public break() { public break() {
this.add_and_send(this.commands.make_break_command()); this.add_and_send(this.commands.make_break_command());
@@ -111,7 +112,11 @@ export class ServerController {
debug_data.get_all_breakpoints(), debug_data.get_all_breakpoints(),
project_path project_path
); );
let godot_exec = cp.exec(executable_line); let godot_exec = cp.exec(executable_line, (error) => {
if (!this.terminated) {
window.showErrorMessage(`Failed to launch Godot instance: ${error}`);
}
});
this.godot_pid = godot_exec.pid; this.godot_pid = godot_exec.pid;
} }
@@ -169,21 +174,26 @@ export class ServerController {
} }
public stop() { public stop() {
this.socket?.end(() => { this.socket?.destroy();
this.server.close(); this.server?.close((error) => {
if (error) {
console.log(error);
}
this.server.unref();
this.server = undefined; this.server = undefined;
}); });
if (this.godot_pid) { if (this.godot_pid) {
TERMINATE(this.godot_pid, (error: string | undefined) => { this.terminate();
if (error) {
Mediator.notify("error", [error]);
}
});
this.godot_pid = undefined;
} }
} }
private terminate() {
this.terminated = true;
TERMINATE(this.godot_pid);
this.godot_pid = undefined;
}
public trigger_breakpoint(stack_frames: GodotStackFrame[]) { public trigger_breakpoint(stack_frames: GodotStackFrame[]) {
let continue_stepping = false; let continue_stepping = false;
let stack_count = stack_frames.length; let stack_count = stack_frames.length;