55
66import * as nls from 'vs/nls' ;
77import { 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' ;
99import { 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' ;
1111import { 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' ;
1613import { IExtensionHostProfileService , ProfileSessionState } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor' ;
1714import { IEditorService } from 'vs/workbench/services/editor/common/editorService' ;
1815import { IWindowsService } from 'vs/platform/windows/common/windows' ;
@@ -22,10 +19,11 @@ import product from 'vs/platform/product/node/product';
2219import { RuntimeExtensionsInput } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsInput' ;
2320import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions' ;
2421import { ExtensionHostProfiler } from 'vs/workbench/services/extensions/electron-browser/extensionHostProfiler' ;
22+ import { CommandsRegistry } from 'vs/platform/commands/common/commands' ;
2523
2624export 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- ) ;
0 commit comments