From aa44b7f5378eeb4ca1b907d6efe3063465ea9fa4 Mon Sep 17 00:00:00 2001 From: codetypes Date: Tue, 16 Jul 2024 13:19:15 +0800 Subject: [PATCH] update status flag --- src/components/register-node.ts | 2 +- src/misc/b3type.ts | 5 ++- src/misc/b3util.ts | 74 +++++++++++++++++++++++++-------- src/misc/template.ts | 26 ++++++------ 4 files changed, 74 insertions(+), 33 deletions(-) diff --git a/src/components/register-node.ts b/src/components/register-node.ts index 605272d..0d3dab0 100644 --- a/src/components/register-node.ts +++ b/src/components/register-node.ts @@ -202,7 +202,7 @@ G6.registerNode( }); // status - const status = ((cfg.status || 0) as number).toString(2).padStart(3, "0"); + const status = (((cfg.status ?? 0) as number) & 0b111).toString(2).padStart(3, "0"); addShape("image", { attrs: { x: 204, diff --git a/src/misc/b3type.ts b/src/misc/b3type.ts index 24ef9e5..d6603a5 100644 --- a/src/misc/b3type.ts +++ b/src/misc/b3type.ts @@ -28,7 +28,10 @@ export interface NodeDef { doc?: string; color?: string; icon?: string; - status?: Exclude<`${Status}` | `!${Status}` | `?${Status}` | `&${Status}`, "!running">[]; + status?: Exclude< + `${Status}` | `!${Status}` | `|${Status}` | `&${Status}`, + "!running" | "&running" + >[]; } export interface NodeModel { diff --git a/src/misc/b3util.ts b/src/misc/b3util.ts index e0cb0eb..a4a073b 100644 --- a/src/misc/b3util.ts +++ b/src/misc/b3util.ts @@ -2,7 +2,6 @@ import { useWorkspace } from "@/contexts/workspace-context"; import { NodeArgType, NodeModel, TreeGraphData, TreeModel } from "@/misc/b3type"; import * as fs from "fs"; import { message } from "./hooks"; -import i18n from "./i18n"; import Path from "./path"; import { zhNodeDef } from "./template"; @@ -207,46 +206,83 @@ export const createNode = (data: TreeGraphData, includeChildren: boolean = true) return node; }; +const enum StatusFlag { + SUCCESS = 2, + FAILURE = 1, + RUNNING = 0, + SUCCESS_ZERO = 5, + FAILURE_ZERO = 4, +} + const toStatusFlag = (data: TreeGraphData) => { let status = 0; data.def.status?.forEach((s) => { switch (s) { case "success": - status |= 1 << 2; + status |= 1 << StatusFlag.SUCCESS; break; case "failure": - status |= 1 << 1; + status |= 1 << StatusFlag.FAILURE; break; case "running": - status |= 1 << 0; + status |= 1 << StatusFlag.RUNNING; break; } }); return status; }; -const appendStatusFlag = (data: TreeGraphData, childStatus: number) => { - const childSuccess = (childStatus >> 2) & 1; - const childFailure = (childStatus >> 1) & 1; - const childRunning = (childStatus >> 0) & 1; +const appendStatusFlag = (status: number, childStatus: number) => { + const childSuccess = (childStatus >> StatusFlag.SUCCESS) & 1; + const childFailure = (childStatus >> StatusFlag.FAILURE) & 1; + if (childSuccess == 0) { + status |= 1 << StatusFlag.SUCCESS_ZERO; + } + if (childFailure == 0) { + status |= 1 << StatusFlag.FAILURE_ZERO; + } + status |= childStatus; + return status; +}; + +const buildStatusFlag = (data: TreeGraphData, childStatus: number) => { let status = data.status!; if (data.def.status?.length) { + const childSuccess = (childStatus >> StatusFlag.SUCCESS) & 1; + const childFailure = (childStatus >> StatusFlag.FAILURE) & 1; + const childRunning = (childStatus >> StatusFlag.RUNNING) & 1; + const childHasZeroSuccess = (childStatus >> StatusFlag.SUCCESS_ZERO) & 1; + const childHasZeroFailure = (childStatus >> StatusFlag.FAILURE_ZERO) & 1; data.def.status?.forEach((s) => { switch (s) { case "!success": - status |= childFailure << 2; + status |= childFailure << StatusFlag.SUCCESS; break; case "!failure": - status |= childSuccess << 1; + status |= childSuccess << StatusFlag.FAILURE; break; - case "?success": - status |= childSuccess << 2; + case "|success": + status |= childSuccess << StatusFlag.SUCCESS; break; - case "?failure": - status |= childFailure << 1; + case "|failure": + status |= childFailure << StatusFlag.FAILURE; break; - case "?running": - status |= childRunning << 0; + case "|running": + status |= childRunning << StatusFlag.RUNNING; + break; + case "&success": + if (childHasZeroSuccess) { + status &= ~(1 << StatusFlag.SUCCESS); + } else { + status |= childSuccess << StatusFlag.SUCCESS; + } + break; + case "&failure": + if (childHasZeroFailure) { + status &= ~(1 << StatusFlag.FAILURE); + } else { + status |= childFailure << StatusFlag.FAILURE; + } break; } }); @@ -269,11 +305,13 @@ export const refreshTreeDataId = (data: TreeGraphData, id?: number) => { child.parent = data.id; id = refreshTreeDataId(child, id); if (child.status && !child.disabled) { - childStatus |= child.status; + childStatus = appendStatusFlag(childStatus, child.status); } }); - appendStatusFlag(data, childStatus); + console.log("##@", data.name, childStatus.toString(2).padStart(6, "0")); + buildStatusFlag(data, childStatus); } + console.log("##$", data.name, data.status.toString(2).padStart(6, "0")); return id; }; diff --git a/src/misc/template.ts b/src/misc/template.ts index d83a40a..f56b89c 100644 --- a/src/misc/template.ts +++ b/src/misc/template.ts @@ -4,14 +4,14 @@ export const zhNodeDef = () => { { name: "AlwaysFail", type: "Decorator", - status: ["failure", "?running"], + status: ["failure", "|running"], desc: "始终返回失败", doc: "+ 只能有一个子节点,多个仅执行第一个\n+ 不管子节点是否成功都返回`失败`\n", }, { name: "AlwaysSuccess", type: "Decorator", - status: ["success", "?running"], + status: ["success", "|running"], desc: "始终返回成功", doc: "+ 只能有一个子节点,多个仅执行第一个\n+ 不管子节点是否成功都返回`成功`\n", }, @@ -77,7 +77,7 @@ export const zhNodeDef = () => { { name: "Filter", type: "Action", - status: ["success", "failure"], + status: ["success", "failure", "|running"], desc: "返回满足条件的元素", input: ["输入数组"], output: ["变量", "新数组"], @@ -86,7 +86,7 @@ export const zhNodeDef = () => { { name: "ForEach", type: "Action", - status: ["success", "running", "failure"], + status: ["success", "|running", "|failure"], desc: "遍历数组", input: ["数组"], output: ["变量"], @@ -119,7 +119,7 @@ export const zhNodeDef = () => { { name: "Inverter", type: "Decorator", - status: ["!success", "!failure", "?running"], + status: ["!success", "!failure", "|running"], desc: "反转子节点运行结果", doc: "+ 只能有一个子节点,多个仅执行第一个\n+ 当子节点返回`成功`时返回`失败`\n+ 当子节点返回`失败`时返回`成功`\n", }, @@ -244,7 +244,7 @@ export const zhNodeDef = () => { { name: "Loop", type: "Action", - status: ["success", "running", "failure"], + status: ["success", "|running", "|failure"], desc: "循环执行", input: ["循环次数?"], args: [ @@ -273,14 +273,14 @@ export const zhNodeDef = () => { { name: "Once", type: "Decorator", - status: ["success", "failure", "?running"], + status: ["success", "failure", "|running"], desc: "只执行一次", doc: "+ 只能有一个子节点,多个仅执行第一个\n+ 第一次执行完全部子节点时返回`成功`,之后永远返回`失败`", }, { name: "Parallel", type: "Composite", - status: ["success", "?running"], + status: ["success", "|running"], desc: "并行执行", doc: "+ 并行执行所有子节点\n+ 当有子节点返回`运行中`时,返回`运行中`状态\n+ 执行完所有子节点后,返回`成功`", }, @@ -329,7 +329,7 @@ export const zhNodeDef = () => { { name: "RepeatUntilFailure", type: "Decorator", - status: ["!success", "failure", "?running"], + status: ["!success", "!failure", "|running"], desc: "一直尝试直到子节点返回失败", input: ["最大循环次数?"], args: [ @@ -344,7 +344,7 @@ export const zhNodeDef = () => { { name: "RepeatUntilSuccess", type: "Decorator", - status: ["?success", "failure", "?running"], + status: ["|success", "|failure", "|running"], desc: "一直尝试直到子节点返回成功", input: ["最大循环次数?"], args: [ @@ -360,13 +360,13 @@ export const zhNodeDef = () => { name: "Selector", type: "Composite", desc: "选择执行", - status: ["?success", "?failure", "?running"], + status: ["|success", "|failure", "|running"], doc: "+ 一直往下执行,直到有子节点返回`成功`则返回`成功`\n+ 若全部节点返回`失败`则返回`失败`", }, { name: "Sequence", type: "Composite", - status: ["?success", "?failure", "?running"], + status: ["&success", "|failure", "|running"], desc: "顺序执行", doc: "+ 一直往下执行,只有当所有子节点都返回`成功`, 才返回`成功`\n+ 若子节点返回`失败`,则直接返回`失败`状态\n+ 其余情况返回`运行中`状态\n", }, @@ -374,7 +374,7 @@ export const zhNodeDef = () => { name: "Timeout", type: "Decorator", desc: "超时", - status: ["?success", "?running", "failure"], + status: ["|success", "|running", "failure"], args: [ { name: "time",