Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: [OneExplorer] Refresh only related nodes #1699

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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