refactor(behavior-tree)!: 迁移到 Runtime 执行器架构 (#196)

* refactor(behavior-tree)!: 迁移到 Runtime 执行器架构

* fix(behavior-tree): 修复LogAction中的ReDoS安全漏洞

* feat(behavior-tree): 完善行为树核心功能并修复类型错误
This commit is contained in:
YHH
2025-10-31 17:27:38 +08:00
committed by GitHub
parent c58e3411fd
commit 61813e67b6
113 changed files with 7795 additions and 10564 deletions

View File

@@ -0,0 +1,67 @@
import { TaskStatus, NodeType } from '../../Types/TaskStatus';
import { INodeExecutor, NodeExecutionContext } from '../NodeExecutor';
import { NodeExecutorMetadata } from '../NodeMetadata';
/**
* 随机序列执行器
*
* 随机顺序执行子节点序列,全部成功才成功
*/
@NodeExecutorMetadata({
implementationType: 'RandomSequence',
nodeType: NodeType.Composite,
displayName: '随机序列',
description: '随机顺序执行子节点,全部成功才成功',
category: 'Composite'
})
export class RandomSequenceExecutor implements INodeExecutor {
execute(context: NodeExecutionContext): TaskStatus {
const { nodeData, state } = context;
if (!nodeData.children || nodeData.children.length === 0) {
return TaskStatus.Success;
}
if (!state.shuffledIndices || state.shuffledIndices.length === 0) {
state.shuffledIndices = this.shuffleIndices(nodeData.children.length);
}
while (state.currentChildIndex < state.shuffledIndices.length) {
const shuffledIndex = state.shuffledIndices[state.currentChildIndex]!;
const childId = nodeData.children[shuffledIndex]!;
const status = context.executeChild(childId);
if (status === TaskStatus.Running) {
return TaskStatus.Running;
}
if (status === TaskStatus.Failure) {
state.currentChildIndex = 0;
delete state.shuffledIndices;
return TaskStatus.Failure;
}
state.currentChildIndex++;
}
state.currentChildIndex = 0;
delete state.shuffledIndices;
return TaskStatus.Success;
}
private shuffleIndices(length: number): number[] {
const indices = Array.from({ length }, (_, i) => i);
for (let i = indices.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = indices[i]!;
indices[i] = indices[j]!;
indices[j] = temp;
}
return indices;
}
reset(context: NodeExecutionContext): void {
context.state.currentChildIndex = 0;
delete context.state.shuffledIndices;
}
}