update project template

This commit is contained in:
codetypes committed 2024-05-12 13:22:17 +08:00
1 parent eece90d233
commit fa5644fda7
8 files changed
+337 -216

No files matched your search

+7 -7
View File
@@ -7,10 +7,10 @@ import Path from "@/misc/path";
import G6 from "@antv/g6";
const NODE_COLORS: any = {
["Composite"]: "#5aed20",
["Decorator"]: "#faad14",
["Composite"]: "#34d800",
["Decorator"]: "#ff6700",
["Condition"]: "#e4148b",
["Action"]: "#5b90f9",
["Action"]: "#1668dc",
["Other"]: "#707070",
["Error"]: "#ff0000",
};
@@ -193,9 +193,9 @@ G6.registerNode(
addShape("image", {
attrs: {
x: 5,
y: 3.5,
height: 16,
width: 16,
y: 3,
height: 18,
width: 18,
img,
},
name: "node-icon",
@@ -205,7 +205,7 @@ G6.registerNode(
addShape("text", {
attrs: {
textBaseline: "top",
x: 25,
x: 26,
y: 5,
fontWeight: 800,
text: cfg.name,
+1
View File
@@ -65,6 +65,7 @@ export const Workspace: FC = () => {
workspace.close(workspace.editing.path);
}
}
keysRef.current?.focus();
} else if (isHotkeyPressed(Hotkey.SearchTree)) {
event.preventDefault();
workspace.onShowingSearch(true);
+2 -133
View File
@@ -4,6 +4,7 @@ import * as fs from "fs";
import { message } from "./hooks";
import i18n from "./i18n";
import Path from "./path";
import { zhNodeDef } from "./template";
export const isSubtreeRoot = (data: TreeGraphData) => {
return data.path && data.id.toString() !== "1";
@@ -415,139 +416,7 @@ export const cutWordTo = (str: string, maxlen: number) => {
};
export const createProject = (path: string) => {
fs.writeFileSync(
Path.dirname(path) + "/node-config.b3-setting",
JSON.stringify(
[
{
name: "AlwaysFail",
type: "Decorator",
desc: i18n.t("node.alwaysFail.desc"),
doc: i18n.t("node.alwaysFail.doc"),
},
{
name: "AlwaysSuccess",
type: "Decorator",
desc: i18n.t("node.alwaysSuccess.desc"),
doc: i18n.t("node.alwaysSuccess.doc"),
},
{
name: "Check",
type: "Condition",
desc: i18n.t("node.check.desc"),
args: [
{
name: "value",
type: "code",
desc: i18n.t("node.check.arg1.desc"),
},
],
doc: i18n.t("node.check.doc"),
},
{
name: "Clear",
type: "Action",
desc: i18n.t("node.clear.desc"),
output: [i18n.t("node.clear.output1")],
},
{
name: "ForEach",
type: "Composite",
desc: i18n.t("node.forEach.desc"),
input: [i18n.t("node.forEach.input1")],
output: [i18n.t("node.forEach.output1")],
doc: i18n.t("node.forEach.doc"),
},
{
name: "GetTime",
type: "Action",
desc: i18n.t("node.getTime.desc"),
output: [i18n.t("node.getTime.output1")],
},
{
name: "IsNull",
type: "Condition",
desc: i18n.t("node.isNull.desc"),
input: [i18n.t("node.isNull.input1")],
},
{
name: "Log",
type: "Action",
desc: i18n.t("node.log.desc"),
args: [
{
name: "message",
type: "string",
desc: i18n.t("node.log.arg1.desc"),
},
],
},
{
name: "Loop",
type: "Composite",
desc: i18n.t("node.loop.desc"),
args: [
{
name: "count",
type: "int?",
desc: i18n.t("node.loop.arg1.desc"),
},
],
input: [i18n.t("node.loop.input1") + "?"],
},
{
name: "Not",
type: "Decorator",
desc: i18n.t("node.not.desc"),
doc: i18n.t("node.not.doc"),
},
{
name: "NotNull",
type: "Condition",
desc: i18n.t("node.notNull.desc"),
input: [i18n.t("node.notNull.input")],
},
{
name: "Once",
type: "Composite",
desc: i18n.t("node.once.desc"),
doc: i18n.t("node.once.doc"),
},
{
name: "Parallel",
type: "Composite",
desc: i18n.t("node.parallel.desc"),
doc: i18n.t("node.parallel.doc"),
},
{
name: "Selector",
type: "Composite",
desc: i18n.t("node.selector.desc"),
doc: i18n.t("node.selector.doc"),
},
{
name: "Sequence",
type: "Composite",
desc: i18n.t("node.sequence.desc"),
doc: i18n.t("node.sequence.doc"),
},
{
name: "Wait",
type: "Action",
desc: i18n.t("node.wait.desc"),
args: [
{
name: "time",
type: "float",
desc: i18n.t("node.wait.arg1.desc"),
},
],
},
],
null,
2
)
);
fs.writeFileSync(Path.dirname(path) + "/node-config.b3-setting", zhNodeDef());
fs.writeFileSync(
Path.dirname(path) + "/example.json",
JSON.stringify(
+323
View File
@@ -0,0 +1,323 @@
type Status = "success" | "failure" | "running";
type Constructor<T = unknown> = new (...args: unknown[]) => T;
interface TreeEnv {}
interface Node {}
interface NodeDef {
name: string;
type: "Action" | "Decorator" | "Condition" | "Composite";
desc: string;
icon?: string;
color?: string;
input?: string[];
args?: {
name: string;
type:
| "boolean"
| "boolean?"
| "int"
| "int?"
| "float"
| "float?"
| "enum"
| "enum?"
| "string"
| "string?"
| "code"
| "code?";
desc: string;
options?: { name: string; value: unknown }[];
}[];
output?: string[];
doc?: string;
}
abstract class Process {
init(node: Node): void {}
run(node: Node, env: TreeEnv): Status {
return "success";
}
abstract get descriptor(): NodeDef;
}
namespace zh {
export namespace action {
export class Clear extends Process {
override get descriptor(): NodeDef {
return {
name: "Clear",
type: "Action",
desc: "清除变量",
output: ["清除的变量名"],
};
}
}
export class Log extends Process {
override get descriptor(): NodeDef {
return {
name: "Log",
type: "Action",
desc: "打印日志",
args: [{ name: "message", type: "string", desc: "日志" }],
};
}
}
export class Now extends Process {
override get descriptor(): NodeDef {
return {
name: "Now",
type: "Action",
desc: "获取当前时间",
output: ["当前时间"],
};
}
}
export class Wait extends Process {
override get descriptor(): NodeDef {
return {
name: "Wait",
type: "Action",
desc: "等待",
input: ["等待时间?"],
args: [
{ name: "time", type: "float", desc: "等待时间" },
{ name: "random", type: "float?", desc: "随机范围" },
],
};
}
}
}
export namespace composite {
export class Foreach extends Process {
override get descriptor(): NodeDef {
return {
name: "ForEach",
type: "Composite",
desc: "遍历数组",
input: ["数组"],
output: ["变量"],
doc: `
+ 每次执行子节点前会设置当前遍历到的变量
+ 会执行所有子节点
+ 永远返回「成功」/「运行中」`,
};
}
}
export class Loop extends Process {
override get descriptor(): NodeDef {
return {
name: "Loop",
type: "Composite",
desc: "循环执行",
input: ["循环次数?"],
args: [{ name: "count", type: "int", desc: "循环次数" }],
};
}
}
export class Parallel extends Process {
override get descriptor(): NodeDef {
return {
name: "Parallel",
type: "Composite",
desc: "并行执行",
doc: `执行所有子节点并返回「成功」/「运行中」`,
};
}
}
export class Selector extends Process {
override get descriptor(): NodeDef {
return {
name: "Selector",
type: "Composite",
desc: "选择执行",
doc: `
+ 一直往下执行,有子节点返回「成功」则返回「成功」
+ 若全部节点返回「失败」则返回「失败」
+ 子节点是或 (OR) 的关系`,
};
}
}
export class Sequence extends Process {
override get descriptor(): NodeDef {
return {
name: "Sequence",
type: "Composite",
desc: "顺序执行",
doc: `
+ 一直往下执行,只有当所有子节点都返回「成功」, 才返回「成功」
+ 子节点是与(AND)的关系`,
};
}
}
}
export namespace condition {
export class Check extends Process {
override get descriptor(): NodeDef {
return {
name: "Check",
type: "Condition",
desc: "检查True或False",
args: [{ name: "value", type: "code", desc: "值" }],
doc: `
+ 做简单数值公式判定,返回「成功」或「失败」`,
};
}
}
export class IsNull extends Process {
override get descriptor(): NodeDef {
return {
name: "IsNull",
type: "Condition",
desc: "判断变量是否不存在",
input: ["判断的变量"],
};
}
}
export class NotNull extends Process {
override get descriptor(): NodeDef {
return {
name: "NotNull",
type: "Condition",
desc: "判断变量是否存在",
input: ["判断的变量"],
};
}
}
}
export namespace decorator {
export class AlwaysFail extends Process {
override get descriptor(): NodeDef {
return {
name: "AlwaysFail",
type: "Decorator",
desc: "始终返回失败",
doc: `
+ 只能有一个子节点,多个仅执行第一个
+ 不管子节点是否成功都返回「失败」`,
};
}
}
export class AlwaysSuccess extends Process {
override get descriptor(): NodeDef {
return {
name: "AlwaysSuccess",
type: "Decorator",
desc: "始终返回成功",
doc: `
+ 只能有一个子节点,多个仅执行第一个
+ 不管子节点是否成功都返回「成功」`,
};
}
}
export class Inverter extends Process {
override get descriptor(): NodeDef {
return {
name: "Inverter",
type: "Decorator",
desc: "反转子节点运行结果",
doc: `
+ 只能有一个子节点,多个仅执行第一个
+ 当子节点返回「成功」时返回「失败」
+ 当子节点返回「失败」时返回「成功」
+ 其余返回「运行中」`,
};
}
}
export class Once extends Process {
override get descriptor(): NodeDef {
return {
name: "Once",
type: "Decorator",
desc: "只执行一次",
doc: `
+ 可以接多个子节点,子节点默认全部执行
+ 被打断后该节点后的子节点依旧不会执行
+ 该节点执行后永远返回「成功」`,
};
}
}
export class RepeatUntilFailure extends Process {
override get descriptor(): NodeDef {
return {
name: "RepeatUntilFailure",
type: "Decorator",
desc: "一直尝试直到子节点返回失败",
input: ["最大循环次数?"],
args: [{ name: "maxLoop", type: "int?", desc: "最大循环次数" }],
doc: `
+ 只能有一个子节点,多个仅执行第一个
+ 只有当子节点返回「失败」时,才返回「成功」,其它情况返回「运行中」状态
+ 如果设定了尝试次数,超过指定次数则返回「失败」`,
};
}
}
export class RepeatUntilSuccess extends Process {
override get descriptor(): NodeDef {
return {
name: "RepeatUntilSuccess",
type: "Decorator",
desc: "一直尝试直到子节点返回成功",
input: ["最大循环次数?"],
args: [{ name: "maxLoop", type: "int?", desc: "最大循环次数" }],
doc: `
+ 只能有一个子节点,多个仅执行第一个
+ 只有当子节点返回「成功」时,才返回「成功」,其它情况返回「运行中」状态
+ 如果设定了尝试次数,超过指定次数则返回「失败」`,
};
}
}
}
}
const toString = (nodes: Constructor<Process>[]) => {
const defs: NodeDef[] = [];
for (const cls of nodes) {
defs.push(new cls().descriptor);
}
defs.sort((a, b) => a.name.localeCompare(b.name));
let str = JSON.stringify(defs, null, 2);
str = str.replace(/"doc": "\\n +/g, '"doc": "');
str = str.replace(/\\n +/g, "\\n");
return str;
};
export const zhNodeDef = () => {
return toString([
zh.action.Clear,
zh.action.Log,
zh.action.Now,
zh.action.Wait,
zh.composite.Foreach,
zh.composite.Loop,
zh.composite.Parallel,
zh.composite.Selector,
zh.composite.Sequence,
zh.condition.Check,
zh.condition.IsNull,
zh.condition.NotNull,
zh.decorator.AlwaysFail,
zh.decorator.AlwaysSuccess,
zh.decorator.Inverter,
zh.decorator.Once,
zh.decorator.RepeatUntilFailure,
zh.decorator.RepeatUntilSuccess,
]);
};