virtual BehaviorTask* CreateTask() const { BehaviorTask* pTask = BEHAVIAC_NEW SelectorProbabilityTask(); pTask->Init(this); return pTask; }
EBTStatus PlannerTaskReference::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_UNUSED_VAR(childStatus); BEHAVIAC_ASSERT(ReferencedBehavior::DynamicCast(this->m_node) != 0); //BEHAVIAC_ASSERT(this->m_node is ReferencedBehavior); ReferencedBehavior* pNode = (ReferencedBehavior*)this->m_node; //ReferencedBehavior pNode = this->m_node as ReferencedBehavior; BEHAVIAC_ASSERT(pNode != NULL); EBTStatus status = BT_RUNNING; //pNode->SetTaskParams(pAgent); if (pNode->RootTaskNode() == NULL) { status = this->m_subTree->exec(pAgent); } else { #if !BEHAVIAC_RELEASE if (!_logged) { pAgent->LogJumpTree(pNode->GetReferencedTree()); _logged = true; } #endif BEHAVIAC_ASSERT(this->m_children.size() == 1); BehaviorTask* c = this->m_children[0]; status = c->exec(pAgent); } return status; }
virtual BehaviorTask* CreateTask() const { BehaviorTask* pTask = BEHAVIAC_NEW DecoratorWeightTask(); pTask->Init(this); return pTask; }
EBTStatus SelectorStochasticTask::update(Agent* pAgent, EBTStatus childStatus) { bool bFirst = true; BEHAVIAC_ASSERT(this->m_activeChildIndex < (int)this->m_children.size()); // Keep going until a child behavior says its running. for (;;) { EBTStatus s = childStatus; if (!bFirst || s == BT_RUNNING) { uint32_t childIndex = this->m_set[this->m_activeChildIndex]; BehaviorTask* pBehavior = this->m_children[childIndex]; s = pBehavior->exec(pAgent); } bFirst = false; // If the child succeeds, or keeps running, do the same. if (s != BT_FAILURE) { return s; } // Hit the end of the array, job done! ++this->m_activeChildIndex; if (this->m_activeChildIndex >= (int)this->m_children.size()) { return BT_FAILURE; } } }
EBTStatus WithPreconditionTask::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_UNUSED_VAR(pAgent); BEHAVIAC_UNUSED_VAR(childStatus); BehaviorTask* pParent = this->GetParent(); BEHAVIAC_UNUSED_VAR(pParent); BEHAVIAC_ASSERT(SelectorLoopTask::DynamicCast(pParent)); BEHAVIAC_ASSERT(this->m_children.size() == 2); if (this->m_bIsUpdatePrecondition) { BehaviorTask* precond = this->m_children[0]; EBTStatus s = precond->exec(pAgent, childStatus); return s; } else { BehaviorTask* action = this->m_children[1]; EBTStatus s = action->exec(pAgent, childStatus); return s; } }
EBTStatus PlannerTaskLoop::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_UNUSED_VAR(childStatus); BEHAVIAC_ASSERT(DecoratorLoop::DynamicCast(this->m_node) != 0); // DecoratorLoop* node = (DecoratorLoop*)this->m_node; BEHAVIAC_ASSERT(this->m_children.size() == 1); BehaviorTask* c = this->m_children[0]; EBTStatus s = c->exec(pAgent); BEHAVIAC_UNUSED_VAR(s); if (this->m_n > 0) { this->m_n--; if (this->m_n == 0) { return BT_SUCCESS; } return BT_RUNNING; } if (this->m_n == -1) { return BT_RUNNING; } BEHAVIAC_ASSERT(this->m_n == 0); return BT_SUCCESS; }
void CompositeTask::load(ISerializableNode* node) { super::load(node); if (this->m_status != BT_INVALID) { CSerializationID attrId("activeChildIndex"); behaviac::string attrStr; node->getAttr(attrId, attrStr); StringUtils::FromString(attrStr.c_str(), this->m_activeChildIndex); //#if !BEHAVIAC_RELEASE // if (this->m_activeChildIndex != uint32_t(-1)) // { // BEHAVIAC_ASSERT(this->m_currentTask == this->m_children[this->m_activeChildIndex]); // } // else // { // BEHAVIAC_ASSERT(this->m_currentTask == 0); // } //#endif BehaviorTasks_t::size_type count = this->m_children.size(); BEHAVIAC_ASSERT(count == (BehaviorTasks_t::size_type)node->getChildCount()); for (BehaviorTasks_t::size_type i = 0; i < count; ++i) { BehaviorTask* childTask = this->m_children[i]; //CSerializationID nodeId("node"); ISerializableNode* chidlNode = node->getChild(i); childTask->load(chidlNode); } } }
BehaviorTask* BehaviorNode::CreateAndInitTask() const { BehaviorTask* pTask = this->createTask(); BEHAVIAC_ASSERT(pTask); pTask->Init(this); return pTask; }
bool BehaviorTask::CheckParentUpdatePreconditions(Agent* pAgent) { bool bValid = true; if (this->m_bHasManagingParent) { bool bHasManagingParent = false; const int kMaxParentsCount = 512; int parentsCount = 0; BehaviorTask* parents[kMaxParentsCount]; BranchTask* parentBranch = this->GetParent(); parents[parentsCount++] = this; //back track the parents until the managing branch while (parentBranch != 0) { BEHAVIAC_ASSERT(parentsCount < kMaxParentsCount, "weird tree!"); parents[parentsCount++] = parentBranch; if (parentBranch->GetCurrentTask() == this) { //BEHAVIAC_ASSERT(parentBranch->GetNode()->IsManagingChildrenAsSubTrees()); bHasManagingParent = true; break; } parentBranch = parentBranch->GetParent(); } if (bHasManagingParent) { for (int i = parentsCount - 1; i >= 0; --i) { BehaviorTask* pb = parents[i]; bValid = pb->CheckPreconditions(pAgent, true); if (!bValid) { break; } } } } else { bValid = this->CheckPreconditions(pAgent, true); } return bValid; }
EBTStatus SelectorProbabilityTask::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_ASSERT(SelectorProbability::DynamicCast(this->GetNode())); const SelectorProbability* pSelectorProbabilityNode = (const SelectorProbability*)(this->GetNode()); if (childStatus != BT_RUNNING) { return childStatus; } //check if we've already chosen a node to run if (this->m_activeChildIndex != CompositeTask::InvalidChildIndex) { BehaviorTask* pNode = this->m_children[this->m_activeChildIndex]; EBTStatus status = pNode->exec(pAgent); return status; } BEHAVIAC_ASSERT(this->m_weightingMap.size() == this->m_children.size()); //generate a number between 0 and the sum of the weights double chosen = this->m_totalSum * GetRandomValue(pSelectorProbabilityNode->m_method, pAgent); double sum = 0; for (uint32_t i = 0; i < this->m_children.size() ; ++i) { int w = this->m_weightingMap[i]; sum += w; if (w > 0 && sum >= chosen) //execute this node { BehaviorTask* pChild = this->m_children[i]; EBTStatus status = pChild->exec(pAgent); if (status == BT_RUNNING) { this->m_activeChildIndex = i; } else { this->m_activeChildIndex = CompositeTask::InvalidChildIndex; } return status; } } return BT_FAILURE; }
EBTStatus FSMTask::UpdateFSM(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_ASSERT(this->m_node != 0); BEHAVIAC_ASSERT(this->m_currentNodeId != -1); EBTStatus status = childStatus; bool bLoop = true; #if !BEHAVIAC_RELEASE const int kMaxCount = 10; behaviac::map<int, int> state_update_count; #endif//#if !BEHAVIAC_RELEASE while (bLoop) { BehaviorTask* currentState = this->GetChildById(this->m_currentNodeId); //BEHAVIAC_ASSERT(currentState->GetNextStateId() == -1, "m_nextStateId is not reset to -1 in onenter"); currentState->exec(pAgent); if (StateTask::DynamicCast(currentState) != 0) { StateTask* pStateTask = (StateTask*)currentState; if (pStateTask->IsEndState()) { return BT_SUCCESS; } } int nextStateId = currentState->GetNextStateId(); if (nextStateId < 0) // don't know why, the nextStateID might be -2147483648, so change the condition { //if not transitioned, don't go on next state, to exit bLoop = false; } else { #if !BEHAVIAC_RELEASE state_update_count[this->m_currentNodeId]++; if (state_update_count[this->m_currentNodeId] > kMaxCount) { behaviac::string treeName = GetParentTreeName(pAgent, this->GetNode()); BEHAVIAC_LOGERROR("%s might be updating an FSM('%s') endlessly, possibly a dead loop, please redesign it!", pAgent->GetName().c_str(), treeName.c_str()); BEHAVIAC_ASSERT(false); } #endif //if transitioned, go on next state this->m_currentNodeId = nextStateId; } } return status; }
EBTStatus PlannerTaskTask::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_UNUSED_VAR(childStatus); //BEHAVIAC_ASSERT(Task::Da); // Task* pNode = (Task*) this->m_node;// as Task; BEHAVIAC_ASSERT(this->m_children.size() == 1); BehaviorTask* c = this->m_children[0]; EBTStatus s = c->exec(pAgent); return s; }
EBTStatus PlannerTaskIterator::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_UNUSED_VAR(childStatus); BEHAVIAC_ASSERT(DecoratorIterator::DynamicCast(this->m_node) != 0); // DecoratorIterator* pNode = (DecoratorIterator*)this->m_node; BEHAVIAC_ASSERT(this->m_children.size() == 1); BehaviorTask* c = this->m_children[0]; EBTStatus s = c->exec(pAgent); return s; }
BehaviorTask* CompositeTask::GetChildById(int nodeId) const { if (this->m_children.size() > 0) { for (unsigned int i = 0; i < this->m_children.size(); ++i) { BehaviorTask* c = this->m_children[i]; if (c->GetId() == nodeId) { return c; } } } return 0; }
EBTStatus SelectorTask::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_UNUSED_VAR(pAgent); bool bFirst = true; BEHAVIAC_ASSERT(this->m_activeChildIndex < this->m_children.size()); // Keep going until a child behavior says its running. for (;;) { EBTStatus s = childStatus; if (!bFirst || s == BT_RUNNING) { BEHAVIAC_ASSERT(this->m_status == BT_INVALID || this->m_status == BT_RUNNING); BehaviorTask* pBehavior = this->m_children[this->m_activeChildIndex]; s = pBehavior->exec(pAgent); } bFirst = false; // If the child succeeds, or keeps running, do the same. if (s != BT_FAILURE) { return s; } // Hit the end of the array, job done! ++this->m_activeChildIndex; if (this->m_activeChildIndex >= this->m_children.size()) { return BT_FAILURE; } if (!this->CheckPredicates(pAgent)) { return BT_FAILURE; } } }
void CompositeTask::save(ISerializableNode* node) const { super::save(node); if (this->m_status != BT_INVALID) { CSerializationID attrId("activeChildIndex"); node->setAttr(attrId, this->m_activeChildIndex); BehaviorTasks_t::size_type count = this->m_children.size(); for (BehaviorTasks_t::size_type i = 0; i < count; ++i) { BehaviorTask* childTask = this->m_children[i]; CSerializationID nodeId("node"); ISerializableNode* chidlNode = node->newChild(nodeId); childTask->save(chidlNode); } } }
EBTStatus IfElseTask::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_ASSERT(childStatus != BT_INVALID); BEHAVIAC_ASSERT(this->m_children.size() == 3); EBTStatus conditionResult = BT_INVALID; if (childStatus == BT_SUCCESS || childStatus == BT_FAILURE) { // if the condition returned running then ended with childStatus conditionResult = childStatus; } if (this->m_activeChildIndex == CompositeTask::InvalidChildIndex) { BehaviorTask* pCondition = this->m_children[0]; if (conditionResult == BT_INVALID) { // condition has not been checked conditionResult = pCondition->exec(pAgent); } if (conditionResult == BT_SUCCESS) { // if this->m_activeChildIndex = 1; } else if (conditionResult == BT_FAILURE) { // else this->m_activeChildIndex = 2; } } else { return childStatus; } if (this->m_activeChildIndex != CompositeTask::InvalidChildIndex) { BehaviorTask* pBehavior = this->m_children[this->m_activeChildIndex]; EBTStatus s = pBehavior->exec(pAgent); return s; } return BT_RUNNING; }
EBTStatus TaskTask::update(Agent* pAgent, EBTStatus childStatus) { EBTStatus status = childStatus; if (childStatus == BT_RUNNING) { BEHAVIAC_ASSERT(Task::DynamicCast(this->GetNode()) != 0, "node is not an Method"); Task* pTaskNode = (Task*)(this->GetNode()); if (pTaskNode->IsHTN()) { #if BEHAVIAC_USE_HTN status = _planner->Update(); #endif //BEHAVIAC_USE_HTN } else { BEHAVIAC_ASSERT(this->m_children.size() == 1); BehaviorTask* c = this->m_children[0]; status = c->exec(pAgent); } } else { BEHAVIAC_ASSERT(true); } return status; }
void CompositeTask::copyto(BehaviorTask* target) const { super::copyto(target); BEHAVIAC_ASSERT(CompositeTask::DynamicCast(target)); CompositeTask* ttask = (CompositeTask*)target; ttask->m_activeChildIndex = this->m_activeChildIndex; BEHAVIAC_ASSERT(this->m_children.size() > 0); BEHAVIAC_ASSERT(this->m_children.size() == ttask->m_children.size()); BehaviorTasks_t::size_type count = this->m_children.size(); for (BehaviorTasks_t::size_type i = 0; i < count; ++i) { BehaviorTask* childTask = this->m_children[i]; BehaviorTask* childTTask = ttask->m_children[i]; childTask->copyto(childTTask); } }
EBTStatus Selector::SelectorUpdate(Agent* pAgent, EBTStatus childStatus, int& activeChildIndex, behaviac::vector<BehaviorTask*>& children) { EBTStatus s = childStatus; int childSize = (int)children.size(); for (;;) { BEHAVIAC_ASSERT(activeChildIndex < childSize); if (s == BT_RUNNING) { BehaviorTask* pBehavior = children[activeChildIndex]; if (this->CheckIfInterrupted(pAgent)) { return BT_FAILURE; } s = pBehavior->exec(pAgent); } // If the child fails, or keeps running, do the same. if (s != BT_FAILURE) { return s; } // Hit the end of the array, job done! ++activeChildIndex; if (activeChildIndex >= childSize) { return BT_FAILURE; } s = BT_RUNNING; } }
EBTStatus SelectorLoopTask::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_UNUSED_VAR(pAgent); BEHAVIAC_UNUSED_VAR(childStatus); //checking the preconditions and take the first action tree uint32_t index = (uint32_t)-1; for (uint32_t i = 0; i < this->m_children.size(); ++i) { WithPreconditionTask* pSubTree = (WithPreconditionTask*)this->m_children[i]; BEHAVIAC_ASSERT(WithPreconditionTask::DynamicCast(pSubTree)); BehaviorTask* pPrecondTree = pSubTree->PreconditionNode(); EBTStatus status = pPrecondTree->exec(pAgent); if (status == BT_SUCCESS) { index = i; break; } } //clean up the current ticking action tree if (index != (uint32_t)-1) { if (this->m_activeChildIndex != CompositeTask::InvalidChildIndex) { WithPreconditionTask* pCurrentSubTree = (WithPreconditionTask*)this->m_children[this->m_activeChildIndex]; BEHAVIAC_ASSERT(WithPreconditionTask::DynamicCast(pCurrentSubTree)); BehaviorTask* pCurrentActionTree = pCurrentSubTree->Action(); WithPreconditionTask* pSubTree = (WithPreconditionTask*)this->m_children[index]; BEHAVIAC_ASSERT(WithPreconditionTask::DynamicCast(pSubTree)); BehaviorTask* pActionTree = pSubTree->Action(); if (pCurrentActionTree != pActionTree) { pCurrentActionTree->abort(pAgent); pCurrentSubTree->abort(pAgent); this->m_activeChildIndex = index; } } for (uint32_t i = 0; i < this->m_children.size(); ++i) { WithPreconditionTask* pSubTree = (WithPreconditionTask*)this->m_children[i]; BEHAVIAC_ASSERT(WithPreconditionTask::DynamicCast(pSubTree)); //dummy ticking so that the designer knows it is updating EBTStatus statusDummy = pSubTree->exec(pAgent); BEHAVIAC_ASSERT(statusDummy == BT_RUNNING); BEHAVIAC_UNUSED_VAR(statusDummy); //when i < index, the precondition is failure, so to continue if (i < index) { continue; } if (i > index) { BehaviorTask* pPreconditionTree = pSubTree->PreconditionNode(); EBTStatus status = pPreconditionTree->exec(pAgent); //to search for the first one whose precondition is success if (status != BT_SUCCESS) { continue; } } BehaviorTask* pActionTree = pSubTree->Action(); EBTStatus status = pActionTree->exec(pAgent); if (status == BT_RUNNING) { this->m_activeChildIndex = index; } else { pActionTree->reset(pAgent); if (status == BT_FAILURE || status == BT_INVALID) { //THE ACTION failed, to try the next one continue; } } BEHAVIAC_ASSERT(status == BT_RUNNING || status == BT_SUCCESS); return status; } } return BT_FAILURE; }
EBTStatus SelectorLoopTask::update(Agent* pAgent, EBTStatus childStatus) { BEHAVIAC_UNUSED_VAR(pAgent); BEHAVIAC_UNUSED_VAR(childStatus); int idx = -1; if (childStatus != BT_RUNNING) { BEHAVIAC_ASSERT(this->m_activeChildIndex != CompositeTask::InvalidChildIndex); if (childStatus == BT_SUCCESS) { return BT_SUCCESS; } else if (childStatus == BT_FAILURE) { //the next for starts from (idx + 1), so that it starts from next one after this failed one idx = this->m_activeChildIndex; } else { BEHAVIAC_ASSERT(false); } } //checking the preconditions and take the first action tree uint32_t index = (uint32_t) - 1; for (uint32_t i = (idx + 1); i < this->m_children.size(); ++i) { WithPreconditionTask* pSubTree = (WithPreconditionTask*)this->m_children[i]; BEHAVIAC_ASSERT(WithPreconditionTask::DynamicCast(pSubTree)); BehaviorTask* pre = pSubTree->PreconditionNode(); EBTStatus status = pre->exec(pAgent); if (status == BT_SUCCESS) { index = i; break; } } //clean up the current ticking action tree if (index != (uint32_t) - 1) { if (this->m_activeChildIndex != CompositeTask::InvalidChildIndex && this->m_activeChildIndex != (int)index) { WithPreconditionTask* pCurrentSubTree = (WithPreconditionTask*)this->m_children[this->m_activeChildIndex]; BEHAVIAC_ASSERT(WithPreconditionTask::DynamicCast(pCurrentSubTree)); BehaviorTask* action = pCurrentSubTree->ActionNode(); BEHAVIAC_UNUSED_VAR(action); pCurrentSubTree->abort(pAgent); } for (uint32_t i = index; i < this->m_children.size(); ++i) { WithPreconditionTask* pSubTree = (WithPreconditionTask*)this->m_children[i]; BEHAVIAC_ASSERT(WithPreconditionTask::DynamicCast(pSubTree)); if (i > index) { BehaviorTask* pre = pSubTree->PreconditionNode(); EBTStatus status = pre->exec(pAgent); //to search for the first one whose precondition is success if (status != BT_SUCCESS) { continue; } } BehaviorTask* action = pSubTree->ActionNode(); EBTStatus s = action->exec(pAgent); if (s == BT_RUNNING) { this->m_activeChildIndex = i; pSubTree->m_status = BT_RUNNING; } else { //pActionTree->reset(pAgent); pSubTree->m_status = s; if (s == BT_FAILURE) { //THE ACTION failed, to try the next one continue; } } BEHAVIAC_ASSERT(s == BT_RUNNING || s == BT_SUCCESS); return s; } } return BT_FAILURE; }