流程
执行线路的分流、循环与排队,以及那个会挂起整张图的等待节点
Flow 节点决定执行接下来去哪里。其它节点都在计算或改变什么,只有这一类节点单纯地为执行线路指路。一张图需要提问、需要重复、需要等待或需要提前收尾时,你要找的就是它们
约定
- 图类型。 除一个之外,Flow 节点都可用于
event图,除Return Value外也都可用于macro图。它们都不出现在function图里:那种图只提供纯的、非 latent(会挂起执行)的节点,而它们每一个都声明为有副作用。本页末尾的Function Entry在两个方向上都是例外——它只存在于function图里,别处都没有 - 引脚命名。
in是执行入口。next、true、false、then、else、then0…、case0…、default、loop、completed是执行出口,卡片上其余引脚都是数据引脚 - 卡上字面量是按引脚给的,不是按类型给的。 下面表格里注明可以填字面量的引脚,才能直接在卡片上输入而不必接线。没有任何一个
condition引脚可以这样填:If、If Else和While的布尔条件永远要接线 - 循环使用单游标推进。
For Loop、For Each和While每次进入只走一步。把循环体末尾接回同一个节点的in引脚,节点才会从loop交出下一轮,并最终从completed离开。没有接回in的循环体只会执行一次 Max iterations留空时默认为 1000。 它是刹车而不是目标:触发上限时会像正常跑完一样从completed离开。没有无上限模式- Blueprint Value 接受 Flow,但不含计时器。
Delay和Skip Delay在那里被排除——一个会挂起的取值器会让它负责的属性一直悬着
If
if
If(如果)按布尔值分流。每次执行有且只有一个出口触发
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
true | out · exec | — | |
false | out · exec | — | |
condition | in · data | boolean | 必须接线 |
If Else
blueprint.flow.ifElse
If Else(如果否则)是一张卡片上的 if / else if / else 阶梯。条件按顺序判断,第一个为真的胜出;都不为真时走else
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
then | out · exec | — | condition为真时走这里 |
else | out · exec | — | 没有任何条件为真时走这里 |
condition | in · data | boolean | 必须接线 |
卡片上的 Add If condition 追加一条分支:一个boolean输入if_N_condition和与之配对的执行出口if_N_then,插在固定的else之前。追加的条件排在condition之后,按添加顺序依次判断
Switch String
blueprint.flow.switchString
Switch String(字符串分支)拿一个字符串逐个比对各 Case 的匹配值,命中第一个匹配的出口;都不匹配时走default。从未设置过值的 Case 永远不会匹配——空着的卡片不是通配符,而是一个永远到不了的分支
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
case0 | out · exec | — | |
case1 | out · exec | — | |
default | out · exec | — | 没有 Case 匹配时走这里 |
value | in · data | string | 用于匹配的字符串。可在卡上填字面量 |
case0Value | in · data | string | case0的匹配值。可在卡上填字面量 |
case1Value | in · data | string | case1的匹配值。可在卡上填字面量 |
Add Case 追加一个string输入case_N_value和与之配对的执行出口case_N_output,插在固定的default之前。追加的 Case 排在case0和case1之后匹配
Sequence
blueprint.flow.sequence
Sequence(顺序执行)把各个出口排队,依次执行:前一条分支跑完,下一条才开始。未连接的出口会被跳过。某条分支里执行到Return时,队列中剩下的分支全部作废
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
then0 | out · exec | — | 卡片上标为 Then 1 |
then1 | out · exec | — | Then 2 |
then2 | out · exec | — | Then 3 |
then3 | out · exec | — | Then 4 |
For Loop
blueprint.flow.forLoop
For Loop(For 循环)从start按step走向end,每个取值触发一次loop,并通过index输出当前值。方向由step的正负决定:只要索引还没越过end就继续
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
loop | out · exec | — | 一轮循环。循环体末尾接回in |
completed | out · exec | — | 区间已走完 |
start | in · data | integer | 可在卡上填字面量 |
end | in · data | integer | 包含该值。可在卡上填字面量 |
step | in · data | integer | 步长为0时按1处理。可在卡上填字面量 |
maxIterations | in · data | integer | 默认 1000。可在卡上填字面量 |
index | out · data | integer | 当前取值 |
For Each
blueprint.flow.forEach
For Each(遍历)走一遍 JSON 数组,每一项触发一次loop,同时给出item和index。items不是数组时不会报错,而是直接从completed离开
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
loop | out · exec | — | 一个数组项。循环体末尾接回in |
completed | out · exec | — | 数组已遍历完 |
items | in · data | json | 要遍历的数组 |
maxIterations | in · data | integer | 默认 1000。可在卡上填字面量 |
item | out · data | json | 当前项 |
index | out · data | integer | 当前下标 |
While
blueprint.flow.while
While(While 循环)只要condition成立就持续触发loop。条件在每次进入时重新读取,所以它必须是循环体真的能改变的东西——一个变量、一次运行时读取——而不是进入循环前算好的定值
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
loop | out · exec | — | 一轮循环。循环体末尾接回in |
completed | out · exec | — | 条件为假,或刹车触发 |
condition | in · data | boolean | 必须接线 |
maxIterations | in · data | integer | 默认 1000。可在卡上填字面量 |
Delay
blueprint.flow.delay · Latent
Delay(延迟)等待一段时间,然后从completed继续。它是唯一的 latent Flow 节点:它会挂起进入它的那条执行链,这也正是它不能出现在function图里的原因——函数要同步把结果交还给调用者,没有地方安放一次尚未完成的等待
token在等待开始之前就已输出,所以这条链挂起期间,另一条链可以读到它并用Skip Delay提前结束等待。时长为0或更小时根本不会挂起。等待期间整次图执行被取消时,等待以取消收场,completed不会触发
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
completed | out · exec | — | 等待结束后触发,被跳过时立即触发 |
duration | in · data | float | 单位秒,0.25即 250 ms。可在卡上填字面量 |
token | out · data | Timer | 传给Skip Delay |
一个Timer标识的是运行时作用域内的那个Delay节点,而不是某一次具体的等待。如果同时有两条执行链停在同一个Delay上,一次Skip Delay会把它们一起放行
Skip Delay
blueprint.flow.skipDelay
Skip Delay(跳过延迟)提前完成一次挂起中的Delay。目标从它自己的completed离开;Skip Delay自己不等待,直接从next继续。传入的不是Delay的 token,或者那个Delay当前并没有在等待时,它静默 no-op——执行照样从next继续
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
next | out · exec | — | 跳过请求提交后立即继续 |
timer | in · data | Timer | 想要提前结束的那个Delay输出的 token |
Return
blueprint.flow.return
Return(返回)结束当前执行链。它没有执行出口,同时也会作废Sequence还排在队列里的分支
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — |
Return Value
blueprint.data.returnValue
Return Value(返回值)把一个值交还给发起求值的一方,并结束当前链。它是 Blueprint Value 图的尾节点——决定被绑定属性取什么值的那个节点。它只属于event图,且只出现在需要产出值的宿主上;放错地方时 graph validation 会指出来。取值图跑完却没有走到它时,上一次解析出的值继续生效
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
value | in · data | any | 属性要取的值 |
要从一个 fn 返回,用的是Fn Return,见 Functions
Noop
blueprint.flow.noop
Noop(空操作)什么都不改,直接把执行传下去。适合做多条分支汇合到同一条后续线路的汇聚点,也适合在链路改到一半时占位
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
next | out · exec | — |
Function Entry
blueprint.function.entry · Pure
function 图的起点。它是本分类里唯一被 function 图提供的节点,也是唯一不被其它任何图类型提供的节点
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
then | out · exec | — |
function 图不是 fn 的函数体——那是一张普通的事件图,它的头是 Functions 里的 Fn。function 是支撑计算值的那种图类型,它只提供纯的、非 latent 的节点