From 37b0e4018cd73d3b32ab89cfcd2be62a40585944 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 27 Aug 2023 07:03:27 -0700 Subject: [PATCH] More adoption of MutableDisposable --- addons/xterm-addon-image/src/ImageRenderer.ts | 6 +- src/browser/services/RenderService.ts | 58 +++++++++---------- src/common/CoreTerminal.ts | 16 ++--- 3 files changed, 35 insertions(+), 45 deletions(-) diff --git a/addons/xterm-addon-image/src/ImageRenderer.ts b/addons/xterm-addon-image/src/ImageRenderer.ts index d225315efa..392816dc9d 100644 --- a/addons/xterm-addon-image/src/ImageRenderer.ts +++ b/addons/xterm-addon-image/src/ImageRenderer.ts @@ -6,6 +6,7 @@ import { toRGBA8888 } from 'sixel/lib/Colors'; import { IDisposable } from 'xterm'; import { ICellSize, ITerminalExt, IImageSpec, IRenderDimensions, IRenderService } from './Types'; +import { MutableDisposable } from 'common/Lifecycle'; const PLACEHOLDER_LENGTH = 4096; @@ -22,7 +23,7 @@ export class ImageRenderer implements IDisposable { private _ctx: CanvasRenderingContext2D | null | undefined; private _placeholder: HTMLCanvasElement | undefined; private _placeholderBitmap: ImageBitmap | undefined; - private _optionsRefresh: IDisposable | undefined; + private _optionsRefresh = new MutableDisposable(); private _oldOpen: ((parent: HTMLElement) => void) | undefined; private _renderService: IRenderService | undefined; private _oldSetRenderer: ((renderer: any) => void) | undefined; @@ -77,7 +78,7 @@ export class ImageRenderer implements IDisposable { this._open(); } // hack to spot fontSize changes - this._optionsRefresh = this._terminal._core.optionsService.onOptionChange(option => { + this._optionsRefresh.value = this._terminal._core.optionsService.onOptionChange(option => { if (option === 'fontSize') { this.rescaleCanvas(); this._renderService?.refreshRows(0, this._terminal.rows); @@ -87,7 +88,6 @@ export class ImageRenderer implements IDisposable { public dispose(): void { - this._optionsRefresh?.dispose(); this.removeLayerFromDom(); if (this._terminal._core && this._oldOpen) { this._terminal._core.open = this._oldOpen; diff --git a/src/browser/services/RenderService.ts b/src/browser/services/RenderService.ts index 41f0c9b5cb..0f18a233ed 100644 --- a/src/browser/services/RenderService.ts +++ b/src/browser/services/RenderService.ts @@ -10,7 +10,7 @@ import { IRenderDebouncerWithCallback } from 'browser/Types'; import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types'; import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services'; import { EventEmitter } from 'common/EventEmitter'; -import { Disposable } from 'common/Lifecycle'; +import { Disposable, MutableDisposable } from 'common/Lifecycle'; import { DebouncedIdleTask } from 'common/TaskQueue'; import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services'; @@ -23,7 +23,7 @@ interface ISelectionState { export class RenderService extends Disposable implements IRenderService { public serviceBrand: undefined; - private _renderer: IRenderer | undefined; + private _renderer: MutableDisposable = this.register(new MutableDisposable()); private _renderDebouncer: IRenderDebouncerWithCallback; private _screenDprMonitor: ScreenDprMonitor; private _pausedResizeTask = new DebouncedIdleTask(); @@ -49,7 +49,7 @@ export class RenderService extends Disposable implements IRenderService { private readonly _onRefreshRequest = this.register(new EventEmitter<{ start: number, end: number }>()); public readonly onRefreshRequest = this._onRefreshRequest.event; - public get dimensions(): IRenderDimensions { return this._renderer!.dimensions; } + public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; } constructor( private _rowCount: number, @@ -63,8 +63,6 @@ export class RenderService extends Disposable implements IRenderService { ) { super(); - this.register({ dispose: () => this._renderer?.dispose() }); - this._renderDebouncer = new RenderDebouncer(coreBrowserService.window, (start, end) => this._renderRows(start, end)); this.register(this._renderDebouncer); @@ -73,7 +71,7 @@ export class RenderService extends Disposable implements IRenderService { this.register(this._screenDprMonitor); this.register(bufferService.onResize(() => this._fullRefresh())); - this.register(bufferService.buffers.onBufferActivate(() => this._renderer?.clear())); + this.register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear())); this.register(optionsService.onOptionChange(() => this._handleOptionsChanged())); this.register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged())); @@ -148,7 +146,7 @@ export class RenderService extends Disposable implements IRenderService { } private _renderRows(start: number, end: number): void { - if (!this._renderer) { + if (!this._renderer.value) { return; } @@ -159,11 +157,11 @@ export class RenderService extends Disposable implements IRenderService { end = Math.min(end, this._rowCount - 1); // Render - this._renderer.renderRows(start, end); + this._renderer.value.renderRows(start, end); // Update selection if needed if (this._needsSelectionRefresh) { - this._renderer.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode); + this._renderer.value.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode); this._needsSelectionRefresh = false; } @@ -181,7 +179,7 @@ export class RenderService extends Disposable implements IRenderService { } private _handleOptionsChanged(): void { - if (!this._renderer) { + if (!this._renderer.value) { return; } this.refreshRows(0, this._rowCount - 1); @@ -189,25 +187,23 @@ export class RenderService extends Disposable implements IRenderService { } private _fireOnCanvasResize(): void { - if (!this._renderer) { + if (!this._renderer.value) { return; } // Don't fire the event if the dimensions haven't changed - if (this._renderer.dimensions.css.canvas.width === this._canvasWidth && this._renderer.dimensions.css.canvas.height === this._canvasHeight) { + if (this._renderer.value.dimensions.css.canvas.width === this._canvasWidth && this._renderer.value.dimensions.css.canvas.height === this._canvasHeight) { return; } - this._onDimensionsChange.fire(this._renderer.dimensions); + this._onDimensionsChange.fire(this._renderer.value.dimensions); } public hasRenderer(): boolean { - return !!this._renderer; + return !!this._renderer.value; } public setRenderer(renderer: IRenderer): void { - // TODO: RenderService should be the only one to dispose the renderer - this._renderer?.dispose(); - this._renderer = renderer; - this._renderer.onRequestRedraw(e => this.refreshRows(e.start, e.end, true)); + this._renderer.value = renderer; + this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, true)); // Force a refresh this._needsSelectionRefresh = true; @@ -227,10 +223,10 @@ export class RenderService extends Disposable implements IRenderService { } public clearTextureAtlas(): void { - if (!this._renderer) { + if (!this._renderer.value) { return; } - this._renderer.clearTextureAtlas?.(); + this._renderer.value.clearTextureAtlas?.(); this._fullRefresh(); } @@ -239,50 +235,50 @@ export class RenderService extends Disposable implements IRenderService { // when devicePixelRatio changes this._charSizeService.measure(); - if (!this._renderer) { + if (!this._renderer.value) { return; } - this._renderer.handleDevicePixelRatioChange(); + this._renderer.value.handleDevicePixelRatioChange(); this.refreshRows(0, this._rowCount - 1); } public handleResize(cols: number, rows: number): void { - if (!this._renderer) { + if (!this._renderer.value) { return; } if (this._isPaused) { - this._pausedResizeTask.set(() => this._renderer!.handleResize(cols, rows)); + this._pausedResizeTask.set(() => this._renderer.value!.handleResize(cols, rows)); } else { - this._renderer.handleResize(cols, rows); + this._renderer.value.handleResize(cols, rows); } this._fullRefresh(); } // TODO: Is this useful when we have onResize? public handleCharSizeChanged(): void { - this._renderer?.handleCharSizeChanged(); + this._renderer.value?.handleCharSizeChanged(); } public handleBlur(): void { - this._renderer?.handleBlur(); + this._renderer.value?.handleBlur(); } public handleFocus(): void { - this._renderer?.handleFocus(); + this._renderer.value?.handleFocus(); } public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void { this._selectionState.start = start; this._selectionState.end = end; this._selectionState.columnSelectMode = columnSelectMode; - this._renderer?.handleSelectionChanged(start, end, columnSelectMode); + this._renderer.value?.handleSelectionChanged(start, end, columnSelectMode); } public handleCursorMove(): void { - this._renderer?.handleCursorMove(); + this._renderer.value?.handleCursorMove(); } public clear(): void { - this._renderer?.clear(); + this._renderer.value?.clear(); } } diff --git a/src/common/CoreTerminal.ts b/src/common/CoreTerminal.ts index 89d9f5e595..47f77406c5 100644 --- a/src/common/CoreTerminal.ts +++ b/src/common/CoreTerminal.ts @@ -21,7 +21,7 @@ * http://linux.die.net/man/7/urxvt */ -import { Disposable, toDisposable } from 'common/Lifecycle'; +import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle'; import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, LogLevelEnum, ITerminalOptions, IOscLinkService } from 'common/services/Services'; import { InstantiationService } from 'common/services/InstantiationService'; import { LogService } from 'common/services/LogService'; @@ -57,7 +57,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal { protected _inputHandler: InputHandler; private _writeBuffer: WriteBuffer; - private _windowsWrappingHeuristics: IDisposable | undefined; + private _windowsWrappingHeuristics = this.register(new MutableDisposable()); private readonly _onBinary = this.register(new EventEmitter()); public readonly onBinary = this._onBinary.event; @@ -144,11 +144,6 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal { // Setup WriteBuffer this._writeBuffer = this.register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult))); this.register(forwardEvent(this._writeBuffer.onWriteParsed, this._onWriteParsed)); - - this.register(toDisposable(() => { - this._windowsWrappingHeuristics?.dispose(); - this._windowsWrappingHeuristics = undefined; - })); } public write(data: string | Uint8Array, callback?: () => void): void { @@ -267,20 +262,19 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal { if (value) { this._enableWindowsWrappingHeuristics(); } else { - this._windowsWrappingHeuristics?.dispose(); - this._windowsWrappingHeuristics = undefined; + this._windowsWrappingHeuristics.clear(); } } protected _enableWindowsWrappingHeuristics(): void { - if (!this._windowsWrappingHeuristics) { + if (!this._windowsWrappingHeuristics.value) { const disposables: IDisposable[] = []; disposables.push(this.onLineFeed(updateWindowsModeWrappedState.bind(null, this._bufferService))); disposables.push(this.registerCsiHandler({ final: 'H' }, () => { updateWindowsModeWrappedState(this._bufferService); return false; })); - this._windowsWrappingHeuristics = toDisposable(() => { + this._windowsWrappingHeuristics.value = toDisposable(() => { for (const d of disposables) { d.dispose(); }