void CompositeBehavior::doAction(bool directlyExecuted) { if (agent->isDead() || agent->isIncapacitated() || (agent->getZone() == NULL)) { agent->setFollowObject(NULL); return; } if (!started()) this->start(); else if (!checkConditions()) endWithFailure(); if (finished()) { Behavior::doAction(directlyExecuted); return; } Behavior* currentChild; do { currentChild = children.get(currentPos); if (currentChild == NULL) { agent->error("NULL child or empty children list in CompositeBehavior"); endWithError(); Behavior::doAction(directlyExecuted); return; } if (!currentChild->started()) currentChild->start(); else if (!currentChild->checkConditions()) // if this isn't here, I can get a single recursion where the child will call the parent's (this) doAction() endWithFailure(); if (!currentChild->finished()) currentChild->doAction(); if (currentChild->finished()) { if (currentChild->succeeded()) this->childSucceeded(); else if (currentChild->failed()) this->childFailed(); currentChild->end(); } } while (currentChild != NULL && currentChild->finished() && !this->finished() && currentPos < children.size()); if (currentChild->finished()) Behavior::doAction(directlyExecuted); }
void ParallelBehavior::doAction(bool directlyExecuted) { if (finished()) { Behavior::doAction(directlyExecuted); return; } if (!started()) this->start(); for (int i = 0; i < children.size(); i++) { Behavior* currentChild = children.get(i); if (currentChild == NULL) { // this shouldn't happen. Bail. agent->error("NULL child or empty children list in ParallelBehavior"); endWithError(); Behavior::doAction(directlyExecuted); return; } if (!unfinishedChildren.contains(currentChild)) // we don't want to process a child after it has already ended continue; if (!currentChild->started()) currentChild->start(); else if (currentChild->finished()) { if (currentChild->succeeded()) this->childSucceeded(); else if (currentChild->failed()) this->childFailed(); currentChild->end(); unfinishedChildren.removeElement(currentChild); } else { currentChild->doAction(); } } if (unfinishedChildren.isEmpty()) this->finish(); Behavior::doAction(directlyExecuted); }