66import 'vs/css!./media/compositepart' ;
77import * as nls from 'vs/nls' ;
88import { defaultGenerator } from 'vs/base/common/idGenerator' ;
9- import { IDisposable , dispose } from 'vs/base/common/lifecycle' ;
9+ import { IDisposable , dispose , toDisposable } from 'vs/base/common/lifecycle' ;
1010import * as strings from 'vs/base/common/strings' ;
1111import { Emitter } from 'vs/base/common/event' ;
1212import * as errors from 'vs/base/common/errors' ;
@@ -46,20 +46,24 @@ export interface ICompositeTitleLabel {
4646 updateStyles ( ) : void ;
4747}
4848
49+ interface CompositeItem {
50+ composite : Composite ;
51+ disposable : IDisposable ;
52+ progressService : IProgressService ;
53+ }
54+
4955export abstract class CompositePart < T extends Composite > extends Part {
5056
5157 protected _onDidCompositeOpen = this . _register ( new Emitter < { composite : IComposite , focus : boolean } > ( ) ) ;
5258 protected _onDidCompositeClose = this . _register ( new Emitter < IComposite > ( ) ) ;
5359
5460 protected toolBar : ToolBar ;
5561
56- private instantiatedCompositeListeners : IDisposable [ ] ;
5762 private mapCompositeToCompositeContainer : { [ compositeId : string ] : HTMLElement ; } ;
5863 private mapActionsBindingToComposite : { [ compositeId : string ] : ( ) => void ; } ;
59- private mapProgressServiceToComposite : { [ compositeId : string ] : IProgressService ; } ;
6064 private activeComposite : Composite | null ;
6165 private lastActiveCompositeId : string ;
62- private instantiatedComposites : Composite [ ] ;
66+ private instantiatedCompositeItems : Map < string , CompositeItem > ;
6367 private titleLabel : ICompositeTitleLabel ;
6468 private progressBar : ProgressBar ;
6569 private contentAreaSize : Dimension ;
@@ -86,12 +90,10 @@ export abstract class CompositePart<T extends Composite> extends Part {
8690 ) {
8791 super ( id , options , themeService , storageService ) ;
8892
89- this . instantiatedCompositeListeners = [ ] ;
9093 this . mapCompositeToCompositeContainer = { } ;
9194 this . mapActionsBindingToComposite = { } ;
92- this . mapProgressServiceToComposite = { } ;
9395 this . activeComposite = null ;
94- this . instantiatedComposites = [ ] ;
96+ this . instantiatedCompositeItems = new Map < string , CompositeItem > ( ) ;
9597 this . lastActiveCompositeId = storageService . get ( activeCompositeSettingsKey , StorageScope . WORKSPACE , this . defaultCompositeId ) ;
9698 }
9799
@@ -159,10 +161,9 @@ export abstract class CompositePart<T extends Composite> extends Part {
159161 protected createComposite ( id : string , isActive ?: boolean ) : Composite {
160162
161163 // Check if composite is already created
162- for ( const composite of this . instantiatedComposites ) {
163- if ( composite . getId ( ) === id ) {
164- return composite ;
165- }
164+ const compositeItem = this . instantiatedCompositeItems . get ( id ) ;
165+ if ( compositeItem ) {
166+ return compositeItem . composite ;
166167 }
167168
168169 // Instantiate composite from registry otherwise
@@ -172,13 +173,13 @@ export abstract class CompositePart<T extends Composite> extends Part {
172173 const compositeInstantiationService = this . instantiationService . createChild ( new ServiceCollection ( [ IProgressService , progressService ] ) ) ;
173174
174175 const composite = compositeDescriptor . instantiate ( compositeInstantiationService ) ;
175- this . mapProgressServiceToComposite [ composite . getId ( ) ] = progressService ;
176+ const disposables : IDisposable [ ] = [ ] ;
176177
177178 // Remember as Instantiated
178- this . instantiatedComposites . push ( composite ) ;
179+ this . instantiatedCompositeItems . set ( id , { composite, disposable : toDisposable ( ( ) => dispose ( disposables ) ) , progressService } ) ;
179180
180181 // Register to title area update events from the composite
181- this . instantiatedCompositeListeners . push ( composite . onTitleAreaUpdate ( ( ) => this . onTitleAreaUpdate ( composite . getId ( ) ) ) ) ;
182+ composite . onTitleAreaUpdate ( ( ) => this . onTitleAreaUpdate ( composite . getId ( ) ) , this , disposables ) ;
182183
183184 return composite ;
184185 }
@@ -219,9 +220,9 @@ export abstract class CompositePart<T extends Composite> extends Part {
219220 }
220221
221222 // Report progress for slow loading composites (but only if we did not create the composites before already)
222- const progressService = this . mapProgressServiceToComposite [ composite . getId ( ) ] ;
223- if ( progressService && ! compositeContainer ) {
224- this . mapProgressServiceToComposite [ composite . getId ( ) ] . showWhile ( Promise . resolve ( ) , this . partService . isRestored ( ) ? 800 : 3200 /* less ugly initial startup */ ) ;
223+ const compositeItem = this . instantiatedCompositeItems . get ( composite . getId ( ) ) ;
224+ if ( compositeItem && ! compositeContainer ) {
225+ compositeItem . progressService . showWhile ( Promise . resolve ( ) , this . partService . isRestored ( ) ? 800 : 3200 /* less ugly initial startup */ ) ;
225226 }
226227
227228 // Fill Content and Actions
@@ -446,8 +447,9 @@ export abstract class CompositePart<T extends Composite> extends Part {
446447 return contentContainer ;
447448 }
448449
449- getProgressIndicator ( id : string ) : IProgressService {
450- return this . mapProgressServiceToComposite [ id ] ;
450+ getProgressIndicator ( id : string ) : IProgressService | null {
451+ const compositeItem = this . instantiatedCompositeItems . get ( id ) ;
452+ return compositeItem ? compositeItem . progressService : null ;
451453 }
452454
453455 protected getActions ( ) : IAction [ ] {
@@ -476,17 +478,33 @@ export abstract class CompositePart<T extends Composite> extends Part {
476478 return sizes ;
477479 }
478480
481+ protected removeComposite ( compositeId : string ) : boolean {
482+ if ( this . activeComposite && this . activeComposite . getId ( ) === compositeId ) {
483+ // do not remove active compoiste
484+ return false ;
485+ }
486+
487+ delete this . mapCompositeToCompositeContainer [ compositeId ] ;
488+ delete this . mapActionsBindingToComposite [ compositeId ] ;
489+ const compositeItem = this . instantiatedCompositeItems . get ( compositeId ) ;
490+ if ( compositeItem ) {
491+ compositeItem . composite . dispose ( ) ;
492+ dispose ( compositeItem . disposable ) ;
493+ this . instantiatedCompositeItems . delete ( compositeId ) ;
494+ }
495+ return true ;
496+ }
497+
479498 dispose ( ) : void {
480499 this . mapCompositeToCompositeContainer = null ! ; // StrictNullOverride: nulling out ok in dispose
481- this . mapProgressServiceToComposite = null ! ; // StrictNullOverride: nulling out ok in dispose
482500 this . mapActionsBindingToComposite = null ! ; // StrictNullOverride: nulling out ok in dispose
483501
484- for ( const composite of this . instantiatedComposites ) {
485- composite . dispose ( ) ;
486- }
502+ this . instantiatedCompositeItems . forEach ( compositeItem => {
503+ compositeItem . composite . dispose ( ) ;
504+ dispose ( compositeItem . disposable ) ;
505+ } ) ;
487506
488- this . instantiatedComposites = [ ] ;
489- this . instantiatedCompositeListeners = dispose ( this . instantiatedCompositeListeners ) ;
507+ this . instantiatedCompositeItems . clear ( ) ;
490508
491509 super . dispose ( ) ;
492510 }
0 commit comments