diff --git a/package.json b/package.json index 01bd800..48e78dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opendream", - "version": "0.2.2", + "version": "0.2.3", "displayName": "OpenDream Dev Tools", "icon": "OD.png", "description": "Developer tools for OpenDream", @@ -39,6 +39,11 @@ "type": "string", "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": { + "type": "boolean", + "default": true, + "description": "Automatically reload resources when they're changed on disk." } } }, diff --git a/src/extension.ts b/src/extension.ts index ca74859..50f2b32 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -106,7 +106,8 @@ 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; - return new vscode.DebugAdapterInlineImplementation(new OpenDreamDebugAdapter(socket, buildClientPromise)); + let hotReloadEnable:boolean = workspace.getConfiguration('opendream').get('hotReload') || false; + return new vscode.DebugAdapterInlineImplementation(new OpenDreamDebugAdapter(socket, buildClientPromise, hotReloadEnable)); } })); @@ -162,12 +163,14 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { private socket: net.Socket; private buffer = Buffer.alloc(0); + private resourceWatcher?: vscode.FileSystemWatcher + private interfaceWatcher?: vscode.FileSystemWatcher private didSendMessageEmitter = new vscode.EventEmitter(); private sendMessageToEditor = this.didSendMessageEmitter.fire.bind(this.didSendMessageEmitter); onDidSendMessage = this.didSendMessageEmitter.event; - constructor(socket: net.Socket, buildClientPromise?: Promise) { + constructor(socket: net.Socket, buildClientPromise?: Promise, hotReloadAuto?: boolean) { this.socket = socket; this.buildClientPromise = buildClientPromise; @@ -216,6 +219,29 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { headerEnd = this.buffer.indexOf('\r\n\r\n'); } }); + + 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.interfaceWatcher.onDidChange(() => {this.hotReloadInterface()}) + this.interfaceWatcher.onDidCreate(() => {this.hotReloadInterface()}) + this.interfaceWatcher.onDidDelete(() => {this.hotReloadInterface()}) + + this.resourceWatcher.onDidChange((file) => {this.hotReloadResource(file)}) + this.resourceWatcher.onDidCreate((file) => {this.hotReloadResource(file)}) + this.resourceWatcher.onDidDelete((file) => {this.hotReloadResource(file)}) + } + } + + private hotReloadInterface(): void { + console.log("Hot reloading interface") + this.sendMessageToGame({ type: 'request', command: 'hotreloadinterface'}) + } + + private hotReloadResource(resource:vscode.Uri) { + console.log(`Hot reloading resource ${resource.fsPath}`) + this.sendMessageToGame({ type: 'request', command: 'hotreloadresource', arguments: {'file':resource.fsPath}}) } handleMessage(message: any): void { @@ -245,6 +271,8 @@ class OpenDreamDebugAdapter implements vscode.DebugAdapter { } dispose() { + this.resourceWatcher?.dispose() + this.interfaceWatcher?.dispose() this.socket.destroy(); this.didSendMessageEmitter.dispose(); }