add nanoid for node
This commit is contained in:
1 parent
bbdf7a95d6
commit
05cce8f91f
9 files changed
+114
-54
No files matched your search
+1
-1
Submodule src/behavior3 updated: 9283002a96...16334eab4c.
+23
-14
@@ -19,7 +19,7 @@ import * as b3util from "../misc/b3util";
|
||||
import { message } from "../misc/hooks";
|
||||
import i18n from "../misc/i18n";
|
||||
import Path from "../misc/path";
|
||||
import { readTree, writeTree } from "../misc/util";
|
||||
import { nanoid, readTree, writeTree } from "../misc/util";
|
||||
import { TreeNodeState, TreeNodeStyle } from "./register-node";
|
||||
|
||||
type G6NodeState = Exclude<G6GraphOptions["node"], undefined>["state"];
|
||||
@@ -89,8 +89,8 @@ export class Graph {
|
||||
const dataB = nodeB.data as unknown as NodeData;
|
||||
return Number(dataA.id) - Number(dataB.id);
|
||||
},
|
||||
getHeight: ({ data }: { data: NodeData }) => data.size![1],
|
||||
getWidth: ({ data }: { data: NodeData }) => data.size![0],
|
||||
getHeight: ({ data }: { data: NodeData }) => data.$size![1],
|
||||
getWidth: ({ data }: { data: NodeData }) => data.$size![0],
|
||||
getVGap: () => 10,
|
||||
getHGap: () => 30,
|
||||
},
|
||||
@@ -147,7 +147,7 @@ export class Graph {
|
||||
private async _update(data: TreeData, refreshId: boolean = true, refreshVars: boolean = false) {
|
||||
this.editor.data = data;
|
||||
if (refreshId) {
|
||||
b3util.refreshNodeData(this.data.root, 1);
|
||||
b3util.refreshNodeData(this.data, this.data.root, 1);
|
||||
}
|
||||
|
||||
if (refreshVars) {
|
||||
@@ -471,18 +471,24 @@ export class Graph {
|
||||
|
||||
async updateNode(editNode: EditNode) {
|
||||
const node = this._graph.getNodeData(editNode.data.id);
|
||||
const data = node.data as unknown as NodeData;
|
||||
let data = node.data as unknown as NodeData;
|
||||
if (b3util.isNodeEqual(data, editNode.data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const subtree = data.path;
|
||||
|
||||
// update node
|
||||
node.data = { ...editNode.data, size: b3util.calcSize(editNode.data) };
|
||||
data = { ...editNode.data, $size: b3util.calcSize(editNode.data) };
|
||||
if (editNode.data.name !== data.name) {
|
||||
data.$id = nanoid();
|
||||
}
|
||||
node.data = data as unknown as Record<string, unknown>;
|
||||
this._graph.updateNodeData([node]);
|
||||
await this._graph.draw();
|
||||
|
||||
// update subtree
|
||||
if (data.path !== editNode.data.path) {
|
||||
if (subtree !== editNode.data.path) {
|
||||
this.editor.data.root = this._nodeToData("1");
|
||||
await this.refresh();
|
||||
}
|
||||
@@ -640,7 +646,7 @@ export class Graph {
|
||||
const id = this._dropId;
|
||||
const pos = this._graph.getElementPosition(id);
|
||||
const data = this._graph.getNodeData(id).data as unknown as NodeData;
|
||||
const [w, h] = data.size!;
|
||||
const [w, h] = data.$size!;
|
||||
const x = e.canvas.x - pos[0];
|
||||
const y = e.canvas.y - pos[1];
|
||||
const states = this._getState(id);
|
||||
@@ -803,17 +809,20 @@ export class Graph {
|
||||
}
|
||||
console.debug("parse node:", str);
|
||||
|
||||
const node = JSON.parse(str) as NodeData;
|
||||
b3util.dfs(node, (v) => (v.$id = nanoid()));
|
||||
|
||||
const root = this._nodeToData("1");
|
||||
let dstData: NodeData | undefined;
|
||||
b3util.dfs(root, (node) => {
|
||||
if (node.id === this._selectedId) {
|
||||
dstData = node;
|
||||
b3util.dfs(root, (v) => {
|
||||
if (v.id === this._selectedId) {
|
||||
dstData = v;
|
||||
}
|
||||
});
|
||||
|
||||
assert(dstData, this._selectedId);
|
||||
dstData.children ||= [];
|
||||
dstData.children.push(JSON.parse(str) as NodeData);
|
||||
dstData.children.push(node);
|
||||
this.selectNode(null);
|
||||
await this._update({ ...this.data, root });
|
||||
this._storeHistory();
|
||||
@@ -881,7 +890,7 @@ export class Graph {
|
||||
|
||||
assert(dstData, this._selectedId);
|
||||
dstData.children ||= [];
|
||||
dstData.children.push({ id: "", name: "unknow" });
|
||||
dstData.children.push({ id: "", name: "unknow", $id: nanoid() });
|
||||
await this._update({ ...this.data, root });
|
||||
this._storeHistory();
|
||||
}
|
||||
@@ -920,7 +929,7 @@ export class Graph {
|
||||
hasSubtreeUpdated() {
|
||||
let updated = false;
|
||||
b3util.dfs(this.data.root, (node) => {
|
||||
if (node.path && b3util.files[node.path] !== node.mtime) {
|
||||
if (node.path && b3util.files[node.path] !== node.$mtime) {
|
||||
updated = true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -822,6 +822,7 @@ const NodeInspector: FC = () => {
|
||||
if (editingNode.data.name !== newname) {
|
||||
workspace.onEditingNode({
|
||||
data: {
|
||||
$id: editingNode.data.$id,
|
||||
id: editingNode.data.id,
|
||||
name: workspace.nodeDefs.get(newname)?.name ?? newname,
|
||||
desc: editingNode.data.desc,
|
||||
|
||||
@@ -388,7 +388,7 @@ class TreeNode extends Rect {
|
||||
}
|
||||
|
||||
private drawStatusIcon(attributes: Required<RectStyleProps>, container: Group) {
|
||||
const status = ((this._data.status ?? 0) & 0b111).toString(2).padStart(3, "0");
|
||||
const status = ((this._data.$status ?? 0) & 0b111).toString(2).padStart(3, "0");
|
||||
this.upsert(
|
||||
"status",
|
||||
GImage,
|
||||
@@ -758,8 +758,8 @@ class TreeNode extends Rect {
|
||||
color = NODE_COLORS[classify];
|
||||
}
|
||||
|
||||
assert(data.size);
|
||||
const [width, height] = data.size;
|
||||
assert(data.$size);
|
||||
const [width, height] = data.$size;
|
||||
|
||||
this._prefix = (node.prefix as string) ?? "";
|
||||
this._width = width;
|
||||
|
||||
+10
-3
@@ -27,10 +27,13 @@ export interface NodeData {
|
||||
disabled?: boolean;
|
||||
path?: string;
|
||||
|
||||
// nanoid, for override
|
||||
$id: string;
|
||||
|
||||
// for runtime
|
||||
mtime?: number;
|
||||
size?: number[];
|
||||
status?: number;
|
||||
$mtime?: number;
|
||||
$size?: number[];
|
||||
$status?: number;
|
||||
}
|
||||
|
||||
export type NodeLayout = "compact" | "normal";
|
||||
@@ -71,6 +74,10 @@ export interface TreeData {
|
||||
import: string[];
|
||||
vars: VarDecl[];
|
||||
root: NodeData;
|
||||
|
||||
$override: {
|
||||
[key: string]: Pick<NodeData, "desc" | "input" | "output" | "args" | "debug" | "disabled">;
|
||||
};
|
||||
}
|
||||
|
||||
export const getNodeType = (def: NodeDef): NodeType => {
|
||||
|
||||
+23
-19
@@ -20,7 +20,7 @@ import {
|
||||
VERSION,
|
||||
} from "./b3type";
|
||||
import Path from "./path";
|
||||
import { readJson, readTree, readWorkspace } from "./util";
|
||||
import { nanoid, readJson, readTree, readWorkspace } from "./util";
|
||||
|
||||
export class NodeDefs extends Map<string, NodeDef> {
|
||||
get(key: string): NodeDef {
|
||||
@@ -520,6 +520,7 @@ const parsingStack: string[] = [];
|
||||
|
||||
export const createNode = (data: NodeData, includeChildren: boolean = true) => {
|
||||
const node: NodeData = {
|
||||
$id: data.$id,
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
desc: data.desc,
|
||||
@@ -598,7 +599,7 @@ const appendStatusFlag = (status: number, childStatus: number) => {
|
||||
};
|
||||
|
||||
const buildStatusFlag = (data: NodeData, childStatus: number) => {
|
||||
let status = data.status!;
|
||||
let status = data.$status!;
|
||||
const def = nodeDefs.get(data.name);
|
||||
if (def.status?.length) {
|
||||
const childSuccess = (childStatus >> StatusFlag.SUCCESS) & 1;
|
||||
@@ -639,9 +640,9 @@ const buildStatusFlag = (data: NodeData, childStatus: number) => {
|
||||
break;
|
||||
}
|
||||
});
|
||||
data.status = status;
|
||||
data.$status = status;
|
||||
} else {
|
||||
data.status = status | childStatus;
|
||||
data.$status = status | childStatus;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -694,9 +695,9 @@ export const checkTreeData = (data: NodeData) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
export const refreshNodeData = (node: NodeData, id: number) => {
|
||||
export const refreshNodeData = (tree: TreeData, node: NodeData, id: number) => {
|
||||
node.id = (id++).toString();
|
||||
node.size = calcSize(node);
|
||||
node.$size = calcSize(node);
|
||||
|
||||
const def = nodeDefs.get(node.name);
|
||||
|
||||
@@ -718,16 +719,16 @@ export const refreshNodeData = (node: NodeData, id: number) => {
|
||||
parsingStack.push(node.path);
|
||||
try {
|
||||
const subtreePath = workdir + "/" + node.path;
|
||||
const subtree = readTree(subtreePath).root;
|
||||
id = refreshNodeData(subtree, --id);
|
||||
const subtree = readTree(subtreePath);
|
||||
id = refreshNodeData(subtree, subtree.root, --id);
|
||||
node.name = subtree.name;
|
||||
node.desc = subtree.desc;
|
||||
node.args = subtree.args;
|
||||
node.input = subtree.input;
|
||||
node.output = subtree.output;
|
||||
node.children = subtree.children;
|
||||
node.mtime = fs.statSync(subtreePath).mtimeMs;
|
||||
node.size = calcSize(node);
|
||||
node.args = subtree.root.args;
|
||||
node.input = subtree.root.input;
|
||||
node.output = subtree.root.output;
|
||||
node.children = subtree.root.children;
|
||||
node.$mtime = fs.statSync(subtreePath).mtimeMs;
|
||||
node.$size = calcSize(node);
|
||||
} catch (e) {
|
||||
alertError(`解析子树失败:${node.path}`);
|
||||
console.log("parse subtree:", e);
|
||||
@@ -735,16 +736,16 @@ export const refreshNodeData = (node: NodeData, id: number) => {
|
||||
parsingStack.pop();
|
||||
} else if (node.children?.length) {
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
id = refreshNodeData(node.children[i], id);
|
||||
id = refreshNodeData(tree, node.children[i], id);
|
||||
}
|
||||
}
|
||||
|
||||
node.status = toStatusFlag(node);
|
||||
node.$status = toStatusFlag(node);
|
||||
if (node.children) {
|
||||
let childStatus = 0;
|
||||
node.children.forEach((child) => {
|
||||
if (child.status && !child.disabled) {
|
||||
childStatus = appendStatusFlag(childStatus, child.status);
|
||||
if (child.$status && !child.disabled) {
|
||||
childStatus = appendStatusFlag(childStatus, child.$status);
|
||||
}
|
||||
});
|
||||
buildStatusFlag(node, childStatus);
|
||||
@@ -756,7 +757,7 @@ export const refreshNodeData = (node: NodeData, id: number) => {
|
||||
export const createBuildData = (path: string) => {
|
||||
try {
|
||||
const treeModel: TreeData = readTree(path);
|
||||
refreshNodeData(treeModel.root, 1);
|
||||
refreshNodeData(treeModel, treeModel.root, 1);
|
||||
dfs(treeModel.root, (node) => (node.id = treeModel.prefix + node.id));
|
||||
treeModel.name = Path.basenameWithoutExt(path);
|
||||
treeModel.root = createFileData(treeModel.root, true);
|
||||
@@ -885,6 +886,7 @@ export const loadModule = async (path: string) => {
|
||||
|
||||
export const createFileData = (data: NodeData, includeSubtree?: boolean) => {
|
||||
const nodeData: NodeData = {
|
||||
$id: data.$id,
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
desc: data.desc || undefined,
|
||||
@@ -926,7 +928,9 @@ export const createNewTree = (path: string) => {
|
||||
root: {
|
||||
id: "1",
|
||||
name: "Sequence",
|
||||
$id: nanoid(),
|
||||
},
|
||||
$override: {},
|
||||
};
|
||||
return tree;
|
||||
};
|
||||
|
||||
+16
-4
@@ -1,9 +1,15 @@
|
||||
import * as fs from "fs";
|
||||
import { customAlphabet } from "nanoid";
|
||||
import { type WorkspaceModel } from "../contexts/workspace-context";
|
||||
import { VarDecl, VERSION, type TreeData } from "./b3type";
|
||||
import { VERSION, type TreeData } from "./b3type";
|
||||
import { dfs } from "./b3util";
|
||||
import Path from "./path";
|
||||
|
||||
export const nanoid = customAlphabet(
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
10
|
||||
);
|
||||
|
||||
export const readJson = <T>(path: string): T => {
|
||||
const str = fs.readFileSync(path, "utf-8");
|
||||
return JSON.parse(str);
|
||||
@@ -21,16 +27,21 @@ export const readWorkspace = (path: string) => {
|
||||
};
|
||||
|
||||
export const readTree = (path: string) => {
|
||||
const data = readJson(path) as TreeData & { declvar?: VarDecl[] };
|
||||
const data = readJson(path) as TreeData;
|
||||
data.version = data.version ?? VERSION;
|
||||
data.prefix = data.prefix ?? "";
|
||||
data.group = data.group || [];
|
||||
data.import = data.import || [];
|
||||
data.vars = data.vars || data.declvar || [];
|
||||
data.vars = data.vars || [];
|
||||
data.root = data.root || {};
|
||||
|
||||
// compatible with old version
|
||||
dfs(data.root, (node) => (node.id = node.id.toString()));
|
||||
dfs(data.root, (node) => {
|
||||
node.id = node.id.toString();
|
||||
if (!node.$id) {
|
||||
node.$id = nanoid();
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
};
|
||||
@@ -46,6 +57,7 @@ export const writeTree = (path: string, data: TreeData) => {
|
||||
import: data.import,
|
||||
vars: data.vars,
|
||||
root: data.root,
|
||||
$override: data.$override,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user