- Notifications
You must be signed in to change notification settings - Fork2
Initial Surfer support#5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:surfer
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
a1f730254eb5efa2d8d0dcd83374bb37e022583b280e489f9c6653a124244cd479e1d1056a035File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -175,6 +175,12 @@ | ||
| "command":"rtlDebugger.browseWaveforms", | ||
| "category":"RTL Debugger", | ||
| "title":"Browse Waveforms" | ||
| }, | ||
| { | ||
| "command":"rtlDebugger.addToWaveform", | ||
| "category":"RTL Debugger", | ||
| "title":"Add to Waveform", | ||
| "icon":"$(keybindings-add)" | ||
| } | ||
| ], | ||
| "viewsContainers": { | ||
| @@ -319,6 +325,11 @@ | ||
| "command":"rtlDebugger.unWatchVariable", | ||
| "when":"view == rtlDebugger.sidebar && viewItem =~ /inWatchList/", | ||
| "group":"inline" | ||
| }, | ||
| { | ||
| "command":"rtlDebugger.addToWaveform", | ||
| "when":"view == rtlDebugger.sidebar && viewItem =~ /variable/", | ||
Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. This is wrong, it should check if the waveform viewer is active but I can't figure out how | ||
| "group":"inline" | ||
| } | ||
| ], | ||
| "rtlDebugger.setRadix": [ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -75,6 +75,16 @@ export function activate(context: vscode.ExtensionContext) { | ||
| } | ||
| })); | ||
| context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.addToWaveform', (treeItem) => { | ||
| if (rtlDebugger.lastActiveWaveformTab) { | ||
| console.log(rtlDebugger.lastActiveWaveformTab); | ||
| const target = rtlDebugger.waveformProviders.get(rtlDebugger.lastActiveWaveformTab); | ||
| if (target) { | ||
| target.addVariable(treeItem.designation.variable); | ||
| } | ||
| } | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. This seems like it would allow for exactly one Surfer tab to exist. Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Yep, so far I've been working under the assumption that this would be the case Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. The existing code doesn't enforce it (intentionally--I think that would be fairly limiting if it was the only thing possible...) Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Yeah, makes sense. It does open a bunch of UI questions about where interactions should happen, for example which surfer should add a variable when you click Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I think the VS Code UI maintains an "active tab" or "selected tab" or something like that. Barring that, simply the last one that received focus will match user expectations. Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Pushed an update to allow multiple viewers. I'm not very happy with the code since it requires maintaining my own list of tab->webview mappings that are based on the weird ViewType string but as far as I can tell, there is no other convenient way to do it... | ||
| })); | ||
| context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.setRadix.2', (treeItem) => | ||
| globalVariableOptions.update(treeItem.designation.variable.cxxrtlIdentifier, { radix: 2 }))); | ||
| context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.setRadix.8', (treeItem) => | ||
| @@ -90,18 +100,48 @@ export function activate(context: vscode.ExtensionContext) { | ||
| globalWatchList.remove(treeItem.metadata.index))); | ||
| context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.browseWaveforms', () => { | ||
| const viewKey = `rtlDebugger.waveforms.${rtlDebugger.nextWaveformviewId++}`; | ||
| const webviewPanel = vscode.window.createWebviewPanel( | ||
| viewKey, | ||
| 'Waveforms', | ||
| { | ||
| viewColumn: vscode.ViewColumn.Beside, | ||
| }, | ||
| { | ||
| enableScripts: true, | ||
| retainContextWhenHidden: true, | ||
| } | ||
| ); | ||
| console.log(`Creating web view panel with viewType ${webviewPanel.viewType}`); | ||
| const bundleRoot = vscode.Uri.joinPath(context.extensionUri, 'out/'); | ||
| const waveformProvider = new WaveformProvider(rtlDebugger, webviewPanel, bundleRoot); | ||
| rtlDebugger.waveformProviders.set(viewKey, waveformProvider); | ||
| rtlDebugger.lastActiveWaveformTab = viewKey; | ||
| context.subscriptions.push(waveformProvider); | ||
| })); | ||
| vscode.window.tabGroups.onDidChangeTabs(event => { | ||
| const activeWaveformTab = event.changed.map((tab, _) => { | ||
| if (tab.input instanceof vscode.TabInputWebview) { | ||
| console.log(`${tab.input.viewType}`); | ||
| const key = tab.input.viewType.match(/.*(rtlDebugger.waveforms\.\d+)/); | ||
| if (key) { | ||
| return key[1]; | ||
| } else { | ||
| return null; | ||
| } | ||
| } else { | ||
| return null; | ||
| } | ||
| }).find((id) => id !== null); | ||
| if (activeWaveformTab) { | ||
| rtlDebugger.lastActiveWaveformTab = activeWaveformTab; | ||
| } | ||
| }); | ||
| // For an unknown reason, the `vscode.open` command (which does the exact same thing) ignores the options. | ||
| context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.openDocument', | ||
| (uri: vscode.Uri, options: vscode.TextDocumentShowOptions) => { | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -3,14 +3,31 @@ import * as vscode from 'vscode'; | ||
| import { CXXRTLDebugger } from '../debugger'; | ||
| // @ts-ignore | ||
| import embedHtml from '../surfer/embed.html'; | ||
| import { ILink, Packet } from '../cxxrtl/link'; | ||
| import { ClientPacket } from '../cxxrtl/proto'; | ||
| import { Variable } from '../model/variable'; | ||
| export class ClientPacketString { | ||
| constructor(public inner: string) { } | ||
| } | ||
| export class ServerPacketString { | ||
| constructor(public inner: string) { } | ||
| } | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. These classes don't seem like they're doing anything useful? Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I added them because I wanted type safety when passing around different kinds of strings | ||
| export type ExtensionToWebviewMessage = | ||
| | { type: 'restore', state: any } | ||
| // TODO: Proper type here | ||
| | { type: 'cxxrtl_sc_message', message: ServerPacketString } | ||
| | { type: 'wcp_cs_message', message: string } | ||
| ; | ||
| export type WebviewToExtensionMessage = | ||
| | { type: 'ready' } | ||
| | { type: 'crash', error: any } | ||
| // TODO: Proper type here | ||
| | { type: 'cxxrtl_cs_message', message: ClientPacketString } | ||
| | { type: 'wcp_sc_message', message: string } | ||
| ; | ||
| export class WaveformProvider { | ||
| @@ -23,6 +40,18 @@ export class WaveformProvider { | ||
| this.webview.asWebviewUri(bundleRoot).toString()); | ||
| this.webview.onDidReceiveMessage(this.processMessage.bind(this)); | ||
| this.webview.html = webviewHtml; | ||
| const debuggerLink = rtlDebugger.session?.createSecondaryLink(); | ||
| // TODO: Correct way to handle errors? | ||
| if (debuggerLink) { | ||
| this.debuggerLink = debuggerLink; | ||
| this.debuggerLink.onRecv = async (message) => { | ||
| // console.log("Running on recv for ", message) | ||
| await this.sendMessage({ type: 'cxxrtl_sc_message', message: new ServerPacketString(message.asString()) }); | ||
| }; | ||
| } else { | ||
| throw new Error('Failed to create secondary debugger link'); | ||
| } | ||
| } | ||
| dispose() { | ||
| @@ -45,8 +74,26 @@ export class WaveformProvider { | ||
| console.log('[RTL Debugger] [WaveformProvider] Ready'); | ||
| } else if (message.type === 'crash') { | ||
| console.log('[RTL Debugger] [WaveformProvider] Crash:', message.error); | ||
| } else if (message.type === 'cxxrtl_cs_message') { | ||
| console.log('[RTL Debugger] [WaveformProvider] Got CSMessage', message.message); | ||
| const packet: Packet<ClientPacket> = Packet.fromString(message.message.inner); | ||
| await this.debuggerLink.send(packet); | ||
| } else if (message.type === 'wcp_sc_message') { | ||
| console.log('[RTL Debugger] [WaveformProvider] Got WCP SC message', message.message); | ||
| } else { | ||
| console.error('[RTL Debugger] [WaveformProvider] Unhandled webview to extension message:', message); | ||
| } | ||
| } | ||
| async addVariable(variable: Variable) { | ||
| // TODO: How should we handle the callbacks here? | ||
| const message = JSON.stringify({ | ||
| type: 'command', | ||
| command: 'add_variables', | ||
| names: [variable.wcpIdentifier] | ||
| }); | ||
| this.sendMessage({type: 'wcp_cs_message', message}); | ||
| } | ||
| private debuggerLink: ILink; | ||
| } | ||
Uh oh!
There was an error while loading.Please reload this page.