| 237 | } |
| 238 | |
| 239 | NodeStatus BehaviorState::runDecorator(DecoratorNode const& node, NodeState& state) { |
| 240 | uint64_t id = (uint64_t)&node; |
| 241 | NodeStatus status = NodeStatus::Running; |
| 242 | if (state.isNothing()) { |
| 243 | auto parameters = board()->parameters(node.parameters, id); |
| 244 | |
| 245 | LuaThread thread = nodeLuaThread(node.name); |
| 246 | try { |
| 247 | status = thread.resume<NodeStatus>(parameters, blackboardPtr(), id).value(NodeStatus::Invalid); |
| 248 | } catch (LuaException const& e) { |
| 249 | throw StarException(strf("Lua Exception caught initializing decorator node {} in behavior {}: {}", node.name, m_tree->name, outputException(e, false))); |
| 250 | } |
| 251 | if (status == NodeStatus::Success || status == NodeStatus::Failure) |
| 252 | return status; |
| 253 | |
| 254 | state.set(DecoratorState(thread)); |
| 255 | } |
| 256 | |
| 257 | DecoratorState& decorator = state->get<DecoratorState>(); |
| 258 | // decorator runs its child on yield and is resumed with the child's status on success or failure |
| 259 | while (status == NodeStatus::Running) { |
| 260 | auto childStatus = runNode(*node.child, *decorator.child); |
| 261 | if (childStatus == NodeStatus::Success || childStatus == NodeStatus::Failure) { |
| 262 | try { |
| 263 | status = decorator.thread.resume<NodeStatus>(childStatus).value(NodeStatus::Invalid); |
| 264 | } catch (LuaException const& e) { |
| 265 | throw StarException(strf("Lua Exception caught resuming decorator node {} in behavior {}: {}", node.name, m_tree->name, outputException(e, false))); |
| 266 | } |
| 267 | } else { |
| 268 | return NodeStatus::Running; |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | m_threads.append(decorator.thread); |
| 273 | |
| 274 | return status; |
| 275 | } |
| 276 | |
| 277 | NodeStatus BehaviorState::runComposite(CompositeNode const& node, NodeState& state) { |
| 278 | NodeStatus status; |
nothing calls this directly
no test coverage detected