77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
|
|
import { TaskStatus, NodeType } from '../../Types/TaskStatus';
|
||
|
|
import { INodeExecutor, NodeExecutionContext, BindingHelper } from '../NodeExecutor';
|
||
|
|
import { NodeExecutorMetadata } from '../NodeMetadata';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 重复装饰器执行器
|
||
|
|
*
|
||
|
|
* 重复执行子节点指定次数
|
||
|
|
*/
|
||
|
|
@NodeExecutorMetadata({
|
||
|
|
implementationType: 'Repeater',
|
||
|
|
nodeType: NodeType.Decorator,
|
||
|
|
displayName: '重复',
|
||
|
|
description: '重复执行子节点指定次数',
|
||
|
|
category: 'Decorator',
|
||
|
|
configSchema: {
|
||
|
|
repeatCount: {
|
||
|
|
type: 'number',
|
||
|
|
default: 1,
|
||
|
|
description: '重复次数(-1表示无限循环)',
|
||
|
|
supportBinding: true
|
||
|
|
},
|
||
|
|
endOnFailure: {
|
||
|
|
type: 'boolean',
|
||
|
|
default: false,
|
||
|
|
description: '子节点失败时是否结束'
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
export class RepeaterExecutor implements INodeExecutor {
|
||
|
|
execute(context: NodeExecutionContext): TaskStatus {
|
||
|
|
const { nodeData, state, runtime } = context;
|
||
|
|
const repeatCount = BindingHelper.getValue<number>(context, 'repeatCount', 1);
|
||
|
|
const endOnFailure = BindingHelper.getValue<boolean>(context, 'endOnFailure', false);
|
||
|
|
|
||
|
|
if (!nodeData.children || nodeData.children.length === 0) {
|
||
|
|
return TaskStatus.Success;
|
||
|
|
}
|
||
|
|
|
||
|
|
const childId = nodeData.children[0]!;
|
||
|
|
|
||
|
|
if (!state.repeatCount) {
|
||
|
|
state.repeatCount = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
const status = context.executeChild(childId);
|
||
|
|
|
||
|
|
if (status === TaskStatus.Running) {
|
||
|
|
return TaskStatus.Running;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (status === TaskStatus.Failure && endOnFailure) {
|
||
|
|
state.repeatCount = 0;
|
||
|
|
return TaskStatus.Failure;
|
||
|
|
}
|
||
|
|
|
||
|
|
state.repeatCount++;
|
||
|
|
runtime.resetNodeState(childId);
|
||
|
|
|
||
|
|
const shouldContinue = (repeatCount === -1) || (state.repeatCount < repeatCount);
|
||
|
|
|
||
|
|
if (shouldContinue) {
|
||
|
|
return TaskStatus.Running;
|
||
|
|
} else {
|
||
|
|
state.repeatCount = 0;
|
||
|
|
return TaskStatus.Success;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
reset(context: NodeExecutionContext): void {
|
||
|
|
delete context.state.repeatCount;
|
||
|
|
if (context.nodeData.children && context.nodeData.children.length > 0) {
|
||
|
|
context.runtime.resetNodeState(context.nodeData.children[0]!);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|