提交 4e5de4b7 编写于 作者: J Johannes Rieken

debounce and queue decoration request, fixes #40210

上级 6cb8c4c7
......@@ -7,21 +7,69 @@
import URI, { UriComponents } from 'vs/base/common/uri';
import { Emitter } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ExtHostContext, MainContext, IExtHostContext, MainThreadDecorationsShape, ExtHostDecorationsShape } from '../node/extHost.protocol';
import { ExtHostContext, MainContext, IExtHostContext, MainThreadDecorationsShape, ExtHostDecorationsShape, DecorationData, DecorationRequest } from '../node/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
import { IDecorationsService, IDecorationData } from 'vs/workbench/services/decorations/browser/decorations';
class DecorationRequestsQueue {
private _idPool = 0;
private _requests: DecorationRequest[] = [];
private _resolver: { [id: number]: Function } = Object.create(null);
private _timer: number;
constructor(
private _proxy: ExtHostDecorationsShape
) {
//
}
enqueue(handle: number, uri: URI): Thenable<DecorationData> {
return new Promise((resolve, reject) => {
const id = ++this._idPool;
this._requests.push({ id, handle, uri });
this._resolver[id] = resolve;
this._processQueue();
});
}
private _processQueue(): void {
if (typeof this._timer === 'number') {
// already queued
return;
}
this._timer = setTimeout(() => {
// make request
const requests = this._requests;
const resolver = this._resolver;
this._proxy.$provideDecorations(requests).then(data => {
for (const id in resolver) {
resolver[id](data[id]);
}
});
// reset
this._requests = [];
this._resolver = [];
this._timer = void 0;
}, 0);
}
}
@extHostNamedCustomer(MainContext.MainThreadDecorations)
export class MainThreadDecorations implements MainThreadDecorationsShape {
private readonly _provider = new Map<number, [Emitter<URI[]>, IDisposable]>();
private readonly _proxy: ExtHostDecorationsShape;
private readonly _requestQueue: DecorationRequestsQueue;
constructor(
context: IExtHostContext,
@IDecorationsService private readonly _decorationsService: IDecorationsService
) {
this._proxy = context.getProxy(ExtHostContext.ExtHostDecorations);
this._requestQueue = new DecorationRequestsQueue(this._proxy);
}
dispose() {
......@@ -30,12 +78,12 @@ export class MainThreadDecorations implements MainThreadDecorationsShape {
}
$registerDecorationProvider(handle: number, label: string): void {
let emitter = new Emitter<URI[]>();
let registration = this._decorationsService.registerDecorationsProvider({
const emitter = new Emitter<URI[]>();
const registration = this._decorationsService.registerDecorationsProvider({
label,
onDidChange: emitter.event,
provideDecorations: (uri) => {
return this._proxy.$provideDecorations(handle, uri).then(data => {
return this._requestQueue.enqueue(handle, uri).then(data => {
if (!data) {
return undefined;
}
......
......@@ -719,10 +719,17 @@ export interface ExtHostDebugServiceShape {
}
export interface DecorationRequest {
readonly id: number;
readonly handle: number;
readonly uri: UriComponents;
}
export type DecorationData = [number, boolean, string, string, ThemeColor, string];
export type DecorationReply = { [id: number]: DecorationData };
export interface ExtHostDecorationsShape {
$provideDecorations(handle: number, uri: UriComponents): TPromise<DecorationData>;
$provideDecorations(requests: DecorationRequest[]): TPromise<DecorationReply>;
}
export interface ExtHostWindowShape {
......
......@@ -5,8 +5,8 @@
'use strict';
import * as vscode from 'vscode';
import URI, { UriComponents } from 'vs/base/common/uri';
import { MainContext, IMainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData } from 'vs/workbench/api/node/extHost.protocol';
import URI from 'vs/base/common/uri';
import { MainContext, IMainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/node/extHost.protocol';
import { TPromise } from 'vs/base/common/winjs.base';
import { Disposable } from 'vs/workbench/api/node/extHostTypes';
import { asWinJsPromise } from 'vs/base/common/async';
......@@ -38,10 +38,19 @@ export class ExtHostDecorations implements ExtHostDecorationsShape {
});
}
$provideDecorations(handle: number, data: UriComponents): TPromise<DecorationData> {
$provideDecorations(requests: DecorationRequest[]): TPromise<DecorationReply> {
const result: DecorationReply = Object.create(null);
return TPromise.join(requests.map(request => {
const { handle, uri, id } = request;
const provider = this._provider.get(handle);
return asWinJsPromise(token => provider.provideDecoration(URI.revive(data), token)).then(data => {
return data && <DecorationData>[data.priority, data.bubble, data.title, data.abbreviation, data.color, data.source];
return asWinJsPromise(token => provider.provideDecoration(URI.revive(uri), token)).then(data => {
result[id] = data && <DecorationData>[data.priority, data.bubble, data.title, data.abbreviation, data.color, data.source];
}, err => {
console.error(err);
});
})).then(() => {
return result;
});
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册