mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-06 14:24:04 -05:00
debounce and queue decoration request, fixes #40210
This commit is contained in:
@@ -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> {
|
||||
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];
|
||||
$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(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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user