From 14121bcdc73a9ceabd8a4e4a0ea4c53df4438344 Mon Sep 17 00:00:00 2001 From: amylizzlep Date: Sun, 17 Nov 2024 00:17:51 +0000 Subject: [PATCH 1/4] hot reload bytecode --- package.json | 2 +- src/extension.ts | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 48e78dd..82f6e7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opendream", - "version": "0.2.3", + "version": "0.2.4", "displayName": "OpenDream Dev Tools", "icon": "OD.png", "description": "Developer tools for OpenDream", diff --git a/src/extension.ts b/src/extension.ts index 50f2b32..743d48f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -165,6 +165,7 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { private buffer = Buffer.alloc(0); private resourceWatcher?: vscode.FileSystemWatcher private interfaceWatcher?: vscode.FileSystemWatcher + private codeWatcher?: vscode.FileSystemWatcher private didSendMessageEmitter = new vscode.EventEmitter(); private sendMessageToEditor = this.didSendMessageEmitter.fire.bind(this.didSendMessageEmitter); @@ -223,6 +224,7 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { if(hotReloadAuto) { this.resourceWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dmi,png,jpg,rsi,gif,bmp}"))//TODO all the sound file formats? this.interfaceWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dmf}")) + this.codeWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dm}")) this.interfaceWatcher.onDidChange(() => {this.hotReloadInterface()}) this.interfaceWatcher.onDidCreate(() => {this.hotReloadInterface()}) @@ -231,6 +233,10 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { this.resourceWatcher.onDidChange((file) => {this.hotReloadResource(file)}) this.resourceWatcher.onDidCreate((file) => {this.hotReloadResource(file)}) this.resourceWatcher.onDidDelete((file) => {this.hotReloadResource(file)}) + + this.codeWatcher.onDidChange(() => {this.hotReloadCode()}) + this.codeWatcher.onDidCreate(() => {this.hotReloadCode()}) + this.codeWatcher.onDidDelete(() => {this.hotReloadCode()}) } } @@ -244,6 +250,24 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { this.sendMessageToGame({ type: 'request', command: 'hotreloadresource', arguments: {'file':resource.fsPath}}) } + private hotReloadCode(): void { + console.log("Hot reloading code") + vscode.tasks.fetchTasks({type: 'opendream'}).then((tasks) => { + for(let x of tasks) + if(x.name.includes("compile") && x.name.includes(".dme")) + return vscode.tasks.executeTask(x); + throw Error("Can't find compile task!") + }).then((execution)=>{ + vscode.tasks.onDidEndTask((event) => { + if(event.execution.task == execution.task) + console.log("compile complete, sending hot reload request") + commands.executeCommand('opendream.getFilenameJson').then( + (filename)=>this.sendMessageToGame({ type: 'request', command: 'hotreloadbytecode', arguments: {'file':filename}}) + ) + }) + }) + } + handleMessage(message: any): void { if (message.type == 'request' && message.command == 'disconnect') { // Kill the client when the Stop button is clicked. @@ -273,6 +297,7 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { dispose() { this.resourceWatcher?.dispose() this.interfaceWatcher?.dispose() + this.codeWatcher?.dispose() this.socket.destroy(); this.didSendMessageEmitter.dispose(); } From df0b2e39c6aa9bfd3b5d8a013d686d6ad93d9b2f Mon Sep 17 00:00:00 2001 From: amylizzlep Date: Sun, 17 Nov 2024 18:17:23 +0000 Subject: [PATCH 2/4] button --- package.json | 19 ++++++++++++++++++- src/extension.ts | 9 +++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 82f6e7a..2b94135 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,24 @@ { "language": "dm" } - ] + ], + "commands": [ + { + "command": "opendream.hotReload", + "title": "Hot Reload", + "shortTitle": "$(flame)", + "icon": "$(flame)" + + } + ], + "menus": { + "debug/toolBar": [ + { + "command": "opendream.hotReload", + "group": "navigation" + } + ] + } }, "scripts": { "vscode:prepublish": "webpack --mode production", diff --git a/src/extension.ts b/src/extension.ts index 743d48f..4493801 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -32,6 +32,8 @@ const LauncherBinVersionTagFile = "latestLauncherBuild.txt" let storagePath: string | undefined; +let hotReloadCommandFunction: (() => void); + /* Correctness notes: - Tasks passed to `executeTask` must have unique `type` values in their definitions, or VSC will confuse them. @@ -53,6 +55,10 @@ export async function activate(context: ExtensionContext) { // Register the task provider for OpenDream build tasks. context.subscriptions.push(vscode.tasks.registerTaskProvider('opendream', new OpenDreamTaskProvider())); + // ------------------------------------------------------------------------7 + // Register the hot reload command as a handle on the function which is set by the debug adapter + commands.registerCommand('opendream.hotReload', () => hotReloadCommandFunction()) + // ------------------------------------------------------------------------ // Register the debugger mode. @@ -221,6 +227,8 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { } }); + hotReloadCommandFunction = () => this.hotReloadCode() + if(hotReloadAuto) { this.resourceWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dmi,png,jpg,rsi,gif,bmp}"))//TODO all the sound file formats? this.interfaceWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dmf}")) @@ -298,6 +306,7 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { this.resourceWatcher?.dispose() this.interfaceWatcher?.dispose() this.codeWatcher?.dispose() + this.socket.destroy(); this.didSendMessageEmitter.dispose(); } From d2b2a2b5357065ca2a9a7860aeb2bdb3306dc065 Mon Sep 17 00:00:00 2001 From: amylizzlep Date: Sun, 17 Nov 2024 18:25:04 +0000 Subject: [PATCH 3/4] toggles --- package.json | 7 ++++++- src/extension.ts | 15 ++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 2b94135..c553e7b 100644 --- a/package.json +++ b/package.json @@ -40,10 +40,15 @@ "default": null, "description": "Path to your copy of the OpenDream source code. This should be the top level folder containing OpenDream.sln. Leave empty to use pre-compiled binaries instead." }, - "opendream.hotReload": { + "opendream.hotReloadResource": { "type": "boolean", "default": true, "description": "Automatically reload resources when they're changed on disk." + }, + "opendream.hotReloadCode": { + "type": "boolean", + "default": true, + "description": "Automatically recompile and hot reload code files when they're changed on disk." } } }, diff --git a/src/extension.ts b/src/extension.ts index 4493801..970e980 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -112,8 +112,9 @@ export async function activate(context: ExtensionContext) { let buildClientPromise = openDream.buildClient(session.workspaceFolder); // Wait for the OD server to connect back to us, then stop listening. let socket = await socketPromise; - let hotReloadEnable:boolean = workspace.getConfiguration('opendream').get('hotReload') || false; - return new vscode.DebugAdapterInlineImplementation(new OpenDreamDebugAdapter(socket, buildClientPromise, hotReloadEnable)); + let hotReloadResourceEnable:boolean = workspace.getConfiguration('opendream').get('hotReloadResource') || false; + let hotReloadCodeEnable:boolean = workspace.getConfiguration('opendream').get('hotReloadCode') || false; + return new vscode.DebugAdapterInlineImplementation(new OpenDreamDebugAdapter(socket, buildClientPromise, hotReloadResourceEnable, hotReloadCodeEnable)); } })); @@ -177,7 +178,7 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { private sendMessageToEditor = this.didSendMessageEmitter.fire.bind(this.didSendMessageEmitter); onDidSendMessage = this.didSendMessageEmitter.event; - constructor(socket: net.Socket, buildClientPromise?: Promise, hotReloadAuto?: boolean) { + constructor(socket: net.Socket, buildClientPromise?: Promise, hotReloadResourceAuto?: boolean, hotReloadCodeAuto?: boolean) { this.socket = socket; this.buildClientPromise = buildClientPromise; @@ -229,10 +230,10 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { hotReloadCommandFunction = () => this.hotReloadCode() - if(hotReloadAuto) { + if(hotReloadResourceAuto) { this.resourceWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dmi,png,jpg,rsi,gif,bmp}"))//TODO all the sound file formats? this.interfaceWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dmf}")) - this.codeWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dm}")) + this.interfaceWatcher.onDidChange(() => {this.hotReloadInterface()}) this.interfaceWatcher.onDidCreate(() => {this.hotReloadInterface()}) @@ -242,6 +243,10 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { this.resourceWatcher.onDidCreate((file) => {this.hotReloadResource(file)}) this.resourceWatcher.onDidDelete((file) => {this.hotReloadResource(file)}) + + } + if(hotReloadCodeAuto){ + this.codeWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dm}")) this.codeWatcher.onDidChange(() => {this.hotReloadCode()}) this.codeWatcher.onDidCreate(() => {this.hotReloadCode()}) this.codeWatcher.onDidDelete(() => {this.hotReloadCode()}) From e5edd1f1e3fd431cde453ebf611486f9c6edd266 Mon Sep 17 00:00:00 2001 From: amylizzlep Date: Sun, 17 Nov 2024 22:38:10 +0000 Subject: [PATCH 4/4] don't compile on DMstandard copy --- src/extension.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 970e980..9d58b08 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -246,10 +246,11 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { } if(hotReloadCodeAuto){ - this.codeWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dm}")) - this.codeWatcher.onDidChange(() => {this.hotReloadCode()}) - this.codeWatcher.onDidCreate(() => {this.hotReloadCode()}) - this.codeWatcher.onDidDelete(() => {this.hotReloadCode()}) + this.codeWatcher = vscode.workspace.createFileSystemWatcher(("**/*.{dm,dme}")) + + this.codeWatcher.onDidChange((file) => {this.hotReloadCode(file)}) + this.codeWatcher.onDidCreate((file) => {this.hotReloadCode(file)}) + this.codeWatcher.onDidDelete((file) => {this.hotReloadCode(file)}) } } @@ -263,8 +264,10 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { this.sendMessageToGame({ type: 'request', command: 'hotreloadresource', arguments: {'file':resource.fsPath}}) } - private hotReloadCode(): void { - console.log("Hot reloading code") + private hotReloadCode(resource?:vscode.Uri): void { + if(resource?.fsPath.includes("DMStandard")) + return //ignore changes to DMStandard + console.log(`Hot reloading code triggered by ${resource?.fsPath}`) vscode.tasks.fetchTasks({type: 'opendream'}).then((tasks) => { for(let x of tasks) if(x.name.includes("compile") && x.name.includes(".dme"))