diff --git a/addons/addon-webgl/src/CharAtlasCache.ts b/addons/addon-webgl/src/CharAtlasCache.ts index 62ff4ff9..823a74cc 100644 --- a/addons/addon-webgl/src/CharAtlasCache.ts +++ b/addons/addon-webgl/src/CharAtlasCache.ts @@ -8,6 +8,7 @@ import { ITerminalOptions, Terminal } from '@xterm/xterm'; import { ITerminal, ReadonlyColorSet } from 'browser/Types'; import { ICharAtlasConfig, ITextureAtlas } from './Types'; import { generateConfig, configEquals } from './CharAtlasUtils'; +import type { ILogService } from 'common/services/Services'; interface ITextureAtlasCacheEntry { atlas: ITextureAtlas; @@ -67,8 +68,9 @@ export function acquireTextureAtlas( } const core: ITerminal = (terminal as any)._core; + const logService = (core as any)._logService as ILogService; const newEntry: ITextureAtlasCacheEntry = { - atlas: new TextureAtlas(document, newConfig, core.unicodeService), + atlas: new TextureAtlas(document, newConfig, core.unicodeService, logService), config: newConfig, ownedBy: [terminal] }; diff --git a/addons/addon-webgl/src/TextureAtlas.ts b/addons/addon-webgl/src/TextureAtlas.ts index aa0e2653..97046ba0 100644 --- a/addons/addon-webgl/src/TextureAtlas.ts +++ b/addons/addon-webgl/src/TextureAtlas.ts @@ -14,7 +14,7 @@ import { IdleTaskQueue } from 'common/TaskQueue'; import { IColor } from 'common/Types'; import { AttributeData } from 'common/buffer/AttributeData'; import { Attributes, DEFAULT_COLOR, DEFAULT_EXT, UnderlineStyle } from 'common/buffer/Constants'; -import { IUnicodeService } from 'common/services/Services'; +import { ILogService, IUnicodeService } from 'common/services/Services'; import { Emitter } from 'common/Event'; /** @@ -88,7 +88,8 @@ export class TextureAtlas implements ITextureAtlas { constructor( private readonly _document: Document, private readonly _config: ICharAtlasConfig, - private readonly _unicodeService: IUnicodeService + private readonly _unicodeService: IUnicodeService, + private readonly _logService: ILogService ) { this._createNewPage(); this._tmpCanvas = createCanvas( @@ -119,7 +120,7 @@ export class TextureAtlas implements ITextureAtlas { private _doWarmUp(): void { // Pre-fill with ASCII 33-126, this is not urgent and done in idle callbacks - const queue = new IdleTaskQueue(); + const queue = new IdleTaskQueue(this._logService); for (let i = 33; i < 126; i++) { queue.enqueue(() => { if (!this._cacheMap.get(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT)) { diff --git a/src/browser/services/RenderService.ts b/src/browser/services/RenderService.ts index 63f83c5b..ada3df30 100644 --- a/src/browser/services/RenderService.ts +++ b/src/browser/services/RenderService.ts @@ -9,7 +9,7 @@ import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types'; import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services'; import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle'; import { DebouncedIdleTask } from 'common/TaskQueue'; -import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services'; +import { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from 'common/services/Services'; import { Emitter } from 'common/Event'; interface ISelectionState { @@ -27,7 +27,7 @@ export class RenderService extends Disposable implements IRenderService { private _renderer: MutableDisposable = this._register(new MutableDisposable()); private _renderDebouncer: IRenderDebouncerWithCallback; - private _pausedResizeTask = new DebouncedIdleTask(); + private _pausedResizeTask: DebouncedIdleTask; private _observerDisposable = this._register(new MutableDisposable()); private _isPaused: boolean = false; @@ -58,6 +58,7 @@ export class RenderService extends Disposable implements IRenderService { private _rowCount: number, screenElement: HTMLElement, @IOptionsService private readonly _optionsService: IOptionsService, + @ILogService private readonly _logService: ILogService, @ICharSizeService private readonly _charSizeService: ICharSizeService, @ICoreService private readonly _coreService: ICoreService, @IDecorationService decorationService: IDecorationService, @@ -67,6 +68,8 @@ export class RenderService extends Disposable implements IRenderService { ) { super(); + this._pausedResizeTask = new DebouncedIdleTask(this._logService); + this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService); this._register(this._renderDebouncer); diff --git a/src/common/CoreTerminal.ts b/src/common/CoreTerminal.ts index 99d1411c..0ce19a4d 100644 --- a/src/common/CoreTerminal.ts +++ b/src/common/CoreTerminal.ts @@ -107,10 +107,10 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal { this._instantiationService = new InstantiationService(); 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._register(this._instantiationService.createInstance(LogService)); this._instantiationService.setService(ILogService, this._logService); + this._bufferService = this._register(this._instantiationService.createInstance(BufferService)); + this._instantiationService.setService(IBufferService, this._bufferService); this.coreService = this._register(this._instantiationService.createInstance(CoreService)); this._instantiationService.setService(ICoreService, this.coreService); this.coreMouseService = this._register(this._instantiationService.createInstance(CoreMouseService)); diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index d7026e50..f36c28b4 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -65,7 +65,7 @@ describe('InputHandler', () => { beforeEach(() => { optionsService = new MockOptionsService(); - bufferService = new BufferService(optionsService); + bufferService = new BufferService(optionsService, new MockLogService()); bufferService.resize(80, 30); coreService = new CoreService(bufferService, new MockLogService(), optionsService); oscLinkService = new OscLinkService(bufferService); @@ -2458,7 +2458,7 @@ describe('InputHandler', () => { beforeEach(() => { optionsService = new MockOptionsService({ vtExtensions: { kittyKeyboard: true } }); - bufferService = new BufferService(optionsService); + bufferService = new BufferService(optionsService, new MockLogService()); bufferService.resize(80, 30); coreService = new CoreService(bufferService, new MockLogService(), optionsService); inputHandler = new TestInputHandler(bufferService, new MockCharsetService(), coreService, new MockLogService(), optionsService, new MockOscLinkService(), new MockCoreMouseService(), new MockUnicodeService()); @@ -2508,7 +2508,7 @@ describe('InputHandler', () => { beforeEach(() => { optionsService = new MockOptionsService(); - bufferService = new BufferService(optionsService); + bufferService = new BufferService(optionsService, new MockLogService()); bufferService.resize(80, 30); coreService = new CoreService(bufferService, new MockLogService(), optionsService); coreService.onData(data => { console.log(data); }); diff --git a/src/common/SortedList.test.ts b/src/common/SortedList.test.ts index d2e01ba8..4718cf97 100644 --- a/src/common/SortedList.test.ts +++ b/src/common/SortedList.test.ts @@ -5,6 +5,7 @@ import { assert } from 'chai'; import { SortedList } from 'common/SortedList'; +import { MockLogService } from 'common/TestUtils.test'; const deepStrictEqual = assert.deepStrictEqual; @@ -15,7 +16,7 @@ describe('SortedList', () => { } beforeEach(() => { - list = new SortedList(e => e); + list = new SortedList(e => e, new MockLogService()); }); describe('insert', () => { @@ -90,7 +91,7 @@ describe('SortedList', () => { assertList([]); }); it('custom key', () => { - const customList = new SortedList<{ key: number }>(e => e.key); + const customList = new SortedList<{ key: number }>(e => e.key, new MockLogService()); customList.insert({ key: 5 }); customList.insert({ key: 2 }); customList.insert({ key: 10 }); diff --git a/src/common/SortedList.ts b/src/common/SortedList.ts index 82b6dfa6..c6dc6208 100644 --- a/src/common/SortedList.ts +++ b/src/common/SortedList.ts @@ -4,6 +4,7 @@ */ import { IdleTaskQueue } from 'common/TaskQueue'; +import type { ILogService } from 'common/services/Services'; // Work variables to avoid garbage collection. let i = 0; @@ -18,16 +19,19 @@ export class SortedList { private _array: T[] = []; private readonly _insertedValues: T[] = []; - private readonly _flushInsertedTask = new IdleTaskQueue(); + private readonly _flushInsertedTask: InstanceType; private _isFlushingInserted = false; private readonly _deletedIndices: number[] = []; - private readonly _flushDeletedTask = new IdleTaskQueue(); + private readonly _flushDeletedTask: InstanceType; private _isFlushingDeleted = false; constructor( - private readonly _getKey: (value: T) => number + private readonly _getKey: (value: T) => number, + logService: ILogService ) { + this._flushInsertedTask = new IdleTaskQueue(logService); + this._flushDeletedTask = new IdleTaskQueue(logService); } public clear(): void { diff --git a/src/common/TaskQueue.ts b/src/common/TaskQueue.ts index 40cddffd..508e5d46 100644 --- a/src/common/TaskQueue.ts +++ b/src/common/TaskQueue.ts @@ -4,6 +4,7 @@ */ import { isNode } from 'common/Platform'; +import type { ILogService } from 'common/services/Services'; interface ITaskQueue { /** @@ -34,6 +35,11 @@ abstract class TaskQueue implements ITaskQueue { private _tasks: (() => boolean | void)[] = []; private _idleCallback?: number; private _i = 0; + protected readonly _logService: ILogService; + + constructor(logService: ILogService) { + this._logService = logService; + } protected abstract _requestCallback(callback: CallbackWithDeadline): number; protected abstract _cancelCallback(identifier: number): void; @@ -90,7 +96,7 @@ abstract class TaskQueue implements ITaskQueue { // Warn when the time exceeding the deadline is over 20ms, if this happens in practice the // task should be split into sub-tasks to ensure the UI remains responsive. if (lastDeadlineRemaining - taskDuration < -20) { - console.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`); + this._logService.warn(`task queue exceeded allotted deadline by ${Math.abs(Math.round(lastDeadlineRemaining - taskDuration))}ms`); } this._start(); return; @@ -151,8 +157,8 @@ export const IdleTaskQueue = (!isNode && 'requestIdleCallback' in window) ? Idle export class DebouncedIdleTask { private _queue: ITaskQueue; - constructor() { - this._queue = new IdleTaskQueue(); + constructor(logService: ILogService) { + this._queue = new IdleTaskQueue(logService); } public set(task: () => boolean | void): void { diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index 908cae0c..6e6f0b64 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -27,7 +27,7 @@ export class MockBufferService implements IBufferService { public rows: number, optionsService: IOptionsService = new MockOptionsService() ) { - this.buffers = new BufferSet(optionsService, this); + this.buffers = new BufferSet(optionsService, this, new MockLogService()); // Listen to buffer activation events and automatically fire scroll events this.buffers.onBufferActivate(e => { this._onScroll.fire(e.activeBuffer.ydisp); diff --git a/src/common/buffer/Buffer.test.ts b/src/common/buffer/Buffer.test.ts index 39cffb49..f9e3e1b1 100644 --- a/src/common/buffer/Buffer.test.ts +++ b/src/common/buffer/Buffer.test.ts @@ -6,7 +6,7 @@ import { assert } from 'chai'; import { Buffer } from 'common/buffer/Buffer'; import { CircularList } from 'common/CircularList'; -import { MockOptionsService, MockBufferService } from 'common/TestUtils.test'; +import { MockOptionsService, MockBufferService, MockLogService } from 'common/TestUtils.test'; import { BufferLine, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; import { CellData } from 'common/buffer/CellData'; import { ExtendedAttrs } from 'common/buffer/AttributeData'; @@ -23,7 +23,7 @@ describe('Buffer', () => { beforeEach(() => { optionsService = new MockOptionsService({ scrollback: INIT_SCROLLBACK }); bufferService = new MockBufferService(INIT_COLS, INIT_ROWS); - buffer = new Buffer(true, optionsService, bufferService); + buffer = new Buffer(true, optionsService, bufferService, new MockLogService()); }); describe('constructor', () => { @@ -151,7 +151,7 @@ describe('Buffer', () => { describe('no scrollback', () => { it('should trim from the top of the buffer when the cursor reaches the bottom', () => { - buffer = new Buffer(true, new MockOptionsService({ scrollback: 0 }), bufferService); + buffer = new Buffer(true, new MockOptionsService({ scrollback: 0 }), bufferService, new MockLogService()); assert.equal(buffer.lines.maxLength, INIT_ROWS); buffer.y = INIT_ROWS - 1; buffer.fillViewportRows(); @@ -1054,7 +1054,7 @@ describe('Buffer', () => { describe('buffer marked to have no scrollback', () => { it('should always have a scrollback of 0', () => { // Test size on initialization - buffer = new Buffer(false, new MockOptionsService({ scrollback: 1000 }), bufferService); + buffer = new Buffer(false, new MockOptionsService({ scrollback: 1000 }), bufferService, new MockLogService()); buffer.fillViewportRows(); assert.equal(buffer.lines.maxLength, INIT_ROWS); // Test size on buffer increase @@ -1068,7 +1068,7 @@ describe('Buffer', () => { describe('addMarker', () => { it('should adjust a marker line when the buffer is trimmed', () => { - buffer = new Buffer(true, new MockOptionsService({ scrollback: 0 }), bufferService); + buffer = new Buffer(true, new MockOptionsService({ scrollback: 0 }), bufferService, new MockLogService()); buffer.fillViewportRows(); const marker = buffer.addMarker(buffer.lines.length - 1); assert.equal(marker.line, buffer.lines.length - 1); @@ -1076,7 +1076,7 @@ describe('Buffer', () => { assert.equal(marker.line, buffer.lines.length - 2); }); it('should dispose of a marker if it is trimmed off the buffer', () => { - buffer = new Buffer(true, new MockOptionsService({ scrollback: 0 }), bufferService); + buffer = new Buffer(true, new MockOptionsService({ scrollback: 0 }), bufferService, new MockLogService()); buffer.fillViewportRows(); assert.equal(buffer.markers.length, 0); const marker = buffer.addMarker(0); @@ -1088,7 +1088,7 @@ describe('Buffer', () => { }); it('should call onDispose', () => { const eventStack: string[] = []; - buffer = new Buffer(true, new MockOptionsService({ scrollback: 0 }), bufferService); + buffer = new Buffer(true, new MockOptionsService({ scrollback: 0 }), bufferService, new MockLogService()); buffer.fillViewportRows(); assert.equal(buffer.markers.length, 0); const marker = buffer.addMarker(0); diff --git a/src/common/buffer/Buffer.ts b/src/common/buffer/Buffer.ts index b738ffef..8efefd60 100644 --- a/src/common/buffer/Buffer.ts +++ b/src/common/buffer/Buffer.ts @@ -14,7 +14,7 @@ import { NULL_CELL_CHAR, NULL_CELL_CODE, NULL_CELL_WIDTH, WHITESPACE_CELL_CHAR, import { Marker } from 'common/buffer/Marker'; import { IBuffer } from 'common/buffer/Types'; import { DEFAULT_CHARSET } from 'common/data/Charsets'; -import { IBufferService, IOptionsService } from 'common/services/Services'; +import { IBufferService, ILogService, IOptionsService } from 'common/services/Services'; export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1 @@ -48,11 +48,14 @@ export class Buffer implements IBuffer { private _cols: number; private _rows: number; private _isClearing: boolean = false; + private _memoryCleanupQueue: InstanceType; + private _memoryCleanupPosition = 0; constructor( private _hasScrollback: boolean, private _optionsService: IOptionsService, - private _bufferService: IBufferService + private _bufferService: IBufferService, + private readonly _logService: ILogService ) { this._cols = this._bufferService.cols; this._rows = this._bufferService.rows; @@ -60,6 +63,7 @@ export class Buffer implements IBuffer { this.scrollTop = 0; this.scrollBottom = this._rows - 1; this.setupTabStops(); + this._memoryCleanupQueue = new IdleTaskQueue(this._logService); } public getNullCell(attr?: IAttributeData): ICellData { @@ -277,9 +281,6 @@ export class Buffer implements IBuffer { } } - private _memoryCleanupQueue = new IdleTaskQueue(); - private _memoryCleanupPosition = 0; - private _batchedMemoryCleanup(): boolean { let normalRun = true; if (this._memoryCleanupPosition >= this.lines.length) { diff --git a/src/common/buffer/BufferSet.test.ts b/src/common/buffer/BufferSet.test.ts index 944b8c15..96737fee 100644 --- a/src/common/buffer/BufferSet.test.ts +++ b/src/common/buffer/BufferSet.test.ts @@ -6,7 +6,7 @@ import { assert } from 'chai'; import { BufferSet } from 'common/buffer/BufferSet'; import { Buffer } from 'common/buffer/Buffer'; -import { MockOptionsService, MockBufferService } from 'common/TestUtils.test'; +import { MockOptionsService, MockBufferService, MockLogService } from 'common/TestUtils.test'; describe('BufferSet', () => { let bufferSet: BufferSet; @@ -14,7 +14,8 @@ describe('BufferSet', () => { beforeEach(() => { bufferSet = new BufferSet( new MockOptionsService({ scrollback: 1000 }), - new MockBufferService(80, 24) + new MockBufferService(80, 24), + new MockLogService() ); }); diff --git a/src/common/buffer/BufferSet.ts b/src/common/buffer/BufferSet.ts index d83d3925..772a7644 100644 --- a/src/common/buffer/BufferSet.ts +++ b/src/common/buffer/BufferSet.ts @@ -7,7 +7,7 @@ import { Disposable } from 'common/Lifecycle'; import { IAttributeData } from 'common/Types'; import { Buffer } from 'common/buffer/Buffer'; import { IBuffer, IBufferSet } from 'common/buffer/Types'; -import { IBufferService, IOptionsService } from 'common/services/Services'; +import { IBufferService, ILogService, IOptionsService } from 'common/services/Services'; import { Emitter } from 'common/Event'; /** @@ -27,7 +27,8 @@ export class BufferSet extends Disposable implements IBufferSet { */ constructor( private readonly _optionsService: IOptionsService, - private readonly _bufferService: IBufferService + private readonly _bufferService: IBufferService, + private readonly _logService: ILogService ) { super(); this.reset(); @@ -36,12 +37,12 @@ export class BufferSet extends Disposable implements IBufferSet { } public reset(): void { - this._normal = new Buffer(true, this._optionsService, this._bufferService); + this._normal = new Buffer(true, this._optionsService, this._bufferService, this._logService); this._normal.fillViewportRows(); // The alt buffer should never have scrollback. // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer - this._alt = new Buffer(false, this._optionsService, this._bufferService); + this._alt = new Buffer(false, this._optionsService, this._bufferService, this._logService); this._activeBuffer = this._normal; this._onBufferActivate.fire({ activeBuffer: this._normal, diff --git a/src/common/services/BufferService.ts b/src/common/services/BufferService.ts index 2e6227fe..6a7ce2b3 100644 --- a/src/common/services/BufferService.ts +++ b/src/common/services/BufferService.ts @@ -7,7 +7,7 @@ import { Disposable } from 'common/Lifecycle'; import { IAttributeData, IBufferLine } from 'common/Types'; import { BufferSet } from 'common/buffer/BufferSet'; import { IBuffer, IBufferSet } from 'common/buffer/Types'; -import { IBufferService, IOptionsService, type IBufferResizeEvent } from 'common/services/Services'; +import { IBufferService, ILogService, IOptionsService, type IBufferResizeEvent } from 'common/services/Services'; import { Emitter } from 'common/Event'; export const MINIMUM_COLS = 2; // Less than 2 can mess with wide chars @@ -32,11 +32,14 @@ export class BufferService extends Disposable implements IBufferService { /** An IBufferline to clone/copy from for new blank lines */ private _cachedBlankLine: IBufferLine | undefined; - constructor(@IOptionsService optionsService: IOptionsService) { + constructor( + @IOptionsService optionsService: IOptionsService, + @ILogService logService: ILogService + ) { super(); this.cols = Math.max(optionsService.rawOptions.cols || 0, MINIMUM_COLS); this.rows = Math.max(optionsService.rawOptions.rows || 0, MINIMUM_ROWS); - this.buffers = this._register(new BufferSet(optionsService, this)); + this.buffers = this._register(new BufferSet(optionsService, this, logService)); this._register(this.buffers.onBufferActivate(e => { this._onScroll.fire(e.activeBuffer.ydisp); })); diff --git a/src/common/services/DecorationService.test.ts b/src/common/services/DecorationService.test.ts index 365be087..95c7c0e2 100644 --- a/src/common/services/DecorationService.test.ts +++ b/src/common/services/DecorationService.test.ts @@ -8,6 +8,7 @@ import { DecorationService } from './DecorationService'; import { IMarker } from 'common/Types'; import { Disposable } from 'common/Lifecycle'; import { Emitter } from 'common/Event'; +import { MockLogService } from 'common/TestUtils.test'; function createFakeMarker(line: number): IMarker { return Object.freeze(new class extends Disposable { @@ -22,7 +23,7 @@ const fakeMarker: IMarker = createFakeMarker(1); describe('DecorationService', () => { it('should set isDisposed to true after dispose', () => { - const service = new DecorationService(); + const service = new DecorationService(new MockLogService()); const decoration = service.registerDecoration({ marker: fakeMarker }); @@ -34,7 +35,7 @@ describe('DecorationService', () => { describe('forEachDecorationAtCell', () => { it('should find decoration at its marker line', () => { - const service = new DecorationService(); + const service = new DecorationService(new MockLogService()); const decoration = service.registerDecoration({ marker: createFakeMarker(5), width: 10 @@ -47,7 +48,7 @@ describe('DecorationService', () => { }); it('should find decoration with height > 1 on subsequent lines', () => { - const service = new DecorationService(); + const service = new DecorationService(new MockLogService()); const decoration = service.registerDecoration({ marker: createFakeMarker(5), width: 10, @@ -73,7 +74,7 @@ describe('DecorationService', () => { }); it('should not find decoration outside its x range', () => { - const service = new DecorationService(); + const service = new DecorationService(new MockLogService()); const decoration = service.registerDecoration({ marker: createFakeMarker(5), x: 5, @@ -102,7 +103,7 @@ describe('DecorationService', () => { describe('getDecorationsAtCell', () => { it('should find decoration with height > 1 on subsequent lines', () => { - const service = new DecorationService(); + const service = new DecorationService(new MockLogService()); const decoration = service.registerDecoration({ marker: createFakeMarker(5), width: 10, diff --git a/src/common/services/DecorationService.ts b/src/common/services/DecorationService.ts index 92e06089..133e1a98 100644 --- a/src/common/services/DecorationService.ts +++ b/src/common/services/DecorationService.ts @@ -5,7 +5,7 @@ import { css } from 'common/Color'; import { Disposable, DisposableStore, toDisposable } from 'common/Lifecycle'; -import { IDecorationService, IInternalDecoration } from 'common/services/Services'; +import { IDecorationService, IInternalDecoration, ILogService } from 'common/services/Services'; import { SortedList } from 'common/SortedList'; import { IColor } from 'common/Types'; import { IDecoration, IDecorationOptions, IMarker } from '@xterm/xterm'; @@ -25,7 +25,7 @@ export class DecorationService extends Disposable implements IDecorationService * while marker line values do change, they should all change by the same amount so this should * never become out of order. */ - private readonly _decorations: SortedList = new SortedList(e => e?.marker.line); + private readonly _decorations: SortedList; private readonly _onDecorationRegistered = this._register(new Emitter()); public readonly onDecorationRegistered = this._onDecorationRegistered.event; @@ -34,9 +34,11 @@ export class DecorationService extends Disposable implements IDecorationService public get decorations(): IterableIterator { return this._decorations.values(); } - constructor() { + constructor(@ILogService private readonly _logService: ILogService) { super(); + this._decorations = new SortedList(e => e?.marker.line, this._logService); + this._register(toDisposable(() => this.reset())); } diff --git a/src/common/services/OscLinkService.test.ts b/src/common/services/OscLinkService.test.ts index 5000e8e2..cc6c2228 100644 --- a/src/common/services/OscLinkService.test.ts +++ b/src/common/services/OscLinkService.test.ts @@ -9,6 +9,7 @@ import { BufferService } from 'common/services/BufferService'; import { OptionsService } from 'common/services/OptionsService'; import { OscLinkService } from 'common/services/OscLinkService'; import { IBufferService, IOptionsService, IOscLinkService } from 'common/services/Services'; +import { MockLogService } from 'common/TestUtils.test'; describe('OscLinkService', () => { describe('constructor', () => { @@ -17,7 +18,7 @@ describe('OscLinkService', () => { let oscLinkService: IOscLinkService; beforeEach(() => { optionsService = new OptionsService({ rows: 3, cols: 10 }); - bufferService = new BufferService(optionsService); + bufferService = new BufferService(optionsService, new MockLogService()); oscLinkService = new OscLinkService(bufferService); });