mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Remove iterators from IDecorationService
They're too low performance for typical use cases Fixes #4079
This commit is contained in:
@@ -404,12 +404,11 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
||||
|
||||
// Don't try cache the glyph if it uses any decoration foreground/background override.
|
||||
let hasOverrides = false;
|
||||
for (const d of this._decorationService.getDecorationsAtCell(x, y)) {
|
||||
this._decorationService.forEachDecorationAtCell(x, y, undefined, d => {
|
||||
if (d.backgroundColorRGB || d.foregroundColorRGB) {
|
||||
hasOverrides = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const atlasDidDraw = hasOverrides ? false : this._charAtlas?.draw(this._ctx, this._currentGlyphIdentifier, x * this._scaledCellWidth + this._scaledCharLeft, y * this._scaledCellHeight + this._scaledCharTop);
|
||||
|
||||
@@ -519,9 +518,9 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
||||
let bgOverride: number | undefined;
|
||||
let fgOverride: number | undefined;
|
||||
let isTop = false;
|
||||
for (const d of this._decorationService.getDecorationsAtCell(x, y)) {
|
||||
this._decorationService.forEachDecorationAtCell(x, y, undefined, d => {
|
||||
if (d.options.layer !== 'top' && isTop) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
if (d.backgroundColorRGB) {
|
||||
bgOverride = d.backgroundColorRGB.rgba;
|
||||
@@ -530,7 +529,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
||||
fgOverride = d.foregroundColorRGB.rgba;
|
||||
}
|
||||
isTop = d.options.layer === 'top';
|
||||
}
|
||||
});
|
||||
|
||||
// Apply selection foreground if applicable
|
||||
if (!isTop) {
|
||||
|
||||
@@ -187,15 +187,15 @@ export class TextRenderLayer extends BaseRenderLayer {
|
||||
// Get any decoration foreground/background overrides, this must be fetched before the early
|
||||
// exist but applied after inverse
|
||||
let isTop = false;
|
||||
for (const d of this._decorationService.getDecorationsAtCell(x, this._bufferService.buffer.ydisp + y)) {
|
||||
this._decorationService.forEachDecorationAtCell(x, this._bufferService.buffer.ydisp + y, undefined, d => {
|
||||
if (d.options.layer !== 'top' && isTop) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
if (d.backgroundColorRGB) {
|
||||
nextFillStyle = d.backgroundColorRGB.css;
|
||||
}
|
||||
isTop = d.options.layer === 'top';
|
||||
}
|
||||
});
|
||||
|
||||
if (prevFillStyle === null) {
|
||||
// This is either the first iteration, or the default background was set. Either way, we
|
||||
|
||||
@@ -204,9 +204,9 @@ export class DomRendererRowFactory {
|
||||
let bgOverride: IColor | undefined;
|
||||
let fgOverride: IColor | undefined;
|
||||
let isTop = false;
|
||||
for (const d of this._decorationService.getDecorationsAtCell(x, row)) {
|
||||
this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {
|
||||
if (d.options.layer !== 'top' && isTop) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
if (d.backgroundColorRGB) {
|
||||
bgColorMode = Attributes.CM_RGB;
|
||||
@@ -219,7 +219,7 @@ export class DomRendererRowFactory {
|
||||
fgOverride = d.foregroundColorRGB;
|
||||
}
|
||||
isTop = d.options.layer === 'top';
|
||||
}
|
||||
});
|
||||
|
||||
// Apply selection foreground if applicable
|
||||
const isInSelection = this._isCellInSelection(x, row);
|
||||
|
||||
@@ -161,8 +161,6 @@ export class MockDecorationService implements IDecorationService {
|
||||
public onDecorationRemoved = new EventEmitter<IInternalDecoration>().event;
|
||||
public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined { return undefined; }
|
||||
public reset(): void { }
|
||||
public *getDecorationsAtLine(line: number): IterableIterator<IInternalDecoration> { }
|
||||
public *getDecorationsAtCell(x: number, line: number): IterableIterator<IInternalDecoration> { }
|
||||
public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void { }
|
||||
public dispose(): void { }
|
||||
}
|
||||
|
||||
@@ -62,10 +62,6 @@ export class DecorationService extends Disposable implements IDecorationService
|
||||
this._decorations.clear();
|
||||
}
|
||||
|
||||
public *getDecorationsAtLine(line: number): IterableIterator<IInternalDecoration> {
|
||||
return this._decorations.getKeyIterator(line);
|
||||
}
|
||||
|
||||
public *getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator<IInternalDecoration> {
|
||||
let xmin = 0;
|
||||
let xmax = 0;
|
||||
|
||||
@@ -304,13 +304,9 @@ export interface IDecorationService extends IDisposable {
|
||||
readonly onDecorationRemoved: IEvent<IInternalDecoration>;
|
||||
registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;
|
||||
reset(): void;
|
||||
/** Iterates over the decorations at a line (in no particular order). */
|
||||
getDecorationsAtLine(line: number): IterableIterator<IInternalDecoration>;
|
||||
/** Iterates over the decorations at a cell (in no particular order). */
|
||||
getDecorationsAtCell(x: number, line: number, layer?: 'bottom' | 'top'): IterableIterator<IInternalDecoration>;
|
||||
/**
|
||||
* Trigger a callback over the decoration at a cell (in no particular order). This is a high
|
||||
* performance, but less ergonomic, version of {@link getDecorationsAtCell}.
|
||||
* Trigger a callback over the decoration at a cell (in no particular order). This uses a callback
|
||||
* instead of an iterator as it's typically used in hot code paths.
|
||||
*/
|
||||
forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user