deco - some debt, add logging

This commit is contained in:
Johannes Rieken
2019-10-04 12:42:04 +02:00
parent c617db19b0
commit e257fad18a
2 changed files with 24 additions and 29 deletions

View File

@@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { IDecorationsService, IDecoration, IResourceDecorationChangeEvent, IDecorationsProvider, IDecorationData } from './decorations';
import { TernarySearchTree } from 'vs/base/common/map';
import { Disposable, IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { isThenable } from 'vs/base/common/async';
import { LinkedList } from 'vs/base/common/linkedList';
import { createStyleSheet, createCSSRule, removeCSSRulesContainingSelector } from 'vs/base/browser/dom';
@@ -19,6 +19,7 @@ import { localize } from 'vs/nls';
import { isPromiseCanceledError } from 'vs/base/common/errors';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
class DecorationRule {
@@ -96,25 +97,21 @@ class DecorationRule {
}
}
class DecorationStyles extends Disposable {
class DecorationStyles {
private readonly _styleElement = createStyleSheet();
private readonly _decorationRules = new Map<string, DecorationRule>();
private readonly _dispoables = new DisposableStore();
constructor(
private _themeService: IThemeService,
) {
super();
this._register(this._themeService.onThemeChange(this._onThemeChange, this));
this._themeService.onThemeChange(this._onThemeChange, this, this._dispoables);
}
dispose(): void {
super.dispose();
const parent = this._styleElement.parentElement;
if (parent) {
parent.removeChild(this._styleElement);
}
this._dispoables.dispose();
this._styleElement.remove();
}
asDecoration(data: IDecorationData[], onlyChildren: boolean): IDecoration {
@@ -224,11 +221,11 @@ class DecorationProviderWrapper {
private readonly _dispoable: IDisposable;
constructor(
private readonly _provider: IDecorationsProvider,
readonly provider: IDecorationsProvider,
private readonly _uriEmitter: Emitter<URI | URI[]>,
private readonly _flushEmitter: Emitter<IResourceDecorationChangeEvent>
) {
this._dispoable = this._provider.onDidChange(uris => {
this._dispoable = this.provider.onDidChange(uris => {
if (!uris) {
// flush event -> drop all data, can affect everything
this.data.clear();
@@ -292,7 +289,7 @@ class DecorationProviderWrapper {
}
const source = new CancellationTokenSource();
const dataOrThenable = this._provider.provideDecorations(uri, source.token);
const dataOrThenable = this.provider.provideDecorations(uri, source.token);
if (!isThenable<IDecorationData | Promise<IDecorationData | undefined> | undefined>(dataOrThenable)) {
// sync -> we have a result now
return this._keepItem(uri, dataOrThenable);
@@ -325,7 +322,7 @@ class DecorationProviderWrapper {
}
}
export class FileDecorationsService implements IDecorationsService {
export class DecorationsService implements IDecorationsService {
_serviceBrand: undefined;
@@ -333,7 +330,6 @@ export class FileDecorationsService implements IDecorationsService {
private readonly _onDidChangeDecorationsDelayed = new Emitter<URI | URI[]>();
private readonly _onDidChangeDecorations = new Emitter<IResourceDecorationChangeEvent>();
private readonly _decorationStyles: DecorationStyles;
private readonly _disposables: IDisposable[];
readonly onDidChangeDecorations: Event<IResourceDecorationChangeEvent> = Event.any(
this._onDidChangeDecorations.event,
@@ -345,29 +341,25 @@ export class FileDecorationsService implements IDecorationsService {
);
constructor(
@IThemeService themeService: IThemeService
@IThemeService themeService: IThemeService,
@ILogService private readonly _logService: ILogService,
) {
this._decorationStyles = new DecorationStyles(themeService);
// every so many events we check if there are
// css styles that we don't need anymore
let count = 0;
let reg = this.onDidChangeDecorations(() => {
this.onDidChangeDecorations(() => {
if (++count % 17 === 0) {
this._decorationStyles.cleanUp(this._data.iterator());
}
});
this._disposables = [
reg,
this._decorationStyles
];
}
dispose(): void {
dispose(this._disposables);
dispose(this._onDidChangeDecorations);
dispose(this._onDidChangeDecorationsDelayed);
this._decorationStyles.dispose();
this._onDidChangeDecorations.dispose();
this._onDidChangeDecorationsDelayed.dispose();
}
registerDecorationsProvider(provider: IDecorationsProvider): IDisposable {
@@ -397,10 +389,12 @@ export class FileDecorationsService implements IDecorationsService {
let data: IDecorationData[] = [];
let containsChildren: boolean = false;
for (let iter = this._data.iterator(), next = iter.next(); !next.done; next = iter.next()) {
const { label } = next.value.provider;
next.value.getOrRetrieve(uri, includeChildren, (deco, isChild) => {
if (!isChild || deco.bubble) {
data.push(deco);
containsChildren = isChild || containsChildren;
this._logService.trace('DecorationsService#getDecoration#getOrRetrieve', label, deco, isChild, uri);
}
});
}
@@ -420,4 +414,4 @@ function getColor(theme: ITheme, color: string | undefined) {
return 'inherit';
}
registerSingleton(IDecorationsService, FileDecorationsService);
registerSingleton(IDecorationsService, DecorationsService, true);

View File

@@ -4,22 +4,23 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { FileDecorationsService } from 'vs/workbench/services/decorations/browser/decorationsService';
import { DecorationsService } from 'vs/workbench/services/decorations/browser/decorationsService';
import { IDecorationsProvider, IDecorationData } from 'vs/workbench/services/decorations/browser/decorations';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ConsoleLogService } from 'vs/platform/log/common/log';
suite('DecorationsService', function () {
let service: FileDecorationsService;
let service: DecorationsService;
setup(function () {
if (service) {
service.dispose();
}
service = new FileDecorationsService(new TestThemeService());
service = new DecorationsService(new TestThemeService(), new ConsoleLogService());
});
test('Async provider, async/evented result', function () {