Skip to content

Commit

Permalink
Add memory view
Browse files Browse the repository at this point in the history
  • Loading branch information
Yazwh0 committed Apr 7, 2024
1 parent 07f8124 commit 60f1beb
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 6 deletions.
41 changes: 36 additions & 5 deletions Bitmagic.VscExtension/esbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,44 @@ const extensionConfig = {

// Config for webview source code (to be run in a web-based context)
/** @type BuildOptions */
const webviewConfig = {
const layerViewWebviewConfig = {
...baseConfig,
target: "es2020",
format: "esm",
entryPoints: ["./src/layerView/layerView.webview.ts"],
entryPoints: [
"./src/layerView/layerView.webview.ts"
],
outdir: "./out/",
plugins: [
// Copy webview css files to `out` directory unaltered
copy({
resolveFrom: "cwd",
assets: {
from: [
"./src/layerView/layerView.css",
],
to: ["./out"],
},
}),
],
};

const memoryViewWebviewConfig = {
...baseConfig,
target: "es2020",
format: "esm",
entryPoints: [
"./src/memoryView/memoryView.webview.ts"
],
outdir: "./out/",
plugins: [
// Copy webview css files to `out` directory unaltered
copy({
resolveFrom: "cwd",
assets: {
from: ["./src/layerView/layerView.css"],
from: [
"./src/memoryView/memoryView.css",
],
to: ["./out"],
},
}),
Expand Down Expand Up @@ -75,14 +101,19 @@ const watchConfig = {
...watchConfig,
});
await build({
...webviewConfig,
...layerViewWebviewConfig,
...watchConfig,
});
await build({
...memoryViewWebviewConfig,
...watchConfig,
});
console.log("[watch] build finished");
} else {
// Build extension and webview code
await build(extensionConfig);
await build(webviewConfig);
await build(layerViewWebviewConfig);
await build(memoryViewWebviewConfig);
console.log("build complete");
}
} catch (err) {
Expand Down
7 changes: 6 additions & 1 deletion Bitmagic.VscExtension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "bitmagic",
"displayName": "BitMagic X16 Debugger",
"description": "BitMagic X16 Debugger and Development Solution",
"version": "0.1.21",
"version": "0.1.22",
"preview": false,
"publisher": "yazwh0",
"icon": "package/butterfly.png",
Expand Down Expand Up @@ -181,6 +181,11 @@
"command": "layerView.start",
"title": "Open The Layer View",
"category": "BitMagic"
},
{
"command": "memoryView.start",
"title": "Open The Memory View",
"category": "BitMagic"
}
],
"debuggers": [
Expand Down
2 changes: 2 additions & 0 deletions Bitmagic.VscExtension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import path = require('path');
import Constants from './constants';
import { LayerView } from './layerView/layerView';
import { provideVSCodeDesignSystem, vsCodeButton } from "@vscode/webview-ui-toolkit";
import { MemoryView } from './memoryView/memoryView';

const bmOutput = vscode.window.createOutputChannel("BitMagic");

Expand Down Expand Up @@ -124,6 +125,7 @@ export function activate(context: vscode.ExtensionContext) {

// Action Replay
LayerView.activate(context);
MemoryView.activate(context);


// Visualiser
Expand Down
35 changes: 35 additions & 0 deletions Bitmagic.VscExtension/src/memoryView/memoryView.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
img.memory_display
{
height : 512px;
width : 512px;
border : 1px white solid;
image-rendering: pixelated;
}

div.memory_container
{
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: flex-start;
}

div.memory
{
margin: 0 5px;
}

div.display_control
{
margin-top: 10px;
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}

div.control_holder
{
margin: 0 5px;
}
121 changes: 121 additions & 0 deletions Bitmagic.VscExtension/src/memoryView/memoryView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { Disposable, Webview, WebviewPanel, window, Uri, ViewColumn, ExtensionContext, commands, debug } from "vscode";
import { getUri } from "../utilities/getUri";
import { getNonce } from "../utilities/getNonce";

export class MemoryView {

public static currentPanel: MemoryView | undefined;

public static activate(context: ExtensionContext) {

const uri = context.extensionUri;

context.subscriptions.push(
commands.registerCommand('memoryView.start', () => {
const columnToShowIn = window.activeTextEditor
? window.activeTextEditor.viewColumn
: undefined;

if (MemoryView.currentPanel) {
MemoryView.currentPanel._panel.reveal(columnToShowIn);
}
else {
const panel = window.createWebviewPanel(
'memoryView',
'Memory View',
columnToShowIn || ViewColumn.One,
{
enableScripts: true
}
);

MemoryView.currentPanel = new MemoryView(panel, uri);
}
})
);
}

private readonly _panel: WebviewPanel;
private _disposables: Disposable[] = [];

private constructor(panel: WebviewPanel, extensionUri: Uri) {
this._panel = panel;

this._panel.onDidDispose(() => { this.dispose(), null, this, this._disposables });

this._panel.webview.html = this._getWebviewContent(this._panel.webview, extensionUri);

this._setWebviewMessageListener(this._panel.webview);
}

private dispose() {
MemoryView.currentPanel = undefined;

this._panel.dispose();

while (this._disposables.length) {
const disposable = this._disposables.pop();
if (disposable) {
disposable.dispose();
}
}
}

private _setWebviewMessageListener(webview: Webview) {
webview.onDidReceiveMessage(
(message: any) => {
const command = message.command;

switch (command) {
case "getMemoryUse":
this._updateMemoryUse(webview);
return;
}
},
undefined,
this._disposables
);
}

private _updateMemoryUse(webview: Webview) {
debug.activeDebugSession?.customRequest("getMemoryUse").then(i => {
webview.postMessage({ command: "memoryUpdate", payload: JSON.stringify(i) });
});
}

private _getWebviewContent(webview: Webview, extensionUri: Uri) {
const webviewUri = getUri(webview, extensionUri, ["out", "memoryView.webview.js"]);
const nonce = getNonce();
const styleUri = getUri(webview, extensionUri, ["out", "memoryView.css"]);

return /*html*/ `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' data:; style-src ${webview.cspSource}; script-src 'nonce-${nonce}';">
<title>Layer View</title>
<link rel="stylesheet" href="${styleUri}">
</head>
<body>
<div class="display_control">
<div class="control_holder">
<vscode-button appearance="primary" id="update">Update</vscode-button>
</div>
<div class="control_holder">
<vscode-checkbox id="automatically_update">Automatically Update</vscode-checkbox>
</div>
</div>
<div class="memory_container">
<div class="memory">
<div>
<h4>Main Ram</h4>
<img id="main_ram" class="memory_display"/>
</div>
</div>
</div>
<script type="module" nonce="${nonce}" src="${webviewUri}"></script>
</body>
</html>`;
}
}
48 changes: 48 additions & 0 deletions Bitmagic.VscExtension/src/memoryView/memoryView.webview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { provideVSCodeDesignSystem, vsCodeButton, Button, vsCodeCheckbox, Checkbox } from "@vscode/webview-ui-toolkit";

provideVSCodeDesignSystem().register(
vsCodeButton(),
vsCodeCheckbox()
);

const vscode = acquireVsCodeApi();

window.addEventListener("load", main);

function main() {
setVSCodeMessageListener();
// To get improved type annotations/IntelliSense the associated class for
// a given toolkit component can be imported and used to type cast a reference
// to the element (i.e. the `as Button` syntax)
const updateButton = document.getElementById("update") as Button;
updateButton.addEventListener("click", () => updateMemory());
}

function setVSCodeMessageListener() {
window.addEventListener("message", (event) => {
const command = event.data.command;
const messageData = JSON.parse(event.data.payload);

switch (command) {
case "memoryUpdate":
updateDisplay(messageData);
break;
}
});
}

function updateMemory() {
vscode.postMessage({ command: "getMemoryUse" });
}

function updateDisplay(messageData: any) {
const d = messageData.Display;
const layer = document.getElementById("main_ram") as HTMLImageElement;

layer.src = `data:image/bmp;base64,${d}`;
const checkBox = document.getElementById("automatically_update") as Checkbox;

if (checkBox.checked) {
setTimeout(updateMemory, 10);
}
}

0 comments on commit 60f1beb

Please sign in to comment.