BVB Source Codes

CRYENGINE Show SelectionTreeNode.cpp Source code

Return Download CRYENGINE: download SelectionTreeNode.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "SelectionTreeNode.h"
  5. #include "SelectionContext.h"
  6. #include "SelectionTree.h"
  7. #include "SelectionTreeDebugger.h"
  8.  
  9. SelectionTreeNode::SelectionTreeNode(NodeID parentID)
  10.         : m_nodeID(0)
  11.         , m_parentID(parentID)
  12.         , m_currentID(0)
  13.         , m_type(Invalid)
  14. {
  15. }
  16.  
  17. bool SelectionTreeNode::LoadFromXML(const BlockyXmlBlocks::Ptr& blocks, SelectionTree& tree, const char* treeName,
  18.                                     SelectionVariableDeclarations& variableDecls, const XmlNodeRef& rootNode,
  19.                                     const char* fileName)
  20. {
  21.         assert(treeName);
  22.         assert(m_nodeID);
  23.  
  24.         const char* nodeName = 0;
  25.         if (rootNode->haveAttr("name"))
  26.                 rootNode->getAttr("name", &nodeName);
  27.         else
  28.         {
  29.                 AIWarning("Missing 'name' attribute for tag '%s' in file '%s' at line %d.",
  30.                           rootNode->getTag(), fileName, rootNode->getLine());
  31.  
  32.                 return false;
  33.         }
  34.  
  35.         m_name = nodeName;
  36.  
  37.         const char* nodeType = rootNode->getTag();
  38.  
  39.         if (!stricmp(nodeType, "Priority") || !stricmp(nodeType, "Sequence"))
  40.         {
  41.                 m_type = !stricmp(nodeType, "Priority") ? Priority : Sequence;
  42.  
  43.                 BlockyXmlNodeRef blockyNode(blocks, treeName, rootNode, fileName);
  44.  
  45.                 while (XmlNodeRef childNode = blockyNode.next())
  46.                 {
  47.                         const char* condition = 0;
  48.                         if (childNode->haveAttr("condition"))
  49.                                 childNode->getAttr("condition", &condition);
  50.                         else
  51.                                 condition = "true";
  52.  
  53.                         NodeID childID = tree.AddNode(SelectionTreeNode(m_nodeID));
  54.                         SelectionTreeNode& child = tree.GetNode(childID);
  55.  
  56.                         if (!child.LoadFromXML(blocks, tree, treeName, variableDecls, childNode, fileName))
  57.                                 return false;
  58.  
  59.                         m_children.push_back(Child(childID, SelectionCondition(condition, variableDecls)));
  60.  
  61.                         if (!m_children.back().condition.Valid())
  62.                         {
  63.                                 AIWarning("Failed to compile condition '%s' in file '%s' at line %d.",
  64.                                           condition, fileName, childNode->getLine());
  65.  
  66.                                 return false;
  67.                         }
  68.                 }
  69.         }
  70.         else if (!stricmp(nodeType, "StateMachine"))
  71.         {
  72.                 m_type = StateMachine;
  73.  
  74.                 std::vector<string> stateNames;
  75.  
  76.                 BlockyXmlNodeRef blockyNode(blocks, treeName, rootNode, fileName);
  77.  
  78.                 while (XmlNodeRef childNode = blockyNode.next())
  79.                 {
  80.                         if (stricmp(childNode->getTag(), "State"))
  81.                         {
  82.                                 AIWarning("Unexpected tag '%s' in file '%s' at line %d. 'State' expected.",
  83.                                           childNode->getTag(), fileName, childNode->getLine());
  84.  
  85.                                 return false;
  86.                         }
  87.  
  88.                         const char* stateName = 0;
  89.                         if (childNode->haveAttr("name"))
  90.                                 childNode->getAttr("name", &stateName);
  91.                         else
  92.                         {
  93.                                 AIWarning("Missing 'name' attribute for tag '%s' in file '%s' at line %d.",
  94.                                           childNode->getTag(), fileName, childNode->getLine());
  95.  
  96.                                 return false;
  97.                         }
  98.  
  99.                         stateNames.push_back(stateName);
  100.                 }
  101.  
  102.                 blockyNode.first();
  103.                 while (XmlNodeRef childNode = blockyNode.next())
  104.                 {
  105.                         const char* stateName = stateNames[m_states.size()].c_str();
  106.  
  107.                         m_states.push_back(State());
  108.                         State& state = m_states.back();
  109.  
  110.                         BlockyXmlNodeRef blockStateNode(blocks, treeName, childNode, fileName);
  111.                         while (XmlNodeRef stateChildNode = blockStateNode.next())
  112.                         {
  113.                                 if (!stricmp(stateChildNode->getTag(), "Transition"))
  114.                                 {
  115.                                         state.transitions.push_back(State::Transition());
  116.                                         State::Transition& transition = state.transitions.back();
  117.  
  118.                                         const char* targetStateName = 0;
  119.                                         if (stateChildNode->haveAttr("state"))
  120.                                                 stateChildNode->getAttr("state", &targetStateName);
  121.                                         else
  122.                                         {
  123.                                                 AIWarning("Missing 'state' attribute for state '%s' transition in file '%s' at line %d.",
  124.                                                           stateName, fileName, stateChildNode->getLine());
  125.  
  126.                                                 return false;
  127.                                         }
  128.  
  129.                                         const char* condition = 0;
  130.                                         if (stateChildNode->haveAttr("condition"))
  131.                                                 stateChildNode->getAttr("condition", &condition);
  132.                                         else
  133.                                         {
  134.                                                 AIWarning("Missing 'condition' attribute for state '%s' transition in file '%s' at line %d.",
  135.                                                           stateName, fileName, stateChildNode->getLine());
  136.  
  137.                                                 return false;
  138.                                         }
  139.  
  140.                                         // find state by name
  141.                                         uint8 targetState = 0xff;
  142.                                         for (uint i = 0; i < stateNames.size(); ++i)
  143.                                         {
  144.                                                 if (!stricmp(stateNames[i], targetStateName))
  145.                                                 {
  146.                                                         targetState = i;
  147.                                                         break;
  148.                                                 }
  149.                                         }
  150.  
  151.                                         if (targetState < stateNames.size())
  152.                                                 transition.targetStateID = targetState;
  153.                                         else
  154.                                         {
  155.                                                 AIWarning("Unknown target state '%s' for state '%s' transition in file '%s' at line %d.",
  156.                                                           targetStateName, stateName, fileName, stateChildNode->getLine());
  157.  
  158.                                                 return false;
  159.                                         }
  160.  
  161.                                         transition.condition = SelectionCondition(condition, variableDecls);
  162.                                         if (!transition.condition.Valid())
  163.                                         {
  164.                                                 AIWarning("Failed to compile condition '%s' for state '%s' transition in file '%s' at line %d.",
  165.                                                           condition, stateName, fileName, stateChildNode->getLine());
  166.  
  167.                                                 return false;
  168.                                         }
  169.                                 }
  170.                                 else if (state.childID == 0)
  171.                                 {
  172.                                         state.childID = tree.AddNode(SelectionTreeNode(m_nodeID));
  173.                                         SelectionTreeNode& child = tree.GetNode(state.childID);
  174.  
  175.                                         if (!child.LoadFromXML(blocks, tree, treeName, variableDecls, stateChildNode, fileName))
  176.                                                 return false;
  177.                                 }
  178.                                 else
  179.                                 {
  180.                                         AIWarning("Multiple children definition for State '%s' in file '%s' at line %d.",
  181.                                                   stateName, fileName, stateChildNode->getLine());
  182.  
  183.                                         return false;
  184.                                 }
  185.                         }
  186.                 }
  187.         }
  188.         else if (!stricmp(nodeType, "Leaf"))
  189.         {
  190.                 m_type = Leaf;
  191.  
  192.                 if (rootNode->getChildCount())
  193.                 {
  194.                         AIWarning("Leaf '%s' contains children in file '%s' at line %d.",
  195.                                   m_name.c_str(), fileName, rootNode->getLine());
  196.  
  197.                         return false;
  198.                 }
  199.         }
  200.         else
  201.         {
  202.                 AIWarning("Unknown node type '%s' in file '%s' at line %d.",
  203.                           nodeType, fileName, rootNode->getLine());
  204.  
  205.                 return false;
  206.         }
  207.  
  208.         return true;
  209. }
  210.  
  211. bool SelectionTreeNode::IsDescendant(SelectionContext& context, const NodeID& nodeID) const
  212. {
  213.         NodeID currentNodeID = nodeID;
  214.         while (NodeID parentID = context.GetNode(currentNodeID).GetParentID())
  215.         {
  216.                 const SelectionTreeNode& parentNode = context.GetNode(parentID);
  217.                 if (parentNode.GetNodeID() == GetNodeID())
  218.                         return true;
  219.  
  220.                 currentNodeID = parentNode.GetNodeID();
  221.         }
  222.  
  223.         return false;
  224. }
  225.  
  226. bool SelectionTreeNode::IsAncestor(SelectionContext& context, const NodeID& nodeID) const
  227. {
  228.         if (m_parentID)
  229.         {
  230.                 if (m_parentID != nodeID)
  231.                 {
  232.                         const SelectionTreeNode& parentNode = context.GetNode(m_parentID);
  233.                         return parentNode.IsAncestor(context, nodeID);
  234.                 }
  235.                 return true;
  236.         }
  237.         return false;
  238. }
  239.  
  240. bool SelectionTreeNode::Evaluate(SelectionContext& context, SelectionNodeID& resultNodeID)
  241. {
  242.         BST_DEBUG_EVAL_NODE(*this);
  243.         switch (m_type)
  244.         {
  245.         case Leaf:
  246.                 {
  247.                         resultNodeID = GetNodeID();
  248.                         return true;
  249.                 }
  250.         case Priority:
  251.                 {
  252.                         Children::iterator it = m_children.begin();
  253.                         Children::iterator end = m_children.end();
  254.  
  255.                         for (; it != end; ++it)
  256.                         {
  257.                                 Child& child = *it;
  258.                                 const bool conditionResult = child.condition.Evaluate(context.GetVariables());
  259.                                 BST_DEBUG_EVAL_NODECONDITON(context.GetNode(child.childID), conditionResult);
  260.                                 if (conditionResult)
  261.                                 {
  262.                                         SelectionTreeNode& childNode = context.GetNode(child.childID);
  263.                                         if (childNode.Evaluate(context, resultNodeID))
  264.                                                 return true;
  265.                                 }
  266.                         }
  267.  
  268.                         return false;
  269.                 }
  270.         case Sequence:
  271.                 {
  272.                         if (!context.GetCurrentNodeID() || !IsDescendant(context, context.GetCurrentNodeID()))
  273.                                 m_currentID = 0;
  274.                 }
  275.         case StateMachine:
  276.                 {
  277.                         uint8 nextID = m_currentID;
  278.  
  279.                         if (!context.GetCurrentNodeID() || !IsDescendant(context, context.GetCurrentNodeID()))
  280.                                 nextID = 0;
  281.  
  282.                         assert(nextID < 32);
  283.  
  284.                         uint32 visitedIDs = 1 << m_currentID;
  285.  
  286.                         while (true)
  287.                         {
  288.                                 State& state = m_states[nextID];
  289.                                 State::Transitions::iterator tit = state.transitions.begin();
  290.                                 State::Transitions::iterator tend = state.transitions.end();
  291.  
  292.                                 for (; tit != tend; ++tit)
  293.                                 {
  294.                                         State::Transition& transition = *tit;
  295.  
  296.                                         const bool conditionResult = transition.condition.Evaluate(context.GetVariables());
  297.                                         BST_DEBUG_EVAL_STATECONDITON(context.GetNode(state.childID), conditionResult);
  298.                                         if (conditionResult)
  299.                                         {
  300.                                                 nextID = transition.targetStateID;
  301.                                                 break;
  302.                                         }
  303.                                 }
  304.  
  305.                                 if (tit == tend)  // no transition
  306.                                         break;
  307.  
  308.                                 if (visitedIDs & (1 << nextID))
  309.                                 {
  310.                                         // loop
  311.                                         break;
  312.                                 }
  313.  
  314.                                 visitedIDs |= (1 << nextID);
  315.                         }
  316.  
  317.                         m_currentID = nextID;
  318.  
  319.                         State& state = m_states[m_currentID];
  320.                         return context.GetNode(state.childID).Evaluate(context, resultNodeID);
  321.                 }
  322.         default:
  323.                 {
  324.                         assert(0);
  325.                         return false;
  326.                 }
  327.         }
  328. }
  329.  
downloadSelectionTreeNode.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top