diff --git a/src/vs/workbench/api/node/extHostTreeViews.ts b/src/vs/workbench/api/node/extHostTreeViews.ts index 98d460a561d31..cd48700d84f0b 100644 --- a/src/vs/workbench/api/node/extHostTreeViews.ts +++ b/src/vs/workbench/api/node/extHostTreeViews.ts @@ -7,13 +7,15 @@ import { localize } from 'vs/nls'; import * as vscode from 'vscode'; import URI from 'vs/base/common/uri'; +import { distinct } from 'vs/base/common/arrays'; +import { debounceEvent } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { Disposable } from 'vs/base/common/lifecycle'; import { ExtHostTreeViewsShape, MainThreadTreeViewsShape } from './extHost.protocol'; import { ITreeItem, TreeViewItemHandleArg } from 'vs/workbench/parts/views/common/views'; import { TreeItemCollapsibleState } from './extHostTypes'; import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands'; -import { asWinJsPromise, Delayer } from 'vs/base/common/async'; +import { asWinJsPromise } from 'vs/base/common/async'; type TreeItemHandle = number; @@ -77,14 +79,11 @@ class ExtHostTreeView extends Disposable { private itemHandlesMap: Map = new Map(); private extChildrenElementsMap: Map = new Map(); - private refreshDelayer: Delayer = new Delayer(200); - private itemsToRefresh: TreeItemHandle[] = []; - constructor(private viewId: string, private dataProvider: vscode.TreeDataProvider, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter) { super(); this.proxy.$registerView(viewId); if (dataProvider.onDidChangeTreeData) { - this._register(dataProvider.onDidChangeTreeData(element => this._refresh(element))); + this._register(debounceEvent(dataProvider.onDidChangeTreeData, (last, current) => last ? [...last, current] : [current], 200)(elements => this._refresh(elements))); } } @@ -113,27 +112,19 @@ class ExtHostTreeView extends Disposable { return this.extElementsMap.get(treeItemHandle); } - private _refresh(element: T): void { - if (this.itemsToRefresh && element) { - const itemHandle = this.itemHandlesMap.get(element); - if (itemHandle) { - if (this.itemsToRefresh.indexOf(itemHandle) === -1) { - this.itemsToRefresh.push(itemHandle); - this.refreshDelayer.trigger(() => this._doRefresh()); - } - } + private _refresh(elements: T[]): void { + const hasRoot = elements.some(element => !element); + if (hasRoot) { + this.proxy.$refresh(this.viewId, []); } else { - // Indicates that root has to be refreshed - this.itemsToRefresh = null; - this.refreshDelayer.trigger(() => this._doRefresh()); + const itemHandles = distinct(elements.map(element => this.itemHandlesMap.get(element)) + .filter(itemHandle => !!itemHandle)); + if (itemHandles.length) { + this.proxy.$refresh(this.viewId, itemHandles); + } } } - private _doRefresh(): void { - this.proxy.$refresh(this.viewId, this.itemsToRefresh || []); - this.itemsToRefresh = []; - } - private processAndMapElements(elements: T[]): TPromise { if (elements && elements.length) { return TPromise.join( diff --git a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts index 7daf59bb341d8..fdcf96360e9cb 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts @@ -77,6 +77,30 @@ suite('ExtHostConfiguration', function () { onDidChangeTreeData.fire('a'); }); + test('refresh calls are throttled on unknown elements', function (done) { + target.onRefresh.event(actuals => { + assert.deepEqual([1, 2], actuals); + done(); + }); + + onDidChangeTreeData.fire('a'); + onDidChangeTreeData.fire('b'); + onDidChangeTreeData.fire('g'); + onDidChangeTreeData.fire('a'); + }); + + test('refresh calls are throttled on unknown elements and root', function (done) { + target.onRefresh.event(actuals => { + assert.equal(0, actuals.length); + done(); + }); + + onDidChangeTreeData.fire('a'); + onDidChangeTreeData.fire('b'); + onDidChangeTreeData.fire('g'); + onDidChangeTreeData.fire(''); + }); + test('refresh calls are throttled on elements and root', function (done) { target.onRefresh.event(actuals => { assert.equal(0, actuals.length);