More adoption of MutableDisposable

This commit is contained in:
Daniel Imms
2023-08-27 07:03:27 -07:00
parent 57db72d287
commit 37b0e4018c
3 changed files with 35 additions and 45 deletions
@@ -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;
+27 -31
View File
@@ -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<IRenderer> = 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();
}
}
+5 -11
View File
@@ -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<string>());
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();
}