Skip to content

Commit

Permalink
[OneExplorer] Targetted refresh on Change/Delete
Browse files Browse the repository at this point in the history
This commit refreshs only the required nodes on change and delete file.

ONE-vscode-DCO-1.0-Signed-off-by: Dayoung Lee <[email protected]>
  • Loading branch information
dayo09 committed Oct 17, 2023
1 parent 9a5d82e commit 06798a6
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 20 deletions.
36 changes: 36 additions & 0 deletions src/OneExplorer/ConfigObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,42 @@ export class ConfigObj {
};
}

static diffBaseModels(
newCfgObj?: ConfigObj,
oldCfgObj?: ConfigObj
): [addedBaseModels: string[], removedBaseModels: string[]] {
const newBaseModels =
newCfgObj?.getBaseModelsExists.map((artifact) => artifact.path) ?? [];
const oldBaseModels =
oldCfgObj?.getBaseModelsExists.map((artifact) => artifact.path) ?? [];

const addedBaseModels =
newBaseModels.filter((path) => !oldBaseModels.includes(path)) ?? [];

const removedBaseModels =
oldBaseModels.filter((path) => !newBaseModels.includes(path)) ?? [];

return [addedBaseModels, removedBaseModels];
}

static diffProducts(
newCfgObj?: ConfigObj,
oldCfgObj?: ConfigObj
): [addedProducts: string[], removedProducts: string[]] {
const newProducts =
newCfgObj?.getProductsExists.map((artifact) => artifact.path) ?? [];
const oldProducts =
oldCfgObj?.getProductsExists.map((artifact) => artifact.path) ?? [];

const addedProducts =
newProducts.filter((path) => !oldProducts.includes(path)) ?? [];

const removedProducts =
oldProducts.filter((path) => !newProducts.includes(path)) ?? [];

return [addedProducts, removedProducts];
}

public updateBaseModelField(
oldpath: string,
newpath: string
Expand Down
121 changes: 101 additions & 20 deletions src/OneExplorer/OneExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { CfgEditorPanel } from "../CfgEditor/CfgEditorPanel";
import { obtainWorkspaceRoots } from "../Utils/Helpers";
import { Logger } from "../Utils/Logger";

import { ConfigObj } from "./ConfigObject";
import { ArtifactAttr } from "./ArtifactLocator";
import { OneStorage } from "./OneStorage";

Expand Down Expand Up @@ -157,6 +158,21 @@ export abstract class Node {
// Return a NodeType as a string value
return NodeType[this.type];
}

/**
* Match possible node types from the given uri
*/
static matchType(uri: vscode.Uri): NodeType {
if (BaseModelNode.extList.some((ext) => uri.fsPath.endsWith(ext))) {
return NodeType.baseModel;
} else if (ConfigNode.extList.some((ext) => uri.fsPath.endsWith(ext))) {
return NodeType.config;
} else if (ProductNode.extList.some((ext) => uri.fsPath.endsWith(ext))) {
return NodeType.product;
}

return NodeType.directory;
}
}

class NodeFactory {
Expand Down Expand Up @@ -516,6 +532,16 @@ export class OneTreeDataProvider implements vscode.TreeDataProvider<Node> {
readonly onDidChangeTreeData: vscode.Event<Node | undefined | void> =
this._onDidChangeTreeData.event;

private _onDidChangeConfig: vscode.EventEmitter<vscode.Uri> =
new vscode.EventEmitter<vscode.Uri>();
readonly onDidChangeConfig: vscode.Event<vscode.Uri> =
this._onDidChangeConfig.event;

private _onDidDeleteProduct: vscode.EventEmitter<vscode.Uri> =
new vscode.EventEmitter<vscode.Uri>();
readonly onDidDeleteProduct: vscode.Event<vscode.Uri> =
this._onDidDeleteProduct.event;

private fileWatcher = vscode.workspace.createFileSystemWatcher(`**/*`);

private _tree: Node[] | undefined;
Expand Down Expand Up @@ -543,30 +569,85 @@ export class OneTreeDataProvider implements vscode.TreeDataProvider<Node> {
provider.refresh();
}),
provider.fileWatcher.onDidChange((uri: vscode.Uri) => {
if (
[
...BaseModelNode.extList,
...ConfigNode.extList,
...ProductNode.extList,
].includes(path.parse(uri.path).ext)
) {
Logger.info(
"OneExploer",
`Refresh explorer view on a file change in '${uri.path}'`
);
// TODO Handle by each node types
provider.refresh();
switch (Node.matchType(uri)) {
case NodeType.config:
provider._onDidChangeConfig.fire(uri);
break;
case NodeType.baseModel:
case NodeType.product:
default:
// Do nothing
break;
}
}),
provider.onDidChangeConfig((uri: vscode.Uri) => {
let nodesChanged: Node[] = [];

const oldCfgObj = OneStorage.getCfgObj(uri.fsPath);
const newCfgObj = ConfigObj.createConfigObj(uri)!;

const [adopters, droppers] = ConfigObj.diffBaseModels(
newCfgObj,
oldCfgObj
);

// Create new config node
adopters
.map((adopter) => OneStorage.getBaseModelNode(adopter))
.forEach((adopterNode) => {
OneStorage.insert(
NodeFactory.create(NodeType.config, uri.fsPath, adopterNode)
);
adopterNode.resetChildren();
adopterNode.getChildren();
nodesChanged.push(adopterNode);
});

// Remove old config node
OneStorage.getNodes(uri.fsPath).forEach((node) => {
if (droppers.some((dropper) => dropper === node?.parent?.path)) {
OneStorage.delete(node, true);
}
});

droppers
.map((dropper) => OneStorage.getBaseModelNode(dropper))
.forEach((dropperNode) => {
dropperNode.resetChildren();
dropperNode.getChildren();
nodesChanged.push(dropperNode);
});

nodesChanged.forEach((node) => {
provider._onDidChangeTreeData.fire(node);
});
}),
provider.fileWatcher.onDidDelete((uri: vscode.Uri) => {
const nodes = OneStorage.getNodes(uri.fsPath);
if (nodes.length === 0) {
return;
switch (Node.matchType(uri)) {
case NodeType.product:
provider._onDidDeleteProduct.fire(uri);
break;
case NodeType.directory:
case NodeType.config:
case NodeType.baseModel:
OneStorage.getNodes(uri.fsPath).forEach((node) => {
OneStorage.delete(node, true);
provider._onDidChangeTreeData.fire(node.parent);
});
break;
default:
// Do nothing
break;
}

nodes.forEach((node) => {
OneStorage.delete(node, true);
provider.refresh(node.parent);
}),
provider.onDidDeleteProduct((uri: vscode.Uri) => {
OneStorage.getNodes(uri.fsPath).forEach((node) => {
OneStorage.delete(node);

const dropper = node.parent;
dropper!.resetChildren();
dropper!.getChildren();
provider._onDidChangeTreeData.fire(dropper);
});
}),
vscode.workspace.onDidChangeWorkspaceFolders(() => {
Expand Down
7 changes: 7 additions & 0 deletions src/OneExplorer/OneStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,13 @@ export class OneStorage {
return OneStorage.get()._nodeMap.get(fsPath);
}

public static getBaseModelNode(fsPath: string): Node {
const nodes = OneStorage.get()._nodeMap.get(fsPath);
assert.ok(nodes.length === 1);
assert.ok(nodes[0].type === NodeType.baseModel);
return nodes[0];
}

public static insert(node: Node) {
const inst = OneStorage.get();

Expand Down

0 comments on commit 06798a6

Please sign in to comment.