Register all event emitters, make some services disposable

This commit is contained in:
Daniel Imms
2022-10-08 09:00:14 -07:00
parent f61d8c91a3
commit 00f6d3a88c
18 changed files with 89 additions and 76 deletions
+2 -2
View File
@@ -16,9 +16,9 @@ export class WebglAddon extends Disposable implements ITerminalAddon {
private _terminal?: Terminal;
private _renderer?: WebglRenderer;
private readonly _onChangeTextureAtlas = new EventEmitter<HTMLElement>();
private readonly _onChangeTextureAtlas = this.register(new EventEmitter<HTMLElement>());
public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event;
private readonly _onContextLoss = new EventEmitter<void>();
private readonly _onContextLoss = this.register(new EventEmitter<void>());
public readonly onContextLoss = this._onContextLoss.event;
constructor(
@@ -46,11 +46,11 @@ export class WebglRenderer extends Disposable implements IRenderer {
private _isAttached: boolean;
private _contextRestorationTimeout: number | undefined;
private readonly _onChangeTextureAtlas = new EventEmitter<HTMLCanvasElement>();
private readonly _onChangeTextureAtlas = this.register(new EventEmitter<HTMLCanvasElement>());
public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event;
private readonly _onRequestRedraw = new EventEmitter<IRequestRedrawEvent>();
private readonly _onRequestRedraw = this.register(new EventEmitter<IRequestRedrawEvent>());
public readonly onRequestRedraw = this._onRequestRedraw.event;
private readonly _onContextLoss = new EventEmitter<void>();
private readonly _onContextLoss = this.register(new EventEmitter<void>());
public readonly onContextLoss = this._onContextLoss.event;
constructor(
+11 -11
View File
@@ -123,28 +123,28 @@ export class Terminal extends CoreTerminal implements ITerminal {
private _colorManager: ColorManager | undefined;
private _theme: ITheme | undefined;
private readonly _onCursorMove = new EventEmitter<void>();
private readonly _onCursorMove = this.register(new EventEmitter<void>());
public readonly onCursorMove = this._onCursorMove.event;
private readonly _onKey = new EventEmitter<{ key: string, domEvent: KeyboardEvent }>();
private readonly _onKey = this.register(new EventEmitter<{ key: string, domEvent: KeyboardEvent }>());
public readonly onKey = this._onKey.event;
private readonly _onRender = new EventEmitter<{ start: number, end: number }>();
private readonly _onRender = this.register(new EventEmitter<{ start: number, end: number }>());
public readonly onRender = this._onRender.event;
private readonly _onSelectionChange = new EventEmitter<void>();
private readonly _onSelectionChange = this.register(new EventEmitter<void>());
public readonly onSelectionChange = this._onSelectionChange.event;
private readonly _onTitleChange = new EventEmitter<string>();
private readonly _onTitleChange = this.register(new EventEmitter<string>());
public readonly onTitleChange = this._onTitleChange.event;
private readonly _onBell = new EventEmitter<void>();
private readonly _onBell = this.register(new EventEmitter<void>());
public readonly onBell = this._onBell.event;
private _onFocus = new EventEmitter<void>();
private _onFocus = this.register(new EventEmitter<void>());
public get onFocus(): IEvent<void> { return this._onFocus.event; }
private _onBlur = new EventEmitter<void>();
private _onBlur = this.register(new EventEmitter<void>());
public get onBlur(): IEvent<void> { return this._onBlur.event; }
private _onA11yCharEmitter = new EventEmitter<string>();
private _onA11yCharEmitter = this.register(new EventEmitter<string>());
public get onA11yChar(): IEvent<string> { return this._onA11yCharEmitter.event; }
private _onA11yTabEmitter = new EventEmitter<number>();
private _onA11yTabEmitter = this.register(new EventEmitter<number>());
public get onA11yTab(): IEvent<number> { return this._onA11yTabEmitter.event; }
private _onWillOpen = new EventEmitter<HTMLElement>();
private _onWillOpen = this.register(new EventEmitter<HTMLElement>());
public get onWillOpen(): IEvent<HTMLElement> { return this._onWillOpen.event; }
/**
+1 -1
View File
@@ -40,7 +40,7 @@ export class DomRenderer extends Disposable implements IRenderer {
public dimensions: IRenderDimensions;
public readonly onRequestRedraw = new EventEmitter<IRequestRedrawEvent>().event;
public readonly onRequestRedraw = this.register(new EventEmitter<IRequestRedrawEvent>()).event;
constructor(
private _colors: IColorSet,
+1 -1
View File
@@ -16,7 +16,7 @@ export class CharSizeService implements ICharSizeService {
public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }
private readonly _onCharSizeChange = new EventEmitter<void>();
private readonly _onCharSizeChange = this.register(new EventEmitter<void>());
public readonly onCharSizeChange = this._onCharSizeChange.event;
constructor(
+4 -4
View File
@@ -40,13 +40,13 @@ export class RenderService extends Disposable implements IRenderService {
columnSelectMode: false
};
private readonly _onDimensionsChange = new EventEmitter<IRenderDimensions>();
private readonly _onDimensionsChange = this.register(new EventEmitter<IRenderDimensions>());
public readonly onDimensionsChange = this._onDimensionsChange.event;
private readonly _onRenderedViewportChange = new EventEmitter<{ start: number, end: number }>();
private readonly _onRenderedViewportChange = this.register(new EventEmitter<{ start: number, end: number }>());
public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;
private readonly _onRender = new EventEmitter<{ start: number, end: number }>();
private readonly _onRender = this.register(new EventEmitter<{ start: number, end: number }>());
public readonly onRender = this._onRender.event;
private readonly _onRefreshRequest = new EventEmitter<{ start: number, end: number }>();
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; }
+6 -4
View File
@@ -5,6 +5,7 @@
import { ICircularList } from 'common/Types';
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { Disposable } from 'common/Lifecycle';
export interface IInsertEvent {
index: number;
@@ -20,21 +21,22 @@ export interface IDeleteEvent {
* Represents a circular list; a list with a maximum size that wraps around when push is called,
* overriding values at the start of the list.
*/
export class CircularList<T> implements ICircularList<T> {
export class CircularList<T> extends Disposable implements ICircularList<T> {
protected _array: (T | undefined)[];
private _startIndex: number;
private _length: number;
public readonly onDeleteEmitter = new EventEmitter<IDeleteEvent>();
public readonly onDeleteEmitter = this.register(new EventEmitter<IDeleteEvent>());
public readonly onDelete = this.onDeleteEmitter.event;
public readonly onInsertEmitter = new EventEmitter<IInsertEvent>();
public readonly onInsertEmitter = this.register(new EventEmitter<IInsertEvent>());
public readonly onInsert = this.onInsertEmitter.event;
public readonly onTrimEmitter = new EventEmitter<number>();
public readonly onTrimEmitter = this.register(new EventEmitter<number>());
public readonly onTrim = this.onTrimEmitter.event;
constructor(
private _maxLength: number
) {
super();
this._array = new Array<T>(this._maxLength);
this._startIndex = 0;
this._length = 0;
+15 -15
View File
@@ -59,15 +59,15 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
private _writeBuffer: WriteBuffer;
private _windowsMode: IDisposable | undefined;
private readonly _onBinary = new EventEmitter<string>();
private readonly _onBinary = this.register(new EventEmitter<string>());
public readonly onBinary = this._onBinary.event;
private readonly _onData = new EventEmitter<string>();
private readonly _onData = this.register(new EventEmitter<string>());
public readonly onData = this._onData.event;
protected _onLineFeed = new EventEmitter<void>();
protected _onLineFeed = this.register(new EventEmitter<void>());
public readonly onLineFeed = this._onLineFeed.event;
private readonly _onResize = new EventEmitter<{ cols: number, rows: number }>();
private readonly _onResize = this.register(new EventEmitter<{ cols: number, rows: number }>());
public readonly onResize = this._onResize.event;
protected readonly _onWriteParsed = new EventEmitter<void>();
protected readonly _onWriteParsed = this.register(new EventEmitter<void>());
public readonly onWriteParsed = this._onWriteParsed.event;
/**
@@ -75,13 +75,13 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
* it's filtered out.
*/
protected _onScrollApi?: EventEmitter<number, void>;
protected _onScroll = new EventEmitter<IScrollEvent, void>();
protected _onScroll = this.register(new EventEmitter<IScrollEvent, void>());
public get onScroll(): IEvent<number, void> {
if (!this._onScrollApi) {
this._onScrollApi = new EventEmitter<number, void>();
this.register(this._onScroll.event(ev => {
this._onScrollApi = this.register(new EventEmitter<number, void>());
this._onScroll.event(ev => {
this._onScrollApi?.fire(ev.position);
}));
});
}
return this._onScrollApi.event;
}
@@ -103,17 +103,17 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
// Setup and initialize services
this._instantiationService = new InstantiationService();
this.optionsService = new OptionsService(options);
this.optionsService = this.register(new OptionsService(options));
this._instantiationService.setService(IOptionsService, this.optionsService);
this._bufferService = this.register(this._instantiationService.createInstance(BufferService));
this._instantiationService.setService(IBufferService, this._bufferService);
this._logService = this._instantiationService.createInstance(LogService);
this._logService = this.register(this._instantiationService.createInstance(LogService));
this._instantiationService.setService(ILogService, this._logService);
this.coreService = this.register(this._instantiationService.createInstance(CoreService, () => this.scrollToBottom()));
this._instantiationService.setService(ICoreService, this.coreService);
this.coreMouseService = this._instantiationService.createInstance(CoreMouseService);
this.coreMouseService = this.register(this._instantiationService.createInstance(CoreMouseService));
this._instantiationService.setService(ICoreMouseService, this.coreMouseService);
this.unicodeService = this._instantiationService.createInstance(UnicodeService);
this.unicodeService = this.register(this._instantiationService.createInstance(UnicodeService));
this._instantiationService.setService(IUnicodeService, this.unicodeService);
this._charsetService = this._instantiationService.createInstance(CharsetService);
this._instantiationService.setService(ICharsetService, this._charsetService);
@@ -121,7 +121,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
this._instantiationService.setService(IOscLinkService, this._oscLinkService);
// Register input handler and handle/forward events
this._inputHandler = new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.coreMouseService, this.unicodeService);
this._inputHandler = this.register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.coreMouseService, this.unicodeService));
this.register(forwardEvent(this._inputHandler.onLineFeed, this._onLineFeed));
this.register(this._inputHandler);
@@ -141,7 +141,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
}));
// Setup WriteBuffer
this._writeBuffer = new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult));
this._writeBuffer = this.register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));
this.register(forwardEvent(this._writeBuffer.onWriteParsed, this._onWriteParsed));
this.register(toDisposable(() => {
+13 -13
View File
@@ -132,32 +132,32 @@ export class InputHandler extends Disposable implements IInputHandler {
private _activeBuffer: IBuffer;
private readonly _onRequestBell = new EventEmitter<void>();
private readonly _onRequestBell = this.register(new EventEmitter<void>());
public readonly onRequestBell = this._onRequestBell.event;
private readonly _onRequestRefreshRows = new EventEmitter<number, number>();
private readonly _onRequestRefreshRows = this.register(new EventEmitter<number, number>());
public readonly onRequestRefreshRows = this._onRequestRefreshRows.event;
private readonly _onRequestReset = new EventEmitter<void>();
private readonly _onRequestReset = this.register(new EventEmitter<void>());
public readonly onRequestReset = this._onRequestReset.event;
private readonly _onRequestSendFocus = new EventEmitter<void>();
private readonly _onRequestSendFocus = this.register(new EventEmitter<void>());
public readonly onRequestSendFocus = this._onRequestSendFocus.event;
private readonly _onRequestSyncScrollBar = new EventEmitter<void>();
private readonly _onRequestSyncScrollBar = this.register(new EventEmitter<void>());
public readonly onRequestSyncScrollBar = this._onRequestSyncScrollBar.event;
private readonly _onRequestWindowsOptionsReport = new EventEmitter<WindowsOptionsReportType>();
private readonly _onRequestWindowsOptionsReport = this.register(new EventEmitter<WindowsOptionsReportType>());
public readonly onRequestWindowsOptionsReport = this._onRequestWindowsOptionsReport.event;
private readonly _onA11yChar = new EventEmitter<string>();
private readonly _onA11yChar = this.register(new EventEmitter<string>());
public readonly onA11yChar = this._onA11yChar.event;
private readonly _onA11yTab = new EventEmitter<number>();
private readonly _onA11yTab = this.register(new EventEmitter<number>());
public readonly onA11yTab = this._onA11yTab.event;
private readonly _onCursorMove = new EventEmitter<void>();
private readonly _onCursorMove = this.register(new EventEmitter<void>());
public readonly onCursorMove = this._onCursorMove.event;
private readonly _onLineFeed = new EventEmitter<void>();
private readonly _onLineFeed = this.register(new EventEmitter<void>());
public readonly onLineFeed = this._onLineFeed.event;
private readonly _onScroll = new EventEmitter<number>();
private readonly _onScroll = this.register(new EventEmitter<number>());
public readonly onScroll = this._onScroll.event;
private readonly _onTitleChange = new EventEmitter<string>();
private readonly _onTitleChange = this.register(new EventEmitter<string>());
public readonly onTitleChange = this._onTitleChange.event;
private readonly _onColor = new EventEmitter<IColorEvent>();
private readonly _onColor = this.register(new EventEmitter<IColorEvent>());
public readonly onColor = this._onColor.event;
private _parseStack: IParseStack = {
+2 -2
View File
@@ -13,10 +13,10 @@ export class Marker extends Disposable implements IMarker {
private _id: number = Marker._nextId++;
public get id(): number { return this._id; }
private readonly _onDispose = new EventEmitter<void>();
private readonly _onDispose = this.register(new EventEmitter<void>());
public readonly onDispose = this._onDispose.event;
public get isDisposed(): boolean { return this._isDisposed; };
public get isDisposed(): boolean { return this._isDisposed; }
constructor(
public line: number
+6 -3
View File
@@ -5,6 +5,7 @@
*/
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { Disposable } from 'common/Lifecycle';
declare const setTimeout: (handler: () => void, timeout?: number) => void;
@@ -33,7 +34,7 @@ const WRITE_TIMEOUT_MS = 12;
*/
const WRITE_BUFFER_LENGTH_THRESHOLD = 50;
export class WriteBuffer {
export class WriteBuffer extends Disposable {
private _writeBuffer: (string | Uint8Array)[] = [];
private _callbacks: ((() => void) | undefined)[] = [];
private _pendingData = 0;
@@ -42,10 +43,12 @@ export class WriteBuffer {
private _syncCalls = 0;
private _didUserInput = false;
private readonly _onWriteParsed = new EventEmitter<void>();
private readonly _onWriteParsed = this.register(new EventEmitter<void>());
public readonly onWriteParsed = this._onWriteParsed.event;
constructor(private _action: (data: string | Uint8Array, promiseResult?: boolean) => void | Promise<boolean>) { }
constructor(private _action: (data: string | Uint8Array, promiseResult?: boolean) => void | Promise<boolean>) {
super();
}
public handleUserInput(): void {
this._didUserInput = true;
+1 -1
View File
@@ -5,7 +5,7 @@
import { IBuffer as IBufferApi, IBufferNamespace as IBufferNamespaceApi } from 'xterm';
import { BufferApiView } from 'common/public/BufferApiView';
import { IEvent, EventEmitter } from 'common/EventEmitter';
import { EventEmitter } from 'common/EventEmitter';
import { ICoreTerminal } from 'common/Types';
export class BufferNamespaceApi implements IBufferNamespaceApi {
+2 -2
View File
@@ -22,9 +22,9 @@ export class BufferService extends Disposable implements IBufferService {
/** Whether the user is scrolling (locks the scroll position) */
public isUserScrolling: boolean = false;
private readonly _onResize = new EventEmitter<{ cols: number, rows: number }>();
private readonly _onResize = this.register(new EventEmitter<{ cols: number, rows: number }>());
public readonly onResize = this._onResize.event;
private readonly _onScroll = new EventEmitter<number>();
private readonly _onScroll = this.register(new EventEmitter<number>());
public readonly onScroll = this._onScroll.event;
public get buffer(): IBuffer { return this.buffers.active; }
+4 -2
View File
@@ -5,6 +5,7 @@
import { IBufferService, ICoreService, ICoreMouseService } from 'common/services/Services';
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { ICoreMouseProtocol, ICoreMouseEvent, CoreMouseEncoding, CoreMouseEventType, CoreMouseButton, CoreMouseAction } from 'common/Types';
import { Disposable } from 'common/Lifecycle';
/**
* Supported default protocols.
@@ -165,20 +166,21 @@ const DEFAULT_ENCODINGS: { [key: string]: CoreMouseEncoding } = {
* a tracking report to the backend based on protocol and encoding limitations.
* To send a mouse event call `triggerMouseEvent`.
*/
export class CoreMouseService implements ICoreMouseService {
export class CoreMouseService extends Disposable implements ICoreMouseService {
private _protocols: { [name: string]: ICoreMouseProtocol } = {};
private _encodings: { [name: string]: CoreMouseEncoding } = {};
private _activeProtocol: string = '';
private _activeEncoding: string = '';
private _lastEvent: ICoreMouseEvent | null = null;
private readonly _onProtocolChange = new EventEmitter<CoreMouseEventType>();
private readonly _onProtocolChange = this.register(new EventEmitter<CoreMouseEventType>());
public readonly onProtocolChange = this._onProtocolChange.event;
constructor(
@IBufferService private readonly _bufferService: IBufferService,
@ICoreService private readonly _coreService: ICoreService
) {
super();
// register default protocols and encodings
for (const name of Object.keys(DEFAULT_PROTOCOLS)) this.addProtocol(name, DEFAULT_PROTOCOLS[name]);
for (const name of Object.keys(DEFAULT_ENCODINGS)) this.addEncoding(name, DEFAULT_ENCODINGS[name]);
+5 -3
View File
@@ -3,6 +3,7 @@
* @license MIT
*/
import { Disposable } from 'common/Lifecycle';
import { ILogService, IOptionsService, LogLevelEnum } from 'common/services/Services';
type LogType = (message?: any, ...optionalParams: any[]) => void;
@@ -29,7 +30,7 @@ const optionsKeyToLogLevel: { [key: string]: LogLevelEnum } = {
const LOG_PREFIX = 'xterm.js: ';
export class LogService implements ILogService {
export class LogService extends Disposable implements ILogService {
public serviceBrand: any;
public logLevel: LogLevelEnum = LogLevelEnum.OFF;
@@ -37,12 +38,13 @@ export class LogService implements ILogService {
constructor(
@IOptionsService private readonly _optionsService: IOptionsService
) {
super();
this._updateLogLevel();
this._optionsService.onOptionChange(key => {
this.register(this._optionsService.onOptionChange(key => {
if (key === 'logLevel') {
this._updateLogLevel();
}
});
}));
}
private _updateLogLevel(): void {
+4 -2
View File
@@ -7,6 +7,7 @@ import { IOptionsService, ITerminalOptions, FontWeight } from 'common/services/S
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { isMac } from 'common/Platform';
import { CursorStyle } from 'common/Types';
import { Disposable } from 'common/Lifecycle';
export const DEFAULT_OPTIONS: Readonly<Required<ITerminalOptions>> = {
cols: 80,
@@ -51,16 +52,17 @@ export const DEFAULT_OPTIONS: Readonly<Required<ITerminalOptions>> = {
const FONT_WEIGHT_OPTIONS: Extract<FontWeight, string>[] = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];
export class OptionsService implements IOptionsService {
export class OptionsService extends Disposable implements IOptionsService {
public serviceBrand: any;
public readonly rawOptions: Required<ITerminalOptions>;
public options: Required<ITerminalOptions>;
private readonly _onOptionChange = new EventEmitter<string>();
private readonly _onOptionChange = this.register(new EventEmitter<string>());
public readonly onOptionChange = this._onOptionChange.event;
constructor(options: Partial<ITerminalOptions>) {
super();
// set the default value of each option
const defaultOptions = { ...DEFAULT_OPTIONS };
for (const key in options) {
+4 -2
View File
@@ -5,19 +5,21 @@
import { IUnicodeService, IUnicodeVersionProvider } from 'common/services/Services';
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { UnicodeV6 } from 'common/input/UnicodeV6';
import { Disposable } from 'common/Lifecycle';
export class UnicodeService implements IUnicodeService {
export class UnicodeService extends Disposable implements IUnicodeService {
public serviceBrand: any;
private _providers: {[key: string]: IUnicodeVersionProvider} = Object.create(null);
private _active: string = '';
private _activeProvider: IUnicodeVersionProvider;
private readonly _onChange = new EventEmitter<string>();
private readonly _onChange = super.register(new EventEmitter<string>();
public readonly onChange = this._onChange.event;
constructor() {
super();
const defaultProvider = new UnicodeV6();
this.register(defaultProvider);
this._active = defaultProvider.version;
+5 -5
View File
@@ -32,15 +32,15 @@ export class Terminal extends CoreTerminal {
// TODO: We should remove options once components adopt optionsService
public get options(): Required<IInitializedTerminalOptions> { return this.optionsService.options; }
private readonly _onBell = new EventEmitter<void>();
private readonly _onBell = this.register(new EventEmitter<void>());
public readonly onBell = this._onBell.event;
private readonly _onCursorMove = new EventEmitter<void>();
private readonly _onCursorMove = this.register(new EventEmitter<void>());
public readonly onCursorMove = this._onCursorMove.event;
private readonly _onTitleChange = new EventEmitter<string>();
private readonly _onTitleChange = this.register(new EventEmitter<string>());
public readonly onTitleChange = this._onTitleChange.event;
private readonly _onA11yCharEmitter = new EventEmitter<string>();
private readonly _onA11yCharEmitter = this.register(new EventEmitter<string>());
public readonly onA11yChar = this._onA11yCharEmitter.event;
private readonly _onA11yTabEmitter = new EventEmitter<number>();
private readonly _onA11yTabEmitter = this.register(new EventEmitter<number>());
public readonly onA11yTab = this._onA11yTabEmitter.event;
/**