optimize import path
This commit is contained in:
1 parent
8bce01dd66
commit
cd84575197
15 files changed
+186
-229
No files matched your search
+24
-4
@@ -47,6 +47,7 @@ const windows: Workspace[] = [];
|
|||||||
|
|
||||||
let buildProject: string;
|
let buildProject: string;
|
||||||
let buildOutput: string;
|
let buildOutput: string;
|
||||||
|
let buildHelp: boolean = false;
|
||||||
|
|
||||||
for (let i = 0; i < argv.length; i++) {
|
for (let i = 0; i < argv.length; i++) {
|
||||||
const arg = argv[i];
|
const arg = argv[i];
|
||||||
@@ -56,9 +57,32 @@ for (let i = 0; i < argv.length; i++) {
|
|||||||
} else if (arg === "--build") {
|
} else if (arg === "--build") {
|
||||||
buildOutput = argv[i + 1];
|
buildOutput = argv[i + 1];
|
||||||
i++;
|
i++;
|
||||||
|
} else if (arg === "--help") {
|
||||||
|
buildHelp = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const printHelp = () => {
|
||||||
|
console.log("Usage: Behavior3 Editor [options]");
|
||||||
|
console.log("Options:");
|
||||||
|
console.log(" --project <path> Set the project path");
|
||||||
|
console.log(" --build <path> Set the build output path");
|
||||||
|
console.log(" --help Print this help");
|
||||||
|
};
|
||||||
|
|
||||||
|
if (buildOutput || buildProject || buildHelp) {
|
||||||
|
if (buildHelp) {
|
||||||
|
printHelp();
|
||||||
|
app.exit(0);
|
||||||
|
} else if (!buildOutput || !buildProject) {
|
||||||
|
console.error("build output or project is not set");
|
||||||
|
printHelp();
|
||||||
|
app.exit(0);
|
||||||
|
}
|
||||||
|
console.log("todo: build output");
|
||||||
|
app.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
async function createWindow(projectPath?: string) {
|
async function createWindow(projectPath?: string) {
|
||||||
const win = new BrowserWindow({
|
const win = new BrowserWindow({
|
||||||
title: "Behaviour3 Editor",
|
title: "Behaviour3 Editor",
|
||||||
@@ -110,10 +134,6 @@ async function createWindow(projectPath?: string) {
|
|||||||
win?.webContents.send("open-project", workspace.projectPath);
|
win?.webContents.send("open-project", workspace.projectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buildProject && buildOutput) {
|
|
||||||
win?.webContents.send("build-project", buildProject, buildOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextWin = BrowserWindow.getAllWindows().at(-1);
|
const nextWin = BrowserWindow.getAllWindows().at(-1);
|
||||||
if (nextWin) {
|
if (nextWin) {
|
||||||
nextWin.focus();
|
nextWin.focus();
|
||||||
|
|||||||
+14
-14
@@ -1,17 +1,3 @@
|
|||||||
import {
|
|
||||||
EditEvent,
|
|
||||||
EditNode,
|
|
||||||
EditTree,
|
|
||||||
EditorStore,
|
|
||||||
useWorkspace,
|
|
||||||
} from "@/contexts/workspace-context";
|
|
||||||
import { NodeModel, TreeGraphData, TreeModel } from "@/misc/b3type";
|
|
||||||
import * as b3util from "@/misc/b3util";
|
|
||||||
import { message } from "@/misc/hooks";
|
|
||||||
import i18n from "@/misc/i18n";
|
|
||||||
import { Hotkey, isMacos, useKeyDown } from "@/misc/keys";
|
|
||||||
import Path from "@/misc/path";
|
|
||||||
import { mergeClassNames, readJson } from "@/misc/util";
|
|
||||||
import { ArrowDownOutlined, ArrowUpOutlined, CloseOutlined } from "@ant-design/icons";
|
import { ArrowDownOutlined, ArrowUpOutlined, CloseOutlined } from "@ant-design/icons";
|
||||||
import G6, { G6GraphEvent, Item, TreeGraph } from "@antv/g6";
|
import G6, { G6GraphEvent, Item, TreeGraph } from "@antv/g6";
|
||||||
import { dialog } from "@electron/remote";
|
import { dialog } from "@electron/remote";
|
||||||
@@ -27,6 +13,20 @@ import { RiFocus3Line } from "react-icons/ri";
|
|||||||
import { VscCaseSensitive } from "react-icons/vsc";
|
import { VscCaseSensitive } from "react-icons/vsc";
|
||||||
import { mergeRefs } from "react-merge-refs";
|
import { mergeRefs } from "react-merge-refs";
|
||||||
import { useDebounceCallback } from "usehooks-ts";
|
import { useDebounceCallback } from "usehooks-ts";
|
||||||
|
import {
|
||||||
|
EditEvent,
|
||||||
|
EditNode,
|
||||||
|
EditTree,
|
||||||
|
EditorStore,
|
||||||
|
useWorkspace,
|
||||||
|
} from "../contexts/workspace-context";
|
||||||
|
import { NodeModel, TreeGraphData, TreeModel } from "../misc/b3type";
|
||||||
|
import * as b3util from "../misc/b3util";
|
||||||
|
import { message } from "../misc/hooks";
|
||||||
|
import i18n from "../misc/i18n";
|
||||||
|
import { Hotkey, isMacos, useKeyDown } from "../misc/keys";
|
||||||
|
import Path from "../misc/path";
|
||||||
|
import { mergeClassNames, readJson } from "../misc/util";
|
||||||
import "./register-node";
|
import "./register-node";
|
||||||
import { calcTreeDataSize } from "./register-node";
|
import { calcTreeDataSize } from "./register-node";
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,3 @@
|
|||||||
import { FileTreeType, useWorkspace } from "@/contexts/workspace-context";
|
|
||||||
import { NodeDef, getNodeType } from "@/misc/b3type";
|
|
||||||
import * as b3util from "@/misc/b3util";
|
|
||||||
import { modal } from "@/misc/hooks";
|
|
||||||
import i18n from "@/misc/i18n";
|
|
||||||
import { Hotkey, isMacos, useKeyDown } from "@/misc/keys";
|
|
||||||
import Path from "@/misc/path";
|
|
||||||
import { DownOutlined } from "@ant-design/icons";
|
import { DownOutlined } from "@ant-design/icons";
|
||||||
import { Button, Dropdown, Flex, FlexProps, Input, MenuProps, Space, Tree } from "antd";
|
import { Button, Dropdown, Flex, FlexProps, Input, MenuProps, Space, Tree } from "antd";
|
||||||
import { ItemType } from "antd/es/menu/interface";
|
import { ItemType } from "antd/es/menu/interface";
|
||||||
@@ -17,6 +10,13 @@ import { FaExclamationTriangle, FaSwatchbook } from "react-icons/fa";
|
|||||||
import { FiCommand, FiDelete } from "react-icons/fi";
|
import { FiCommand, FiDelete } from "react-icons/fi";
|
||||||
import { IoMdReturnLeft } from "react-icons/io";
|
import { IoMdReturnLeft } from "react-icons/io";
|
||||||
import { PiTreeStructureFill } from "react-icons/pi";
|
import { PiTreeStructureFill } from "react-icons/pi";
|
||||||
|
import { FileTreeType, useWorkspace } from "../contexts/workspace-context";
|
||||||
|
import { NodeDef, getNodeType } from "../misc/b3type";
|
||||||
|
import * as b3util from "../misc/b3util";
|
||||||
|
import { modal } from "../misc/hooks";
|
||||||
|
import i18n from "../misc/i18n";
|
||||||
|
import { Hotkey, isMacos, useKeyDown } from "../misc/keys";
|
||||||
|
import Path from "../misc/path";
|
||||||
|
|
||||||
const { DirectoryTree } = Tree;
|
const { DirectoryTree } = Tree;
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,3 @@
|
|||||||
import { EditNode, EditTree, useWorkspace } from "@/contexts/workspace-context";
|
|
||||||
import {
|
|
||||||
isBoolType,
|
|
||||||
isEnumType,
|
|
||||||
isExprType,
|
|
||||||
isFloatType,
|
|
||||||
isIntType,
|
|
||||||
isJsonType,
|
|
||||||
isStringType,
|
|
||||||
NodeModel,
|
|
||||||
TreeGraphData,
|
|
||||||
} from "@/misc/b3type";
|
|
||||||
import {
|
|
||||||
checkNodeArgValue,
|
|
||||||
checkOneof,
|
|
||||||
getNodeArgRawType,
|
|
||||||
isNodeArgArray,
|
|
||||||
isNodeArgOptional,
|
|
||||||
isValidVariableName,
|
|
||||||
} from "@/misc/b3util";
|
|
||||||
import { Hotkey, isMacos } from "@/misc/keys";
|
|
||||||
import { mergeClassNames } from "@/misc/util";
|
|
||||||
import { EditOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
|
import { EditOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
|
||||||
import {
|
import {
|
||||||
AutoComplete,
|
AutoComplete,
|
||||||
@@ -38,6 +16,29 @@ import { FC, useEffect, useMemo } from "react";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Markdown from "react-markdown";
|
import Markdown from "react-markdown";
|
||||||
import { useDebounceCallback } from "usehooks-ts";
|
import { useDebounceCallback } from "usehooks-ts";
|
||||||
|
import { EditNode, EditTree, useWorkspace } from "../contexts/workspace-context";
|
||||||
|
import {
|
||||||
|
isBoolType,
|
||||||
|
isEnumType,
|
||||||
|
isExprType,
|
||||||
|
isFloatType,
|
||||||
|
isIntType,
|
||||||
|
isJsonType,
|
||||||
|
isStringType,
|
||||||
|
NodeModel,
|
||||||
|
TreeGraphData,
|
||||||
|
} from "../misc/b3type";
|
||||||
|
import {
|
||||||
|
checkNodeArgValue,
|
||||||
|
checkOneof,
|
||||||
|
getNodeArgRawType,
|
||||||
|
isNodeArgArray,
|
||||||
|
isNodeArgOptional,
|
||||||
|
isValidVariableName,
|
||||||
|
nodeDefs,
|
||||||
|
} from "../misc/b3util";
|
||||||
|
import { Hotkey, isMacos } from "../misc/keys";
|
||||||
|
import { mergeClassNames } from "../misc/util";
|
||||||
|
|
||||||
interface OptionType extends DefaultOptionType {
|
interface OptionType extends DefaultOptionType {
|
||||||
value: string;
|
value: string;
|
||||||
@@ -99,7 +100,6 @@ const NodeInspector: FC = () => {
|
|||||||
const workspace = {
|
const workspace = {
|
||||||
editing: useWorkspace((state) => state.editing),
|
editing: useWorkspace((state) => state.editing),
|
||||||
editingNode: useWorkspace((state) => state.editingNode)!,
|
editingNode: useWorkspace((state) => state.editingNode)!,
|
||||||
getNodeDef: useWorkspace((state) => state.getNodeDef),
|
|
||||||
nodeDefs: useWorkspace((state) => state.nodeDefs),
|
nodeDefs: useWorkspace((state) => state.nodeDefs),
|
||||||
onEditingNode: useWorkspace((state) => state.onEditingNode),
|
onEditingNode: useWorkspace((state) => state.onEditingNode),
|
||||||
allFiles: useWorkspace((state) => state.allFiles),
|
allFiles: useWorkspace((state) => state.allFiles),
|
||||||
@@ -121,7 +121,7 @@ const NodeInspector: FC = () => {
|
|||||||
// set form values
|
// set form values
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const data = workspace.editingNode.data;
|
const data = workspace.editingNode.data;
|
||||||
const def = workspace.getNodeDef(workspace.editingNode.data.name);
|
const def = nodeDefs.get(workspace.editingNode.data.name);
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
form.setFieldValue("id", data.id);
|
form.setFieldValue("id", data.id);
|
||||||
form.setFieldValue("name", data.name);
|
form.setFieldValue("name", data.name);
|
||||||
@@ -237,7 +237,7 @@ const NodeInspector: FC = () => {
|
|||||||
}, [workspace.allFiles, workspace.fileTree]);
|
}, [workspace.allFiles, workspace.fileTree]);
|
||||||
|
|
||||||
const editingNode = workspace.editingNode;
|
const editingNode = workspace.editingNode;
|
||||||
const def = workspace.getNodeDef(editingNode.data.name);
|
const def = nodeDefs.get(editingNode.data.name);
|
||||||
const disabled = !editingNode.editable;
|
const disabled = !editingNode.editable;
|
||||||
|
|
||||||
// update value
|
// update value
|
||||||
|
|||||||
+6
-53
@@ -1,18 +1,5 @@
|
|||||||
import { useSetting } from "@/contexts/setting-context";
|
|
||||||
import { useWorkspace } from "@/contexts/workspace-context";
|
|
||||||
import * as b3util from "@/misc/b3util";
|
|
||||||
import i18n from "@/misc/i18n";
|
|
||||||
import { Hotkey, isMacos, sendInputEvent } from "@/misc/keys";
|
|
||||||
import Path from "@/misc/path";
|
|
||||||
import { CheckOutlined } from "@ant-design/icons";
|
import { CheckOutlined } from "@ant-design/icons";
|
||||||
import {
|
import { Menu as AppMenu, BrowserWindow, app, dialog } from "@electron/remote";
|
||||||
Menu as AppMenu,
|
|
||||||
BrowserWindow,
|
|
||||||
app,
|
|
||||||
dialog,
|
|
||||||
getCurrentWindow,
|
|
||||||
getGlobal,
|
|
||||||
} from "@electron/remote";
|
|
||||||
import { Button, DropDownProps, Dropdown, Flex, FlexProps, LayoutProps, Space } from "antd";
|
import { Button, DropDownProps, Dropdown, Flex, FlexProps, LayoutProps, Space } from "antd";
|
||||||
import { ItemType } from "antd/es/menu/interface";
|
import { ItemType } from "antd/es/menu/interface";
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
@@ -21,6 +8,11 @@ import * as fs from "fs";
|
|||||||
import { FC, useMemo, useState } from "react";
|
import { FC, useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { PiTreeStructureFill } from "react-icons/pi";
|
import { PiTreeStructureFill } from "react-icons/pi";
|
||||||
|
import { useSetting } from "../contexts/setting-context";
|
||||||
|
import { useWorkspace } from "../contexts/workspace-context";
|
||||||
|
import * as b3util from "../misc/b3util";
|
||||||
|
import i18n from "../misc/i18n";
|
||||||
|
import { Hotkey, isMacos, sendInputEvent } from "../misc/keys";
|
||||||
|
|
||||||
const MenuItemLabel: FC<FlexProps> = (itemProps) => {
|
const MenuItemLabel: FC<FlexProps> = (itemProps) => {
|
||||||
return (
|
return (
|
||||||
@@ -45,45 +37,6 @@ ipcRenderer.on("refresh-app-men", () => {
|
|||||||
useSetting.getState().load();
|
useSetting.getState().load();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on("build-project", (_, project, buildDir) => {
|
|
||||||
const mainConsole = getGlobal("console") as Console;
|
|
||||||
try {
|
|
||||||
let hasError = false;
|
|
||||||
project = Path.posixPath(project);
|
|
||||||
buildDir = Path.posixPath(buildDir);
|
|
||||||
if (!project.endsWith(".b3-workspace")) {
|
|
||||||
throw new Error(`'${project}' is not a workspace`);
|
|
||||||
}
|
|
||||||
const workspace = useWorkspace.getState();
|
|
||||||
workspace.workdir = Path.dirname(project);
|
|
||||||
workspace.loadNodeDefs();
|
|
||||||
for (const path of Path.ls(Path.dirname(project), true)) {
|
|
||||||
if (path.endsWith(".json")) {
|
|
||||||
const buildpath = buildDir + "/" + path.substring(workspace.workdir.length + 1);
|
|
||||||
const treeModel = b3util.createBuildData(path);
|
|
||||||
if (treeModel && treeModel.export === false) {
|
|
||||||
mainConsole.log("skip:", buildpath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mainConsole.log("build:", buildpath);
|
|
||||||
if (!b3util.checkNodeData(treeModel?.root)) {
|
|
||||||
hasError = true;
|
|
||||||
}
|
|
||||||
fs.mkdirSync(Path.dirname(buildpath), { recursive: true });
|
|
||||||
fs.writeFileSync(buildpath, JSON.stringify(treeModel, null, 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasError) {
|
|
||||||
mainConsole.error(i18n.t("buildFailed"));
|
|
||||||
} else {
|
|
||||||
mainConsole.log(i18n.t("buildCompleted"));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
mainConsole.error(i18n.t("buildFailed"));
|
|
||||||
}
|
|
||||||
getCurrentWindow().close();
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Menu: FC<LayoutProps> = () => {
|
export const Menu: FC<LayoutProps> = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [trigger, setTrigger] = useState<DropDownProps["trigger"]>(["click"]);
|
const [trigger, setTrigger] = useState<DropDownProps["trigger"]>(["click"]);
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { useWorkspace } from "@/contexts/workspace-context";
|
|
||||||
import { TreeGraphData, getNodeType } from "@/misc/b3type";
|
|
||||||
import { checkTreeData } from "@/misc/b3util";
|
|
||||||
|
|
||||||
import i18n from "@/misc/i18n";
|
|
||||||
import { isMacos } from "@/misc/keys";
|
|
||||||
import G6 from "@antv/g6";
|
import G6 from "@antv/g6";
|
||||||
|
import { TreeGraphData, getNodeType } from "../misc/b3type";
|
||||||
|
import { checkTreeData, nodeDefs, workdir } from "../misc/b3util";
|
||||||
|
import i18n from "../misc/i18n";
|
||||||
|
import { isMacos } from "../misc/keys";
|
||||||
|
|
||||||
let ctx: CanvasRenderingContext2D | null = null;
|
let ctx: CanvasRenderingContext2D | null = null;
|
||||||
let defaultFontSize = "";
|
let defaultFontSize = "";
|
||||||
@@ -142,12 +140,11 @@ G6.registerNode(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
draw(cfg, group) {
|
draw(cfg, group) {
|
||||||
const workspace = useWorkspace.getState();
|
const nodeDef = nodeDefs.get(cfg.name as string);
|
||||||
const nodeDef = workspace.getNodeDef(cfg.name as string);
|
|
||||||
let classify = getNodeType(nodeDef);
|
let classify = getNodeType(nodeDef);
|
||||||
let color = nodeDef.color || NODE_COLORS[classify] || NODE_COLORS["Other"];
|
let color = nodeDef.color || NODE_COLORS[classify] || NODE_COLORS["Other"];
|
||||||
if (
|
if (
|
||||||
!workspace.hasNodeDef(cfg.name as string) ||
|
!nodeDefs.has(cfg.name as string) ||
|
||||||
(cfg.path && (!cfg.children || (cfg.children as []).length === 0)) ||
|
(cfg.path && (!cfg.children || (cfg.children as []).length === 0)) ||
|
||||||
!checkTreeData(cfg as TreeGraphData)
|
!checkTreeData(cfg as TreeGraphData)
|
||||||
) {
|
) {
|
||||||
@@ -259,9 +256,7 @@ G6.registerNode(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// icon
|
// icon
|
||||||
const img = nodeDef.icon
|
const img = nodeDef.icon ? `file:///${workdir}/${nodeDef.icon}` : `./icons/${classify}.svg`;
|
||||||
? `file:///${workspace.workdir}/${nodeDef.icon}`
|
|
||||||
: `./icons/${classify}.svg`;
|
|
||||||
addShape("image", {
|
addShape("image", {
|
||||||
attrs: {
|
attrs: {
|
||||||
x: 5,
|
x: 5,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useSetting } from "@/contexts/setting-context";
|
|
||||||
import { message, setGlobalHooks } from "@/misc/hooks";
|
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
|
import { useSetting } from "../contexts/setting-context";
|
||||||
|
import { message, setGlobalHooks } from "../misc/hooks";
|
||||||
|
|
||||||
export const Setup: FC = () => {
|
export const Setup: FC = () => {
|
||||||
if (!message) {
|
if (!message) {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { useWorkspace } from "@/contexts/workspace-context";
|
|
||||||
import { NodeDef } from "@/misc/b3type";
|
|
||||||
import { Hotkey, isMacos } from "@/misc/keys";
|
|
||||||
import Path from "@/misc/path";
|
|
||||||
import { SearchOutlined } from "@ant-design/icons";
|
import { SearchOutlined } from "@ant-design/icons";
|
||||||
import { Button, Flex, LayoutProps, Select } from "antd";
|
import { Button, Flex, LayoutProps, Select } from "antd";
|
||||||
import React, { FC, useMemo } from "react";
|
import React, { FC, useMemo } from "react";
|
||||||
|
import { useWorkspace } from "../contexts/workspace-context";
|
||||||
|
import { NodeDef } from "../misc/b3type";
|
||||||
|
import { Hotkey, isMacos } from "../misc/keys";
|
||||||
|
import Path from "../misc/path";
|
||||||
import { Menu } from "./menu";
|
import { Menu } from "./menu";
|
||||||
|
|
||||||
interface OptionType {
|
interface OptionType {
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
import { useSetting } from "@/contexts/setting-context";
|
|
||||||
import { EditorStore, useWorkspace } from "@/contexts/workspace-context";
|
|
||||||
import { modal } from "@/misc/hooks";
|
|
||||||
import { Hotkey, isMacos, setInputFocus, useKeyDown } from "@/misc/keys";
|
|
||||||
import Path from "@/misc/path";
|
|
||||||
import { app } from "@electron/remote";
|
import { app } from "@electron/remote";
|
||||||
import { useKeyPress } from "ahooks";
|
import { useKeyPress } from "ahooks";
|
||||||
import { Button, Flex, Layout, Space, Tabs, Tag, Tooltip } from "antd";
|
import { Button, Flex, Layout, Space, Tabs, Tag, Tooltip } from "antd";
|
||||||
@@ -13,6 +8,11 @@ import { PiTreeStructureFill } from "react-icons/pi";
|
|||||||
import { VscNewFolder, VscRepo } from "react-icons/vsc";
|
import { VscNewFolder, VscRepo } from "react-icons/vsc";
|
||||||
import useForceUpdate from "use-force-update";
|
import useForceUpdate from "use-force-update";
|
||||||
import { useWindowSize } from "usehooks-ts";
|
import { useWindowSize } from "usehooks-ts";
|
||||||
|
import { useSetting } from "../contexts/setting-context";
|
||||||
|
import { EditorStore, useWorkspace } from "../contexts/workspace-context";
|
||||||
|
import { modal } from "../misc/hooks";
|
||||||
|
import { Hotkey, isMacos, setInputFocus, useKeyDown } from "../misc/keys";
|
||||||
|
import Path from "../misc/path";
|
||||||
import { Editor } from "./editor";
|
import { Editor } from "./editor";
|
||||||
import { Explorer } from "./explorer";
|
import { Explorer } from "./explorer";
|
||||||
import { Inspector } from "./inspector";
|
import { Inspector } from "./inspector";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { readJson, writeJson } from "@/misc/util";
|
|
||||||
import { app } from "@electron/remote";
|
import { app } from "@electron/remote";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
|
import { readJson, writeJson } from "../misc/util";
|
||||||
|
|
||||||
const settingPath = app.getPath("userData") + "/settings.json";
|
const settingPath = app.getPath("userData") + "/settings.json";
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import { NodeDef, NodeModel, TreeGraphData, TreeModel, unknownNodeDef } from "@/misc/b3type";
|
|
||||||
import * as b3util from "@/misc/b3util";
|
|
||||||
import { message } from "@/misc/hooks";
|
|
||||||
import i18n from "@/misc/i18n";
|
|
||||||
import Path from "@/misc/path";
|
|
||||||
import { readJson, writeJson } from "@/misc/util";
|
|
||||||
import { Matrix, TreeGraph } from "@antv/g6";
|
import { Matrix, TreeGraph } from "@antv/g6";
|
||||||
import { BrowserWindow, dialog } from "@electron/remote";
|
import { BrowserWindow, dialog } from "@electron/remote";
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
|
import { NodeDef, NodeModel, TreeGraphData, TreeModel } from "../misc/b3type";
|
||||||
|
import * as b3util from "../misc/b3util";
|
||||||
|
import { message } from "../misc/hooks";
|
||||||
|
import i18n from "../misc/i18n";
|
||||||
|
import Path from "../misc/path";
|
||||||
|
import { zhNodeDef } from "../misc/template";
|
||||||
|
import { readJson, writeJson } from "../misc/util";
|
||||||
import { useSetting } from "./setting-context";
|
import { useSetting } from "./setting-context";
|
||||||
|
|
||||||
let buildDir: string | undefined;
|
let buildDir: string | undefined;
|
||||||
@@ -151,7 +152,9 @@ export type WorkspaceStore = {
|
|||||||
|
|
||||||
watch(): void;
|
watch(): void;
|
||||||
loadTrees: () => void;
|
loadTrees: () => void;
|
||||||
|
|
||||||
loadNodeDefs: () => void;
|
loadNodeDefs: () => void;
|
||||||
|
nodeDefs: Map<string, NodeDef>;
|
||||||
|
|
||||||
// edit node
|
// edit node
|
||||||
editingNode?: EditNode | null;
|
editingNode?: EditNode | null;
|
||||||
@@ -164,11 +167,6 @@ export type WorkspaceStore = {
|
|||||||
// edit tree
|
// edit tree
|
||||||
editingTree?: EditTree | null;
|
editingTree?: EditTree | null;
|
||||||
onEditingTree: (editor: EditorStore) => void;
|
onEditingTree: (editor: EditorStore) => void;
|
||||||
|
|
||||||
// node setting
|
|
||||||
nodeDefs: Map<string, NodeDef>;
|
|
||||||
getNodeDef: (name: string) => NodeDef;
|
|
||||||
hasNodeDef: (name: string) => boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadFileTree = (workdir: string, filename: string) => {
|
const loadFileTree = (workdir: string, filename: string) => {
|
||||||
@@ -249,7 +247,48 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
|
|||||||
});
|
});
|
||||||
if (path) {
|
if (path) {
|
||||||
const workspace = get();
|
const workspace = get();
|
||||||
b3util.createProject(path);
|
fs.writeFileSync(Path.dirname(path) + "/node-config.b3-setting", zhNodeDef());
|
||||||
|
fs.writeFileSync(
|
||||||
|
Path.dirname(path) + "/example.json",
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
name: "example",
|
||||||
|
root: {
|
||||||
|
id: 1,
|
||||||
|
name: "Sequence",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Log",
|
||||||
|
args: {
|
||||||
|
str: "hello",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Wait",
|
||||||
|
args: {
|
||||||
|
time: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
fs.writeFileSync(
|
||||||
|
path,
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
nodeConf: "node-config.b3-setting",
|
||||||
|
metadata: [],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
workspace.init(path);
|
workspace.init(path);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -569,14 +608,11 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
nodeDefs: new Map(),
|
||||||
loadNodeDefs: () => {
|
loadNodeDefs: () => {
|
||||||
const workspace = get();
|
const workspace = get();
|
||||||
const nodeDefData = readJson(`${workspace.workdir}/node-config.b3-setting`) as NodeDef[];
|
b3util.initWorkdir(workspace.workdir, message.error.bind(message));
|
||||||
const nodeDefs: Map<string, NodeDef> = new Map();
|
set({ nodeDefs: b3util.nodeDefs });
|
||||||
for (const v of nodeDefData) {
|
|
||||||
nodeDefs.set(v.name, v);
|
|
||||||
}
|
|
||||||
set({ nodeDefs });
|
|
||||||
workspace.editing?.dispatch("refresh");
|
workspace.editing?.dispatch("refresh");
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -616,16 +652,4 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
|
|||||||
editingNode: null,
|
editingNode: null,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// node def
|
|
||||||
nodeDefs: new Map(),
|
|
||||||
getNodeDef: (name) => {
|
|
||||||
const workspace = get();
|
|
||||||
unknownNodeDef.desc = i18n.t("node.unknown.desc");
|
|
||||||
return workspace.nodeDefs.get(name) || unknownNodeDef;
|
|
||||||
},
|
|
||||||
hasNodeDef: (name) => {
|
|
||||||
const workspace = get();
|
|
||||||
return workspace.nodeDefs.has(name);
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
@@ -122,12 +122,6 @@ export interface TreeGraphData extends G6TreeGraphData {
|
|||||||
status?: number;
|
status?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const unknownNodeDef: NodeDef = {
|
|
||||||
name: "unknown",
|
|
||||||
desc: "新建节点",
|
|
||||||
type: "Action",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getNodeType = (def: NodeDef): NodeType => {
|
export const getNodeType = (def: NodeDef): NodeType => {
|
||||||
const type = def.type.toLocaleLowerCase().toString();
|
const type = def.type.toLocaleLowerCase().toString();
|
||||||
if (type.startsWith("action")) {
|
if (type.startsWith("action")) {
|
||||||
|
|||||||
+34
-59
@@ -1,4 +1,4 @@
|
|||||||
import { useWorkspace } from "@/contexts/workspace-context";
|
import * as fs from "fs";
|
||||||
import {
|
import {
|
||||||
isBoolType,
|
isBoolType,
|
||||||
isEnumType,
|
isEnumType,
|
||||||
@@ -12,12 +12,33 @@ import {
|
|||||||
NodeModel,
|
NodeModel,
|
||||||
TreeGraphData,
|
TreeGraphData,
|
||||||
TreeModel,
|
TreeModel,
|
||||||
unknownNodeDef,
|
} from "./b3type";
|
||||||
} from "@/misc/b3type";
|
|
||||||
import * as fs from "fs";
|
|
||||||
import { message } from "./hooks";
|
|
||||||
import Path from "./path";
|
import Path from "./path";
|
||||||
import { zhNodeDef } from "./template";
|
import { readJson } from "./util";
|
||||||
|
|
||||||
|
export let workdir: string = "";
|
||||||
|
let alertError: (msg: string, duration?: number) => void = () => {};
|
||||||
|
|
||||||
|
const unknownNodeDef: NodeDef = {
|
||||||
|
name: "unknown",
|
||||||
|
desc: "",
|
||||||
|
type: "Action",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const nodeDefs = new (class extends Map<string, NodeDef> {
|
||||||
|
get(key: string): NodeDef {
|
||||||
|
return super.get(key) ?? unknownNodeDef;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
export const initWorkdir = (path: string, handler: typeof alertError) => {
|
||||||
|
workdir = path;
|
||||||
|
alertError = handler;
|
||||||
|
const nodeDefData = readJson(`${workdir}/node-config.b3-setting`) as NodeDef[];
|
||||||
|
for (const v of nodeDefData) {
|
||||||
|
nodeDefs.set(v.name, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const isValidVariableName = (name: string) => {
|
export const isValidVariableName = (name: string) => {
|
||||||
return /^[a-zA-Z_]/.test(name);
|
return /^[a-zA-Z_]/.test(name);
|
||||||
@@ -35,7 +56,7 @@ export const isNodeEqual = (node1: NodeModel, node2: NodeModel) => {
|
|||||||
node1.debug === node2.debug &&
|
node1.debug === node2.debug &&
|
||||||
node1.disabled === node2.disabled
|
node1.disabled === node2.disabled
|
||||||
) {
|
) {
|
||||||
const def = useWorkspace.getState().getNodeDef(node1.name);
|
const def = nodeDefs.get(node1.name);
|
||||||
|
|
||||||
for (const arg of def.args ?? []) {
|
for (const arg of def.args ?? []) {
|
||||||
if (node1.args?.[arg.name] !== node2.args?.[arg.name]) {
|
if (node1.args?.[arg.name] !== node2.args?.[arg.name]) {
|
||||||
@@ -208,7 +229,7 @@ export const checkNodeData = (data: NodeModel | null | undefined) => {
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const conf = useWorkspace.getState().getNodeDef(data.name);
|
const conf = nodeDefs.get(data.name);
|
||||||
if (conf.name === unknownNodeDef.name) {
|
if (conf.name === unknownNodeDef.name) {
|
||||||
error(data, `undefined node: ${data.name}`);
|
error(data, `undefined node: ${data.name}`);
|
||||||
return false;
|
return false;
|
||||||
@@ -530,7 +551,6 @@ export const createTreeData = (
|
|||||||
parent?: string,
|
parent?: string,
|
||||||
calcSize?: (d: TreeGraphData) => number[]
|
calcSize?: (d: TreeGraphData) => number[]
|
||||||
) => {
|
) => {
|
||||||
const workspace = useWorkspace.getState();
|
|
||||||
let treeData: TreeGraphData = {
|
let treeData: TreeGraphData = {
|
||||||
id: node.id.toFixed(),
|
id: node.id.toFixed(),
|
||||||
name: node.name,
|
name: node.name,
|
||||||
@@ -540,7 +560,7 @@ export const createTreeData = (
|
|||||||
output: node.output,
|
output: node.output,
|
||||||
debug: node.debug,
|
debug: node.debug,
|
||||||
disabled: node.disabled,
|
disabled: node.disabled,
|
||||||
def: workspace.getNodeDef(node.name),
|
def: nodeDefs.get(node.name),
|
||||||
parent: parent,
|
parent: parent,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -570,12 +590,12 @@ export const createTreeData = (
|
|||||||
if (calcSize) {
|
if (calcSize) {
|
||||||
treeData.size = calcSize(treeData);
|
treeData.size = calcSize(treeData);
|
||||||
}
|
}
|
||||||
message.error(`循环引用节点:${node.path}`, 4);
|
alertError(`循环引用节点:${node.path}`, 4);
|
||||||
return treeData;
|
return treeData;
|
||||||
}
|
}
|
||||||
parsingStack.push(node.path);
|
parsingStack.push(node.path);
|
||||||
try {
|
try {
|
||||||
const subtreePath = workspace.workdir + "/" + node.path;
|
const subtreePath = workdir + "/" + node.path;
|
||||||
const str = fs.readFileSync(subtreePath, "utf8");
|
const str = fs.readFileSync(subtreePath, "utf8");
|
||||||
treeData = createTreeData(JSON.parse(str).root, treeData.id, calcSize);
|
treeData = createTreeData(JSON.parse(str).root, treeData.id, calcSize);
|
||||||
treeData.lastModified = fs.statSync(subtreePath).mtimeMs;
|
treeData.lastModified = fs.statSync(subtreePath).mtimeMs;
|
||||||
@@ -588,7 +608,7 @@ export const createTreeData = (
|
|||||||
treeData.size = calcSize(treeData);
|
treeData.size = calcSize(treeData);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error(`解析子树失败:${node.path}`);
|
alertError(`解析子树失败:${node.path}`);
|
||||||
console.log("parse subtree:", e);
|
console.log("parse subtree:", e);
|
||||||
}
|
}
|
||||||
parsingStack.pop();
|
parsingStack.pop();
|
||||||
@@ -623,7 +643,7 @@ export const createFileData = (data: TreeGraphData, includeSubtree?: boolean) =>
|
|||||||
disabled: data.disabled || undefined,
|
disabled: data.disabled || undefined,
|
||||||
path: data.path || undefined,
|
path: data.path || undefined,
|
||||||
};
|
};
|
||||||
const conf = useWorkspace.getState().getNodeDef(data.name);
|
const conf = nodeDefs.get(data.name);
|
||||||
if (!conf.input?.length) {
|
if (!conf.input?.length) {
|
||||||
nodeData.input = undefined;
|
nodeData.input = undefined;
|
||||||
}
|
}
|
||||||
@@ -657,48 +677,3 @@ export const createNewTree = (path: string) => {
|
|||||||
export const isTreeFile = (path: string) => {
|
export const isTreeFile = (path: string) => {
|
||||||
return path.toLocaleLowerCase().endsWith(".json");
|
return path.toLocaleLowerCase().endsWith(".json");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createProject = (path: string) => {
|
|
||||||
fs.writeFileSync(Path.dirname(path) + "/node-config.b3-setting", zhNodeDef());
|
|
||||||
fs.writeFileSync(
|
|
||||||
Path.dirname(path) + "/example.json",
|
|
||||||
JSON.stringify(
|
|
||||||
{
|
|
||||||
name: "example",
|
|
||||||
root: {
|
|
||||||
id: 1,
|
|
||||||
name: "Sequence",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: "Log",
|
|
||||||
args: {
|
|
||||||
str: "hello",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: "Wait",
|
|
||||||
args: {
|
|
||||||
time: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)
|
|
||||||
);
|
|
||||||
fs.writeFileSync(
|
|
||||||
path,
|
|
||||||
JSON.stringify(
|
|
||||||
{
|
|
||||||
nodeConf: "node-config.b3-setting",
|
|
||||||
metadata: [],
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Context, Node, NodeDef } from "@/behavior3/src/behavior3";
|
import { Node, NodeDef } from "../behavior3/src/behavior3";
|
||||||
import { DeepReadonly } from "../behavior3/src/behavior3/context";
|
import { Context, DeepReadonly } from "../behavior3/src/behavior3/context";
|
||||||
|
|
||||||
export const zhNodeDef = () => {
|
export const zhNodeDef = () => {
|
||||||
const context = new (class extends Context {
|
const context = new (class extends Context {
|
||||||
|
|||||||
+1
-5
@@ -14,11 +14,7 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx"
|
||||||
"baseUrl": "./",
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["src/*"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
|||||||
Reference in new issue
Block a user