@@ -8,7 +8,7 @@ import { findLast } from 'vs/base/common/arraysFind';
8
8
import { BugIndicatingError , onUnexpectedError } from 'vs/base/common/errors' ;
9
9
import { Event } from 'vs/base/common/event' ;
10
10
import { toDisposable } from 'vs/base/common/lifecycle' ;
11
- import { IObservable , ITransaction , autorun , autorunWithStore , derived , observableFromEvent , observableValue , recomputeInitiallyAndOnChange , subtransaction , transaction } from 'vs/base/common/observable' ;
11
+ import { IObservable , ITransaction , autorun , autorunWithStore , derived , disposableObservableValue , observableFromEvent , observableValue , recomputeInitiallyAndOnChange , subtransaction , transaction } from 'vs/base/common/observable' ;
12
12
import { derivedDisposable } from 'vs/base/common/observableInternal/derived' ;
13
13
import 'vs/css!./style' ;
14
14
import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration' ;
@@ -26,7 +26,7 @@ import { HideUnchangedRegionsFeature } from 'vs/editor/browser/widget/diffEditor
26
26
import { MovedBlocksLinesFeature } from 'vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature' ;
27
27
import { OverviewRulerFeature } from 'vs/editor/browser/widget/diffEditor/features/overviewRulerFeature' ;
28
28
import { RevertButtonsFeature } from 'vs/editor/browser/widget/diffEditor/features/revertButtonsFeature' ;
29
- import { CSSStyle , ObservableElementSizeObserver , applyStyle , applyViewZones , translatePosition } from 'vs/editor/browser/widget/diffEditor/utils' ;
29
+ import { CSSStyle , ObservableElementSizeObserver , RefCounted , applyStyle , applyViewZones , translatePosition } from 'vs/editor/browser/widget/diffEditor/utils' ;
30
30
import { readHotReloadableExport } from 'vs/base/common/hotReloadHelpers' ;
31
31
import { bindContextKey } from 'vs/platform/observable/common/platformObservableUtils' ;
32
32
import { IDiffEditorOptions } from 'vs/editor/common/config/editorOptions' ;
@@ -62,8 +62,8 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor {
62
62
h ( 'div.editor.modified@modified' , { style : { position : 'absolute' , height : '100%' , } } ) ,
63
63
h ( 'div.accessibleDiffViewer@accessibleDiffViewer' , { style : { position : 'absolute' , height : '100%' } } ) ,
64
64
] ) ;
65
- private readonly _diffModel = observableValue < DiffEditorViewModel | undefined > ( this , undefined ) ;
66
- private _shouldDisposeDiffModel = false ;
65
+ private readonly _diffModelSrc = this . _register ( disposableObservableValue < RefCounted < DiffEditorViewModel > | undefined > ( this , undefined ) ) ;
66
+ private readonly _diffModel = derived < DiffEditorViewModel | undefined > ( this , reader => this . _diffModelSrc . read ( reader ) ?. object ) ;
67
67
public readonly onDidChangeModel = Event . fromObservableLight ( this . _diffModel ) ;
68
68
69
69
public get onDidContentSizeChange ( ) { return this . _editors . onDidContentSizeChange ; }
@@ -318,12 +318,6 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor {
318
318
}
319
319
} ) ) ;
320
320
321
- this . _register ( toDisposable ( ( ) => {
322
- if ( this . _shouldDisposeDiffModel ) {
323
- this . _diffModel . get ( ) ?. dispose ( ) ;
324
- }
325
- } ) ) ;
326
-
327
321
this . _register ( autorunWithStore ( ( reader , store ) => {
328
322
store . add ( new ( readHotReloadableExport ( RevertButtonsFeature , reader ) ) ( this . _editors , this . _diffModel , this . _options , this ) ) ;
329
323
} ) ) ;
@@ -478,30 +472,36 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor {
478
472
479
473
override getModel ( ) : IDiffEditorModel | null { return this . _diffModel . get ( ) ?. model ?? null ; }
480
474
481
- override setModel ( model : IDiffEditorModel | null | IDiffEditorViewModel , tx ?: ITransaction ) : void {
482
- if ( ! model && this . _diffModel . get ( ) ) {
475
+ override setModel ( model : IDiffEditorModel | null | IDiffEditorViewModel ) : void {
476
+ const vm = ! model ? null
477
+ : ( 'model' in model ) ? RefCounted . create ( model ) . createNewRef ( this )
478
+ : RefCounted . create ( this . createViewModel ( model ) , this ) ;
479
+ this . setDiffModel ( vm ) ;
480
+ }
481
+
482
+ setDiffModel ( viewModel : RefCounted < IDiffEditorViewModel > | null , tx ?: ITransaction ) : void {
483
+ const currentModel = this . _diffModel . get ( ) ;
484
+
485
+ if ( ! viewModel && currentModel ) {
483
486
// Transitioning from a model to no-model
484
487
this . _accessibleDiffViewer . get ( ) . close ( ) ;
485
488
}
486
489
487
- const vm = model ? ( 'model' in model ) ? { model, shouldDispose : false } : { model : this . createViewModel ( model ) , shouldDispose : true } : undefined ;
488
-
489
- if ( this . _diffModel . get ( ) !== vm ?. model ) {
490
+ if ( this . _diffModel . get ( ) !== viewModel ?. object ) {
490
491
subtransaction ( tx , tx => {
492
+ const vm = viewModel ?. object ;
491
493
/** @description DiffEditorWidget.setModel */
492
494
observableFromEvent . batchEventsGlobally ( tx , ( ) => {
493
- this . _editors . original . setModel ( vm ? vm . model . model . original : null ) ;
494
- this . _editors . modified . setModel ( vm ? vm . model . model . modified : null ) ;
495
+ this . _editors . original . setModel ( vm ? vm . model . original : null ) ;
496
+ this . _editors . modified . setModel ( vm ? vm . model . modified : null ) ;
495
497
} ) ;
496
- const prevValue = this . _diffModel . get ( ) ;
497
- const shouldDispose = this . _shouldDisposeDiffModel ;
498
-
499
- this . _shouldDisposeDiffModel = vm ?. shouldDispose ?? false ;
500
- this . _diffModel . set ( vm ?. model as ( DiffEditorViewModel | undefined ) , tx ) ;
501
-
502
- if ( shouldDispose ) {
503
- prevValue ?. dispose ( ) ;
504
- }
498
+ const prevValueRef = this . _diffModelSrc . get ( ) ?. createNewRef ( this ) ;
499
+ this . _diffModelSrc . set ( viewModel ?. createNewRef ( this ) as RefCounted < DiffEditorViewModel > | undefined , tx ) ;
500
+ setTimeout ( ( ) => {
501
+ // async, so that this runs after the transaction finished.
502
+ // TODO: use the transaction to schedule disposal
503
+ prevValueRef ?. dispose ( ) ;
504
+ } , 0 ) ;
505
505
} ) ;
506
506
}
507
507
}
0 commit comments