diff --git a/src/console/index.ts b/src/console/index.ts index c3ef108..915cf4d 100644 --- a/src/console/index.ts +++ b/src/console/index.ts @@ -3,7 +3,6 @@ import { randomInt } from '../utility'; import * as tools from '../tools'; import { ConsoleServer } from './server'; import { registerMethod } from './client'; -import * as vscode from 'vscode'; function setPort(port: number) { if (!env.scriptUri) { diff --git a/src/console/treeView.ts b/src/console/treeView.ts index 6564878..e8a1d26 100644 --- a/src/console/treeView.ts +++ b/src/console/treeView.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -import { Client, registerMethod } from './client'; +import { Client } from './client'; class TreeItem extends vscode.TreeItem { childs?: number[]; @@ -11,23 +11,28 @@ class TreeItem extends vscode.TreeItem { } class TreeDataProvider implements vscode.TreeDataProvider { - constructor(private treeView: TreeView, private root: number) { + constructor(private manager: TreeViewManager) { } - private onDidChange = new vscode.EventEmitter(); + readonly onDidChange = new vscode.EventEmitter(); onDidChangeTreeData = this.onDidChange.event; itemMap = new Map(); async getTreeItem(id: number): Promise { - let data = await this.treeView.manager.requestGetTreeNode(id); - let item = this.getItem(id) ?? this.createItem(id, data); - return item; + let data = await this.manager.requestGetTreeNode(id); + if (this.getItem(id)) { + return this.getItem(id)!; + } + if (!data) { + return new TreeItem(id, 'Loading...'); + } + return this.createItem(id, data); } async getChildren(id: number | undefined): Promise { if (id === undefined) { - return [this.root]; + return this.manager.treeViews.map(view => view.root); } let item = this.itemMap.get(id); if (!item) { @@ -36,20 +41,22 @@ class TreeDataProvider implements vscode.TreeDataProvider { if (item.childs) { return item.childs; } - let childs = await this.treeView.manager.requestGetChildTreeNodes(id); + let childs = await this.manager.requestGetChildTreeNodes(id); item.childs = childs; + if (!childs) { + return []; + } return childs; } - private getItem(id: number) { + getItem(id: number) { return this.itemMap.get(id); } - private createItem(id: number, data: getTreeNodeResponse) { + createItem(id: number, data: getTreeNodeResponse) { this.removeItem(id); let item = new TreeItem(id, data.name); this.itemMap.set(id, item); - this.treeView.addOwnedID(id); if (typeof data.desc === 'string') { item.description = data.desc; } @@ -60,7 +67,7 @@ class TreeDataProvider implements vscode.TreeDataProvider { item.iconPath = new vscode.ThemeIcon(data.icon); } if (data.hasChilds) { - if (id === this.root) { + if (this.manager.treeViews.find(view => view.root === id)) { item.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; } else { item.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; @@ -68,13 +75,13 @@ class TreeDataProvider implements vscode.TreeDataProvider { } return item; } - private removeItem(id: number) { + + removeItem(id: number) { let item = this.itemMap.get(id); if (!item) { return; } this.itemMap.delete(id); - this.treeView.removeOwnedID(id); if (item.childs) { for (const child of item.childs) { this.removeItem(child); @@ -82,28 +89,41 @@ class TreeDataProvider implements vscode.TreeDataProvider { } } - refresh(id: number) { - this.removeItem(id); + refresh(id: number | undefined) { + if (id) { + this.removeItem(id); + } this.onDidChange.fire(id); } } -export class TreeView extends vscode.Disposable { - private view: vscode.TreeView; - readonly ownedIDs = new Set(); - private treeDataProvider: TreeDataProvider; +export class TreeView { constructor( readonly manager: TreeViewManager, readonly id: number, readonly name: string, - private root: number, + readonly root: number, ) { + vscode.commands.executeCommand('y3-helper.client.focus'); + } +} + +interface getTreeNodeResponse { + name: string; + desc?: string; + tip?: string; + icon?: string; + hasChilds?: boolean; +} + +export class TreeViewManager extends vscode.Disposable { + constructor(private client: Client) { super(() => { this.view.dispose(); }); - this.treeDataProvider = new TreeDataProvider(this, root); + this.treeDataProvider = new TreeDataProvider(this); this.view = vscode.window.createTreeView('y3-helper.client', { treeDataProvider: this.treeDataProvider, @@ -112,88 +132,51 @@ export class TreeView extends vscode.Disposable { this.view.onDidExpandElement(e => { let item = this.treeDataProvider.itemMap.get(e.element); if (item && item.childs) { - this.manager.notifyChangeTreeNodeVisible(item.childs, true); + this.notifyChangeTreeNodeVisible(item.childs, true); } }); this.view.onDidCollapseElement(e => { let item = this.treeDataProvider.itemMap.get(e.element); if (item && item.childs) { - this.manager.notifyChangeTreeNodeVisible(item.childs, false); + this.notifyChangeTreeNodeVisible(item.childs, false); } }); - vscode.commands.executeCommand('y3-helper.client.focus'); - } - - refresh(id: number) { - this.treeDataProvider.refresh(id); - } - - addOwnedID(id: number) { - this.ownedIDs.add(id); - } - - removeOwnedID(id: number) { - this.ownedIDs.delete(id); - } -} - -interface getTreeNodeResponse { - name: string; - desc?: string; - tip?: string; - icon?: string; - hasChilds?: boolean; -} - -export class TreeViewManager extends vscode.Disposable { - constructor(private client: Client) { - super(() => { - this.treeViews.forEach(view => view.dispose()); - }); } - private treeViews = new Map(); + private view: vscode.TreeView; + private treeDataProvider: TreeDataProvider; - findTreeViewByNodeID(id: number): TreeView | undefined { - for (const view of this.treeViews.values()) { - if (view.ownedIDs.has(id)) { - return view; - } - } - return undefined; - } + readonly treeViews = new Array(); // 从客户端中获取节点信息 - async requestGetTreeNode(id: number): Promise { + async requestGetTreeNode(id: number): Promise { return await this.client.request('getTreeNode', { id }); } // 从客户端中获取子节点 - async requestGetChildTreeNodes(id: number): Promise { + async requestGetChildTreeNodes(id: number): Promise { return await this.client.request('getChildTreeNodes', { id }); } async createTreeView(id: number, name: string, root: number) { let treeView = new TreeView(this, id, name, root); - this.treeViews.set(id, treeView); + this.treeViews.push(treeView); + this.treeDataProvider.refresh(undefined); return treeView; } async removeTreeView(id: number) { - let treeView = this.treeViews.get(id); + let treeView = this.treeViews.find(view => view.id === id); if (!treeView) { return; } - this.treeViews.delete(id); - treeView.dispose(); + this.treeViews.splice(this.treeViews.indexOf(treeView), 1); + this.treeDataProvider.removeItem(treeView.root); + this.treeDataProvider.refresh(undefined); } refreshTreeNode(id: number) { - let treeView = this.findTreeViewByNodeID(id); - if (!treeView) { - return; - } - treeView.refresh(id); + this.treeDataProvider.refresh(id); } notifyChangeTreeNodeVisible(ids: number[], visible: boolean) {