bool BranchTask::oneventCurrentNode(Agent* pAgent, const char* eventName) { BEHAVIAC_ASSERT(this->m_currentTask); EBTStatus s = this->m_currentTask->GetStatus(); BEHAVIAC_UNUSED_VAR(s); BEHAVIAC_ASSERT(s == BT_RUNNING && this->m_node->HasEvents()); bool bGoOn = this->m_currentTask->onevent(pAgent, eventName); //give the handling back to parents if (bGoOn) { BranchTask* parentBranch = this->m_currentTask->GetParent(); //back track the parents until the branch while (parentBranch && parentBranch != this) { BEHAVIAC_ASSERT(parentBranch->GetStatus() == BT_RUNNING); bGoOn = parentBranch->onevent(pAgent, eventName); if (!bGoOn) { return false; } parentBranch = parentBranch->GetParent(); } } return bGoOn; }
EBTStatus BranchTask::execCurrentTask(Agent* pAgent) { BEHAVIAC_ASSERT(this->m_currentTask != 0 && this->m_currentTask->GetStatus() == BT_RUNNING); //this->m_currentTask could be cleared in ::tick, to remember it EBTStatus status = this->m_currentTask->exec(pAgent); //give the handling back to parents if (status != BT_RUNNING) { BEHAVIAC_ASSERT(status == BT_SUCCESS || status == BT_FAILURE); BEHAVIAC_ASSERT(this->m_currentTask->m_status == status); BranchTask* parentBranch = this->m_currentTask->GetParent(); this->m_currentTask = 0; //back track the parents until the branch while (parentBranch != 0 && parentBranch != this) { status = parentBranch->exec(pAgent, status); if (status == BT_RUNNING) { return BT_RUNNING; } BEHAVIAC_ASSERT(parentBranch->m_status == status); parentBranch = parentBranch->GetParent(); } } return status; }
EBTStatus BranchTask::resume_branch(Agent* pAgent, EBTStatus status) { BEHAVIAC_ASSERT(this->m_currentTask != 0); BEHAVIAC_ASSERT(status == BT_SUCCESS || status == BT_FAILURE); BranchTask* parent = 0; BehaviorNode* _tNode = (BehaviorNode*) this->m_currentTask->m_node; if (_tNode->IsManagingChildrenAsSubTrees()) { parent = (BranchTask*)this->m_currentTask; } else { parent = this->m_currentTask->GetParent(); } //clear it as it ends and the next exec might need to set it this->m_currentTask = 0; EBTStatus s = parent->exec(pAgent, status); return s; }
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; }
void BranchTask::copyto(BehaviorTask* target) const { super::copyto(target); BEHAVIAC_ASSERT(BranchTask::DynamicCast(target)); BranchTask* ttask = (BranchTask*)target; if (this->m_currentTask) { int id = this->m_currentTask->GetId(); getnode_t temp(id); ttask->traverse(&getid_handler, 0, &temp); BEHAVIAC_ASSERT(temp.task_); ttask->m_currentTask = temp.task_; } }
BranchTask* BehaviorTask::GetParentBranch() { BehaviorTask* pTopNode = this->m_parent; while (pTopNode) { BranchTask* pBranch = BranchTask::DynamicCast(pTopNode); if (pBranch && pBranch->isContinueTicking()) { return pBranch; } pTopNode = pTopNode->m_parent; } return 0; }
EBTStatus BehaviorTask::exec(Agent* pAgent, EBTStatus childStatus) { #if BEHAVIAC_ENABLE_PROFILING #if 1 const char* classStr = (this->m_node ? this->m_node->GetClassNameString().c_str() : "BT"); int nodeId = (this->m_node ? this->m_node->GetId() : -1); behaviac::string taskClassid = FormatString("%s[%i]", classStr, nodeId); AutoProfileBlockSend profiler_block(Profiler::GetInstance(), taskClassid, pAgent); #else const char* classStr = (this->m_node ? this->m_node->GetClassNameString().c_str() : "BT"); BEHAVIAC_PROFILE(classStr); #endif #endif//#if BEHAVIAC_ENABLE_PROFILING BEHAVIAC_ASSERT(!this->m_node || this->m_node->IsValid(pAgent, this), FormatString("Agent In BT:%s while the Agent used for: %s", this->m_node->m_agentType.c_str(), pAgent->GetClassTypeName())); bool bEnterResult = false; if (this->m_status == BT_RUNNING) { bEnterResult = true; } else { //reset it to invalid when it was success/failure this->m_status = BT_INVALID; bEnterResult = this->onenter_action(pAgent); } if (bEnterResult) { #if !BEHAVIAC_RELEASE if (Config::IsLoggingOrSocketing()) { string btStr = BehaviorTask::GetTickInfo(pAgent, this, "update"); //empty btStr is for internal BehaviorTreeTask if (!StringUtils::IsNullOrEmpty(btStr.c_str())) { LogManager::GetInstance()->Log(pAgent, btStr.c_str(), EAR_none, ELM_tick); } } #endif bool bValid = true; int _tempPrecndCount = this->m_node != 0 ? this->m_node->PreconditionsCount() : 0; if (_tempPrecndCount > 0) { bValid = this->m_node->CheckPreconditions(pAgent, true); } if (bValid) { this->m_status = this->update_current(pAgent, childStatus); } else { this->m_status = BT_FAILURE; } if (this->m_status != BT_RUNNING) { //clear it this->onexit_action(pAgent, this->m_status); //this node is possibly ticked by its parent or by the topBranch who records it as currrent node //so, we can't here reset the topBranch's current node } else { BranchTask* tree = this->GetTopManageBranchTask(); if (tree != 0) { tree->SetCurrentTask(this); } } } else { this->m_status = BT_FAILURE; } return this->m_status; }