Skip to content

Commit

Permalink
feat(diagnostics): Ability to load a replay of diagnostics events fro…
Browse files Browse the repository at this point in the history
…m file
  • Loading branch information
chmeyer-ms committed Dec 7, 2024
1 parent bca64b6 commit 51eb60f
Show file tree
Hide file tree
Showing 20 changed files with 721 additions and 277 deletions.
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,19 @@
},
"commands": [
{
"command": "minecraft-debugger.showMinecraftDiagnostics",
"title": "Minecraft Diagnostics: Show"
"command": "minecraft-debugger.liveDiagnostics",
"title": "Minecraft Diagnostics: Show Live Stats"
},
{
"command": "minecraft-debugger.replayDiagnostics",
"title": "Minecraft Diagnostics: Open Stats Replay"
},
{
"command": "minecraft-debugger.minecraftReload",
"title": "Minecraft Reload"
}
],
"keybindings":[
"keybindings": [
{
"command": "minecraft-debugger.minecraftReload",
"key": "ctrl+shift+r",
Expand Down Expand Up @@ -242,4 +246,4 @@
"typescript": "^5.5.4",
"vitest": "^2.1.3"
}
}
}
35 changes: 18 additions & 17 deletions src/Session.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// Copyright (C) Microsoft Corporation. All rights reserved.

import { createConnection, Server, Socket } from 'net';
Expand Down Expand Up @@ -28,10 +27,10 @@ import {
import { DebugProtocol } from '@vscode/debugprotocol';
import { EventEmitter } from 'events';
import { LogOutputEvent, LogLevel } from '@vscode/debugadapter/lib/logger';
import { MessageStreamParser } from './MessageStreamParser';
import { SourceMaps } from './SourceMaps';
import { StatMessageModel, StatsProvider2 } from './StatsProvider2';
import { HomeViewProvider } from './panels/HomeViewProvider';
import { MessageStreamParser } from './message-stream-parser';
import { SourceMaps } from './source-maps';
import { StatMessageModel, StatsProvider } from './stats/stats-provider';
import { HomeViewProvider } from './panels/home-view-provider';
import * as path from 'path';
import * as fs from 'fs';
import { isUUID } from './Utils';
Expand Down Expand Up @@ -144,10 +143,10 @@ export class Session extends DebugSession {

// external communication
private _homeViewProvider: HomeViewProvider;
private _statsProvider: StatsProvider2;
private _statsProvider: StatsProvider;
private _eventEmitter: EventEmitter;

public constructor(homeViewProvider: HomeViewProvider, statsProvider: StatsProvider2, eventEmitter: EventEmitter) {
public constructor(homeViewProvider: HomeViewProvider, statsProvider: StatsProvider, eventEmitter: EventEmitter) {
super();

this._homeViewProvider = homeViewProvider;
Expand Down Expand Up @@ -192,7 +191,7 @@ export class Session extends DebugSession {
command: {
command: command,
dimension_type: 'overworld',
}
},
});
}
}
Expand All @@ -202,7 +201,7 @@ export class Session extends DebugSession {
type: 'startProfiler',
profiler: {
target_module_uuid: this._targetModuleUuid,
}
},
});
}

Expand All @@ -212,7 +211,7 @@ export class Session extends DebugSession {
profiler: {
captures_path: capturesBasePath,
target_module_uuid: this._targetModuleUuid,
}
},
});
}

Expand All @@ -231,10 +230,9 @@ export class Session extends DebugSession {
this.showNotification(`Failed to write to temp file: ${err.message}`, LogLevel.Error);
return;
}
commands.executeCommand('vscode.open', Uri.file(captureFullPath))
.then(undefined, error => {
this.showNotification(`Failed to open CPU profile: ${error.message}`, LogLevel.Error);
});
commands.executeCommand('vscode.open', Uri.file(captureFullPath)).then(undefined, error => {
this.showNotification(`Failed to open CPU profile: ${error.message}`, LogLevel.Error);
});

// notify home view of new capture
this._eventEmitter.emit('new-profiler-capture', profilerCapture.capture_base_path, newCaptureFileName);
Expand Down Expand Up @@ -1026,14 +1024,17 @@ export class Session extends DebugSession {
const reloadOnSourceChangesEnabled = config.get<boolean>('reloadOnSourceChanges.enabled');
const reloadOnSourceChangesDelay = Math.max(config.get<number>('reloadOnSourceChanges.delay') ?? 0, 0);
const reloadOnSourceChangesGlobPattern = config.get<string>('reloadOnSourceChanges.globPattern');

// watch all files within the workspace matching custom glob pattern.
// only active if Minecraft /reload is enabled
let globPattern: RelativePattern | undefined = undefined;
if (reloadOnSourceChangesGlobPattern && reloadOnSourceChangesEnabled) {
const workspaceFolders = workspace.workspaceFolders;
if (workspaceFolders && workspaceFolders.length > 0) {
globPattern = new RelativePattern(workspaceFolders[0].uri.fsPath ?? '', reloadOnSourceChangesGlobPattern);
globPattern = new RelativePattern(
workspaceFolders[0].uri.fsPath ?? '',
reloadOnSourceChangesGlobPattern
);
}
}
// watch source map files and reload cache if changed.
Expand Down Expand Up @@ -1064,7 +1065,7 @@ export class Session extends DebugSession {
}
}, reloadOnSourceChangesDelay);
};

if (this._sourceFileWatcher) {
this._sourceFileWatcher.onDidChange(onSourceChanged);
this._sourceFileWatcher.onDidCreate(onSourceChanged);
Expand Down
5 changes: 2 additions & 3 deletions src/Utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// Copyright (C) Microsoft Corporation. All rights reserved.

import * as os from 'os';
Expand Down Expand Up @@ -28,7 +27,7 @@ describe('Utils', () => {
expect(normalizePathForRemote('C:\\path\\to\\file')).toBe('C:/path/to/file');
expect(normalizePathForRemote('C:/path/to/file')).toBe('C:/path/to/file');
});
});
});

describe('isUUID', () => {
it('should return true for valid UUIDs', () => {
Expand All @@ -40,5 +39,5 @@ describe('Utils', () => {
expect(isUUID('123e4567-e89b-12d3-a456-42661417400')).toBe(false); // One character short
expect(isUUID('123e4567-e89b-12d3-a456-4266141740000')).toBe(false); // One character too long
});
});
});
});
File renamed without changes.
78 changes: 50 additions & 28 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,45 @@

// Copyright (C) Microsoft Corporation. All rights reserved.

import * as vscode from 'vscode';
import { ConfigProvider } from './ConfigProvider';
import { ServerDebugAdapterFactory } from './ServerDebugAdapterFactory';
import { HomeViewProvider } from './panels/HomeViewProvider';
import { MinecraftDiagnosticsPanel } from './panels/MinecraftDiagnostics';
import { StatsProvider2 } from './StatsProvider2';
import { ConfigProvider } from './config-provider';
import { EventEmitter } from 'stream';
import { HomeViewProvider } from './panels/home-view-provider';
import { MinecraftDiagnosticsPanel } from './panels/minecraft-diagnostics';
import { ServerDebugAdapterFactory } from './server-debug-adapter-factory';
import { StatsProvider } from './stats/stats-provider';
import { ReplayStatsProvider } from './stats/replay-stats-provider';

// called when extension is activated
//
export function activate(context: vscode.ExtensionContext) {
const statsProvider = new StatsProvider2();
const liveStatsProvider = new StatsProvider('Live', 'minecraftDiagnosticsLive');
const eventEmitter: EventEmitter = new EventEmitter();

// home view
const homeViewProvider = new HomeViewProvider(context.extensionUri, eventEmitter);
context.subscriptions.push(vscode.window.registerWebviewViewProvider(HomeViewProvider.viewType, homeViewProvider));

// register commands
context.subscriptions.push(
vscode.commands.registerCommand('extension.minecraft-js.getPort', _config => {
return vscode.window.showInputBox({
placeHolder: 'Please enter the port Minecraft is listening on.',
value: '',
});
})
);

// register a configuration provider for the 'minecraft-js' debug type
const configProvider = new ConfigProvider();
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('minecraft-js', configProvider));

// register a debug adapter descriptor factory for 'minecraft-js', this factory creates the DebugSession
let descriptorFactory = new ServerDebugAdapterFactory(homeViewProvider, statsProvider, eventEmitter);
let descriptorFactory = new ServerDebugAdapterFactory(homeViewProvider, liveStatsProvider, eventEmitter);
context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('minecraft-js', descriptorFactory));

if ('dispose' in descriptorFactory) {
context.subscriptions.push(descriptorFactory);
}

// Create the show diagnostics command
const showDiagnosticsCommand = vscode.commands.registerCommand(
'minecraft-debugger.showMinecraftDiagnostics',
() => {
MinecraftDiagnosticsPanel.render(context.extensionUri, statsProvider);
}
);
//
// Command Registrations
//

const getPortCommand = vscode.commands.registerCommand('extension.minecraft-js.getPort', () => {
return vscode.window.showInputBox({
placeHolder: 'Please enter the port Minecraft is listening on.',
value: '',
});
});

const minecraftReloadCommand = vscode.commands.registerCommand('minecraft-debugger.minecraftReload', () => {
if (!vscode.debug.activeDebugSession) {
Expand Down Expand Up @@ -76,8 +68,38 @@ export function activate(context: vscode.ExtensionContext) {
}
);

// Add command to the extension context
context.subscriptions.push(showDiagnosticsCommand, minecraftReloadCommand, runMinecraftCommand);
const liveDiagnosticsCommand = vscode.commands.registerCommand('minecraft-debugger.liveDiagnostics', () => {
MinecraftDiagnosticsPanel.render(context.extensionUri, liveStatsProvider);
});

const replayDiagnosticsCommand = vscode.commands.registerCommand(
'minecraft-debugger.replayDiagnostics',
async () => {
const fileUri = await vscode.window.showOpenDialog({
canSelectMany: false,
openLabel: 'Select diagnostics capture to replay',
filters: {
'MC Stats files': ['mcstats'],
'All files': ['*'],
},
});
if (!fileUri || fileUri.length === 0) {
vscode.window.showErrorMessage('No file selected.');
return;
}
const replayStats = new ReplayStatsProvider(fileUri[0].fsPath);
MinecraftDiagnosticsPanel.render(context.extensionUri, replayStats);
}
);

// Add commands to the extension context
context.subscriptions.push(
getPortCommand,
minecraftReloadCommand,
runMinecraftCommand,
liveDiagnosticsCommand,
replayDiagnosticsCommand
);
}

// called when extension is deactivated
Expand Down
File renamed without changes.
Loading

0 comments on commit 51eb60f

Please sign in to comment.