load subtree variable definition

This commit is contained in:
codetypes committed 2025-03-16 23:26:43 +08:00
1 parent fea5e0cad8
commit b9be3b09e0
6 files changed
+124 -17

No files matched your search

+3 -2
View File
@@ -79,11 +79,12 @@
"tree.desc": "Tree desc",
"tree.export": "Export",
"tree.firstid": "First id",
"tree.vars": "Variable Definition",
"tree.vars": "Define Variables",
"tree.vars.name": "name",
"tree.vars.invalidName": "Invalid variable name",
"tree.vars.desc": "description",
"tree.vars.imports": "Variable References",
"tree.vars.imports": "Import Variables",
"tree.vars.subtree": "Subtree Variables",
"regnode.input": "Input: ",
"regnode.output": "Output: ",
+3 -2
View File
@@ -79,11 +79,12 @@
"tree.desc": "说明",
"tree.export": "导出",
"tree.firstid": "起始标识",
"tree.vars": "变量定义",
"tree.vars": "定义变量",
"tree.vars.name": "变量名",
"tree.vars.invalidName": "变量名不合法",
"tree.vars.desc": "变量说明",
"tree.vars.imports": "变量引用",
"tree.vars.imports": "导入变量",
"tree.vars.subtree": "子树变量",
"regnode.input": "输入:",
"regnode.output": "输出:",
+9 -2
View File
@@ -4,8 +4,15 @@
"firstid": 1,
"export": true,
"declare": {
"imports": [],
"vars": []
"imports": [
"vars/declare-core.json"
],
"vars": [
{
"name": "test",
"desc": "测试"
}
]
},
"root": {
"id": 1,
+68 -2
View File
@@ -40,7 +40,7 @@ import {
isNodeArgOptional,
isValidVariableName,
isVariadic,
loadImportedVars,
loadVarDef,
} from "../misc/b3util";
import { Hotkey, isMacos } from "../misc/keys";
import { mergeClassNames } from "../misc/util";
@@ -65,7 +65,7 @@ const TreeInspector: FC = () => {
// set form values
useEffect(() => {
const data = workspace.editingTree.data;
loadImportedVars(data.declare.imports);
loadVarDef(data.declare.imports);
form.resetFields();
form.setFieldValue("name", data.name);
form.setFieldValue("desc", data.desc);
@@ -73,6 +73,7 @@ const TreeInspector: FC = () => {
form.setFieldValue("firstid", data.firstid);
form.setFieldValue("declare.vars", data.declare?.vars);
form.setFieldValue("declare.imports", data.declare?.imports);
form.setFieldValue("declare.subtree", data.declare?.subtree);
}, [workspace.editingTree]);
// auto complete for subtree
@@ -231,6 +232,71 @@ const TreeInspector: FC = () => {
)}
</Form.List>
</>
{workspace.editingTree.data.declare.subtree.length > 0 && (
<>
<Divider orientation="left">
<h4>{t("tree.vars.subtree")}</h4>
</Divider>
<Form.List name="declare.subtree">
{(vars) => (
<div style={{ display: "flex", flexDirection: "column", rowGap: 0 }}>
{vars.map((v, idx, arr) => (
<Flex key={v.key} gap={4}>
<Space.Compact
className="b3-inspector-vars-item"
style={{ width: "100%", marginBottom: 0, paddingRight: 18 }}
>
<Form.Item noStyle name={[v.name, "id"]}>
<div
style={{
display: "flex",
alignItems: "center",
paddingLeft: "8px",
paddingRight: "8px",
maxWidth: "60px",
minWidth: "60px",
borderTopLeftRadius: idx === 0 ? "4px" : 0,
borderBottomLeftRadius: idx === arr.length - 1 ? "4px" : 0,
borderLeft: "1px solid #3d506c",
borderTop: "1px solid #3d506c",
borderBottom: idx === arr.length - 1 ? "1px solid #3d506c" : "none",
}}
>
<AimOutlined />
<span style={{ marginLeft: 4 }}>0</span>
</div>
</Form.Item>
<Form.Item noStyle name={[v.name, "name"]}>
<Input
disabled={true}
placeholder={t("tree.vars.name")}
style={{
borderRadius: "0",
borderTop: "1px solid #3d506c",
borderBottom: idx === arr.length - 1 ? "1px solid #3d506c" : "none",
}}
/>
</Form.Item>
<Form.Item noStyle name={[v.name, "desc"]}>
<Input
disabled={true}
placeholder={t("tree.vars.desc")}
style={{
borderTopRightRadius: idx === 0 ? "4px" : 0,
borderBottomRightRadius: idx === arr.length - 1 ? "4px" : 0,
borderTop: "1px solid #3d506c",
borderBottom: idx === arr.length - 1 ? "1px solid #3d506c" : "none",
}}
/>
</Form.Item>
</Space.Compact>
</Flex>
))}
</div>
)}
</Form.List>
</>
)}
<>
<Divider orientation="left">
<h4>{t("tree.vars.imports")}</h4>
+4
View File
@@ -7,6 +7,7 @@ import { create } from "zustand";
import { NodeDef } from "../behavior3/src/behavior3";
import { ImportDef, NodeModel, TreeGraphData, TreeModel, VarDef } from "../misc/b3type";
import * as b3util from "../misc/b3util";
import { loadSubtreeVarDef } from "../misc/b3util";
import { message } from "../misc/hooks";
import i18n from "../misc/i18n";
import Path from "../misc/path";
@@ -128,6 +129,7 @@ export type EditTree = {
declare: {
imports: ImportDef[];
vars: VarDef[];
subtree: VarDef[];
};
};
};
@@ -521,6 +523,7 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
declare: {
vars: editting.declare.vars,
imports: editting.declare.imports,
subtree: loadSubtreeVarDef(editting.data),
},
},
},
@@ -679,6 +682,7 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
declare: {
imports: editor.declare.imports,
vars: editor.declare.vars,
subtree: loadSubtreeVarDef(editor.data),
},
},
},
+37 -9
View File
@@ -687,11 +687,11 @@ export const isTreeFile = (path: string) => {
return path.toLocaleLowerCase().endsWith(".json");
};
export const loadImportedVars = (imports: ImportDef[]) => {
for (const importDef of imports) {
export const loadVarDef = (list: ImportDef[]) => {
for (const entry of list) {
// TODO: check file date
// TODO: use cache
if (importDef.vars.length) {
if (entry.vars.length) {
continue;
}
const filter: Map<string, boolean> = new Map();
@@ -701,14 +701,17 @@ export const loadImportedVars = (imports: ImportDef[]) => {
return;
}
filter.set(path, true);
const model: TreeModel = readTree(`${workdir}/${path}`);
model.declare?.vars?.forEach((v) => vars.push(v));
model.declare?.imports?.forEach((v) => load(v));
console.log("load imported vars:", path);
try {
const model: TreeModel = readTree(`${workdir}/${path}`);
model.declare?.vars?.forEach((v) => vars.push(v));
model.declare?.imports?.forEach((v) => load(v));
} catch (e) {
alertError(`parsing error: ${path}`);
}
};
load(importDef.path);
load(entry.path);
filter.clear();
importDef.vars = vars
entry.vars = vars
.filter((v) => {
if (!filter.has(v.name)) {
filter.set(v.name, true);
@@ -719,3 +722,28 @@ export const loadImportedVars = (imports: ImportDef[]) => {
.sort((a, b) => a.name.localeCompare(b.name));
}
};
export const loadSubtreeVarDef = (data: TreeGraphData) => {
const list: ImportDef[] = [];
const traverse = (v: TreeGraphData) => {
if (v.path) {
list.push({ path: v.path, vars: [] });
}
if (v.children) {
v.children.forEach(traverse);
}
};
traverse(data);
loadVarDef(list);
const filter: Map<string, boolean> = new Map();
const result: VarDef[] = [];
list.forEach((entry) => {
entry.vars.forEach((v) => {
if (!filter.has(v.name)) {
filter.set(v.name, true);
result.push(v);
}
});
});
return result;
};