Maintain decorations sorted by line
This commit is contained in:
@@ -7,13 +7,19 @@ import { css } from 'common/Color';
|
||||
import { EventEmitter } from 'common/EventEmitter';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { IDecorationService, IInternalDecoration } from 'common/services/Services';
|
||||
import { SortedList } from 'common/SortedList';
|
||||
import { IColor } from 'common/Types';
|
||||
import { IDecorationOptions, IDecoration, IMarker, IEvent } from 'xterm';
|
||||
|
||||
export class DecorationService extends Disposable implements IDecorationService {
|
||||
public serviceBrand: any;
|
||||
|
||||
private readonly _decorations: IInternalDecoration[] = [];
|
||||
/**
|
||||
* A list of all decorations, sorted by the marker's line value. This relies on the fact that
|
||||
* 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<IInternalDecoration> = new SortedList(e => e.marker.line);
|
||||
|
||||
private _onDecorationRegistered = this.register(new EventEmitter<IInternalDecoration>());
|
||||
public get onDecorationRegistered(): IEvent<IInternalDecoration> { return this._onDecorationRegistered.event; }
|
||||
@@ -35,56 +41,47 @@ export class DecorationService extends Disposable implements IDecorationService
|
||||
const markerDispose = decoration.marker.onDispose(() => decoration.dispose());
|
||||
decoration.onDispose(() => {
|
||||
if (decoration) {
|
||||
const index = this._decorations.indexOf(decoration);
|
||||
if (index >= 0) {
|
||||
this._decorations.splice(this._decorations.indexOf(decoration), 1);
|
||||
if (this._decorations.delete(decoration)) {
|
||||
this._onDecorationRemoved.fire(decoration);
|
||||
}
|
||||
markerDispose.dispose();
|
||||
}
|
||||
});
|
||||
this._decorations.push(decoration);
|
||||
this._decorations.insert(decoration);
|
||||
this._onDecorationRegistered.fire(decoration);
|
||||
}
|
||||
return decoration;
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
for (let i = 0; i < this._decorations.length; i++) {
|
||||
this._decorations[0].dispose();
|
||||
for (const d of this._decorations.values()) {
|
||||
d.dispose();
|
||||
}
|
||||
this._decorations.length = 0;
|
||||
this._decorations.clear();
|
||||
}
|
||||
|
||||
public *getDecorationsAtLine(line: number): IterableIterator<IInternalDecoration> {
|
||||
// TODO: This could be made much faster if _decorations was sorted by line (and col?)
|
||||
for (const d of this.decorations) {
|
||||
if (d.marker.line === line) {
|
||||
yield d;
|
||||
}
|
||||
}
|
||||
return this._decorations.getKeyIterator(line);
|
||||
}
|
||||
|
||||
public *getDecorationsAtCell(x: number, line: number): IterableIterator<IInternalDecoration> {
|
||||
let xmin = 0;
|
||||
let xmax = 0;
|
||||
for (const d of this.decorations) {
|
||||
if (d.marker.line === line) {
|
||||
xmin = d.options.x ?? 0;
|
||||
xmax = xmin + (d.options.width ?? 1);
|
||||
if (x >= xmin && x < xmax) {
|
||||
yield d;
|
||||
}
|
||||
for (const d of this._decorations.getKeyIterator(line)) {
|
||||
console.log('d', d);
|
||||
xmin = d.options.x ?? 0;
|
||||
xmax = xmin + (d.options.width ?? 1);
|
||||
if (x >= xmin && x < xmax) {
|
||||
yield d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
for (const decoration of this._decorations) {
|
||||
this._onDecorationRemoved.fire(decoration);
|
||||
decoration.dispose();
|
||||
for (const d of this._decorations.values()) {
|
||||
this._onDecorationRemoved.fire(d);
|
||||
}
|
||||
this._decorations.length = 0;
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user