Skip to content

Commit ca35e2c

Browse files
author
Benjamin Pasero
committed
debt - convert profile status to status item
1 parent c934405 commit ca35e2c

2 files changed

Lines changed: 51 additions & 103 deletions

File tree

src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts

Lines changed: 51 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@
55

66
import * as nls from 'vs/nls';
77
import { Event, Emitter } from 'vs/base/common/event';
8-
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
8+
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
99
import { IExtensionHostProfile, ProfileSession, IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
10-
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
10+
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
1111
import { onUnexpectedError } from 'vs/base/common/errors';
12-
import { append, $, addDisposableListener } from 'vs/base/browser/dom';
13-
import { IStatusbarRegistry, StatusbarItemDescriptor, Extensions, IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
14-
import { StatusbarAlignment } from 'vs/platform/statusbar/common/statusbar';
15-
import { Registry } from 'vs/platform/registry/common/platform';
12+
import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/platform/statusbar/common/statusbar';
1613
import { IExtensionHostProfileService, ProfileSessionState } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor';
1714
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
1815
import { IWindowsService } from 'vs/platform/windows/common/windows';
@@ -22,10 +19,11 @@ import product from 'vs/platform/product/node/product';
2219
import { RuntimeExtensionsInput } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsInput';
2320
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
2421
import { ExtensionHostProfiler } from 'vs/workbench/services/extensions/electron-browser/extensionHostProfiler';
22+
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
2523

2624
export class ExtensionHostProfileService extends Disposable implements IExtensionHostProfileService {
2725

28-
_serviceBrand: any;
26+
_serviceBrand: ServiceIdentifier<IExtensionHostProfileService>;
2927

3028
private readonly _onDidChangeState: Emitter<void> = this._register(new Emitter<void>());
3129
public readonly onDidChangeState: Event<void> = this._onDidChangeState.event;
@@ -38,6 +36,9 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
3836
private _profileSession: ProfileSession | null;
3937
private _state: ProfileSessionState;
4038

39+
private profilingStatusBarIndicator: IStatusbarEntryAccessor | undefined;
40+
private profilingStatusBarIndicatorLabelUpdater: IDisposable | undefined;
41+
4142
public get state() { return this._state; }
4243
public get lastProfile() { return this._profile; }
4344

@@ -46,12 +47,18 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
4647
@IEditorService private readonly _editorService: IEditorService,
4748
@IInstantiationService private readonly _instantiationService: IInstantiationService,
4849
@IWindowsService private readonly _windowsService: IWindowsService,
49-
@IDialogService private readonly _dialogService: IDialogService
50+
@IDialogService private readonly _dialogService: IDialogService,
51+
@IStatusbarService private readonly _statusbarService: IStatusbarService,
5052
) {
5153
super();
5254
this._profile = null;
5355
this._profileSession = null;
5456
this._setState(ProfileSessionState.None);
57+
58+
CommandsRegistry.registerCommand('workbench.action.extensionHostProfilder.stop', () => {
59+
this.stopProfiling();
60+
this._editorService.openEditor(this._instantiationService.createInstance(RuntimeExtensionsInput), { revealIfOpened: true });
61+
});
5562
}
5663

5764
private _setState(state: ProfileSessionState): void {
@@ -61,17 +68,48 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
6168
this._state = state;
6269

6370
if (this._state === ProfileSessionState.Running) {
64-
ProfileExtHostStatusbarItem.instance.show(() => {
65-
this.stopProfiling();
66-
this._editorService.openEditor(this._instantiationService.createInstance(RuntimeExtensionsInput), { revealIfOpened: true });
67-
});
71+
this.updateProfilingStatusBarIndicator(true);
6872
} else if (this._state === ProfileSessionState.Stopping) {
69-
ProfileExtHostStatusbarItem.instance.hide();
73+
this.updateProfilingStatusBarIndicator(false);
7074
}
7175

7276
this._onDidChangeState.fire(undefined);
7377
}
7478

79+
private updateProfilingStatusBarIndicator(visible: boolean): void {
80+
if (this.profilingStatusBarIndicatorLabelUpdater) {
81+
this.profilingStatusBarIndicatorLabelUpdater.dispose();
82+
this.profilingStatusBarIndicatorLabelUpdater = undefined;
83+
}
84+
85+
if (visible) {
86+
const indicator: IStatusbarEntry = {
87+
text: nls.localize('profilingExtensionHost', "$(sync~spin) Profiling Extension Host"),
88+
tooltip: nls.localize('selectAndStartDebug', "Click to stop profiling."),
89+
command: 'workbench.action.extensionHostProfilder.stop'
90+
};
91+
92+
const timeStarted = Date.now();
93+
const handle = setInterval(() => {
94+
if (this.profilingStatusBarIndicator) {
95+
this.profilingStatusBarIndicator.update({ ...indicator, text: nls.localize('profilingExtensionHostTime', "$(sync~spin) Profiling Extension Host ({0} sec)", Math.round((new Date().getTime() - timeStarted) / 1000)), });
96+
}
97+
}, 1000);
98+
this.profilingStatusBarIndicatorLabelUpdater = toDisposable(() => clearInterval(handle));
99+
100+
if (!this.profilingStatusBarIndicator) {
101+
this.profilingStatusBarIndicator = this._statusbarService.addEntry(indicator, StatusbarAlignment.RIGHT);
102+
} else {
103+
this.profilingStatusBarIndicator.update(indicator);
104+
}
105+
} else {
106+
if (this.profilingStatusBarIndicator) {
107+
this.profilingStatusBarIndicator.dispose();
108+
this.profilingStatusBarIndicator = undefined;
109+
}
110+
}
111+
}
112+
75113
public startProfiling(): Promise<any> | null {
76114
if (this._state !== ProfileSessionState.None) {
77115
return null;
@@ -134,76 +172,3 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
134172
}
135173

136174
}
137-
138-
export class ProfileExtHostStatusbarItem implements IStatusbarItem {
139-
140-
public static instance: ProfileExtHostStatusbarItem;
141-
142-
private toDispose: IDisposable[];
143-
private statusBarItem: HTMLElement;
144-
private label: HTMLElement;
145-
private timeStarted: number;
146-
private labelUpdater: any;
147-
private clickHandler: (() => void) | null;
148-
149-
constructor() {
150-
ProfileExtHostStatusbarItem.instance = this;
151-
this.toDispose = [];
152-
this.timeStarted = 0;
153-
}
154-
155-
public show(clickHandler: () => void) {
156-
this.clickHandler = clickHandler;
157-
if (this.timeStarted === 0) {
158-
this.timeStarted = new Date().getTime();
159-
this.statusBarItem.hidden = false;
160-
this.labelUpdater = setInterval(() => {
161-
this.updateLabel();
162-
}, 1000);
163-
this.updateLabel();
164-
}
165-
}
166-
167-
public hide() {
168-
this.clickHandler = null;
169-
this.statusBarItem.hidden = true;
170-
this.timeStarted = 0;
171-
clearInterval(this.labelUpdater);
172-
this.labelUpdater = null;
173-
}
174-
175-
public render(container: HTMLElement): IDisposable {
176-
if (!this.statusBarItem && container) {
177-
this.statusBarItem = append(container, $('.profileExtHost-statusbar-item'));
178-
this.toDispose.push(addDisposableListener(this.statusBarItem, 'click', () => {
179-
if (this.clickHandler) {
180-
this.clickHandler();
181-
}
182-
}));
183-
this.statusBarItem.title = nls.localize('selectAndStartDebug', "Click to stop profiling.");
184-
const a = append(this.statusBarItem, $('a'));
185-
append(a, $('.icon'));
186-
this.label = append(a, $('span.label'));
187-
this.updateLabel();
188-
this.statusBarItem.hidden = true;
189-
}
190-
return this;
191-
}
192-
193-
private updateLabel() {
194-
let label = 'Profiling Extension Host';
195-
if (this.timeStarted > 0) {
196-
let secondsRecoreded = (new Date().getTime() - this.timeStarted) / 1000;
197-
label = `Profiling Extension Host (${Math.round(secondsRecoreded)} sec)`;
198-
}
199-
this.label.textContent = label;
200-
}
201-
202-
public dispose(): void {
203-
this.toDispose = dispose(this.toDispose);
204-
}
205-
}
206-
207-
Registry.as<IStatusbarRegistry>(Extensions.Statusbar).registerStatusbarItem(
208-
new StatusbarItemDescriptor(ProfileExtHostStatusbarItem, StatusbarAlignment.RIGHT)
209-
);

src/vs/workbench/contrib/extensions/electron-browser/media/runtimeExtensionsEditor.css

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,3 @@
3636
.runtime-extensions-editor .monaco-action-bar .actions-container {
3737
justify-content: left;
3838
}
39-
40-
.monaco-workbench .part.statusbar .profileExtHost-statusbar-item .icon {
41-
background: url('profile-stop.svg') no-repeat;
42-
display: inline-block;
43-
padding-right: 2px;
44-
padding-bottom: 2px;
45-
width: 16px;
46-
height: 16px;
47-
vertical-align: middle;
48-
animation:fade 1000ms infinite;
49-
}
50-
51-
@keyframes fade {
52-
from { opacity: 1.0; }
53-
50% { opacity: 0.5; }
54-
to { opacity: 1.0; }
55-
}

0 commit comments

Comments
 (0)