Explorar el Código

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

Francois Belair hace 4 años
padre
commit
d2d7813312

+ 6 - 4
README.md

@@ -21,7 +21,7 @@ experience as comfortable as possible:
 - Ctrl + click on a variable or method call to jump to its definition
 - Full documentation of the Godot Engine's API supported
 - 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)
 
@@ -50,13 +50,15 @@ for Godot by following these steps:
 
 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.
 - `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:
 2. `>Debug: Open launch.json`

+ 10 - 5
package.json

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

+ 10 - 11
src/debugger/debug_session.ts

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

+ 2 - 2
src/debugger/mediator.ts

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

+ 4 - 3
src/debugger/scene_tree/inspector_provider.ts

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

+ 1 - 1
src/debugger/scene_tree/scene_tree_provider.ts

@@ -22,7 +22,7 @@ export class SceneTreeProvider implements TreeDataProvider<SceneNode> {
 
 	public fill_tree(tree: SceneNode) {
 		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[]> {

+ 19 - 9
src/debugger/server_controller.ts

@@ -24,6 +24,7 @@ export class ServerController {
 	private server?: net.Server;
 	private socket?: net.Socket;
 	private stepping_out = false;
+	private terminated = false;
 
 	public break() {
 		this.add_and_send(this.commands.make_break_command());
@@ -111,7 +112,11 @@ export class ServerController {
 				debug_data.get_all_breakpoints(),
 				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;
 		}
 
@@ -169,21 +174,26 @@ export class ServerController {
 	}
 
 	public stop() {
-		this.socket?.end(() => {
-			this.server.close();
+		this.socket?.destroy();
+		this.server?.close((error) => {
+			if (error) {
+				console.log(error);
+			}
+			this.server.unref();
 			this.server = undefined;
 		});
 
 		if (this.godot_pid) {
-			TERMINATE(this.godot_pid, (error: string | undefined) => {
-				if (error) {
-					Mediator.notify("error", [error]);
-				}
-			});
-			this.godot_pid = undefined;
+			this.terminate();
 		}
 	}
 
+	private terminate() {
+		this.terminated = true;
+		TERMINATE(this.godot_pid);
+		this.godot_pid = undefined;
+	}
+
 	public trigger_breakpoint(stack_frames: GodotStackFrame[]) {
 		let continue_stepping = false;
 		let stack_count = stack_frames.length;