BVB Source Codes

CRYENGINE Show SelectionCondition.cpp Source code

Return Download CRYENGINE: download SelectionCondition.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 "SelectionCondition.h"
  5. #include "SelectionVariables.h"
  6.  
  7. class SimpleLexer
  8. {
  9. public:
  10.         SimpleLexer(const char* buffer)
  11.                 : m_buffer(buffer)
  12.                 , m_obuffer(buffer)
  13.         {
  14.         }
  15.  
  16.         int peek(string* ident = 0)
  17.         {
  18.                 const char* obuffer = m_buffer;
  19.                 string oident(m_ident);
  20.                 int tok = operator()();
  21.                 m_buffer = obuffer;
  22.                 if (ident)
  23.                         ident->swap(m_ident);
  24.                 m_ident.swap(oident);
  25.  
  26.                 return tok;
  27.         }
  28.  
  29.         const char* ident() const
  30.         {
  31.                 return m_ident.c_str();
  32.         }
  33.  
  34.         const char* buf() const
  35.         {
  36.                 return m_obuffer;
  37.         }
  38.  
  39.         int operator()()
  40.         {
  41.                 while (unsigned char ch = *m_buffer++)
  42.                 {
  43.                         unsigned char next = *m_buffer;
  44.  
  45.                         switch (ch)
  46.                         {
  47.                         case '(':
  48.                         case ')':
  49.                                 return (int)ch;
  50.                         case '=':
  51.                                 if (next == '=')
  52.                                 {
  53.                                         ++m_buffer;
  54.                                         return '==';
  55.                                 }
  56.                                 return ch;
  57.                         case '!':
  58.                                 if (next == '=')
  59.                                 {
  60.                                         ++m_buffer;
  61.                                         return '!=';
  62.                                 }
  63.                                 return ch;
  64.                         default:
  65.                                 {
  66.                                         if (isalpha(ch) || (ch == '_'))
  67.                                         {
  68.                                                 m_ident.clear();
  69.                                                 m_ident.push_back(ch);
  70.                                                 while ((ch = *m_buffer) && (isalnum(ch) || (ch == '.') || (ch == '_')))
  71.                                                 {
  72.                                                         ++m_buffer;
  73.                                                         m_ident.push_back(ch);
  74.                                                 }
  75.  
  76.                                                 // keywords
  77.                                                 if (!stricmp(m_ident.c_str(), "or"))
  78.                                                         return 'or';
  79.                                                 else if (!stricmp(m_ident.c_str(), "and"))
  80.                                                         return 'and';
  81.                                                 else if (!stricmp(m_ident.c_str(), "xor"))
  82.                                                         return 'xor';
  83.                                                 else if (!stricmp(m_ident.c_str(), "true"))
  84.                                                         return 'true';
  85.                                                 else if (!stricmp(m_ident.c_str(), "false"))
  86.                                                         return 'fals';
  87.                                                 return 'var';
  88.                                         }
  89.                                         else if (isspace(ch))
  90.                                                 continue;
  91.  
  92.                                         return ch;
  93.                                 }
  94.                         }
  95.                 }
  96.  
  97.                 return 0;
  98.         }
  99.  
  100. private:
  101.         const char* m_buffer;
  102.         const char* m_obuffer;
  103.         string      m_ident;
  104. };
  105.  
  106. SelectionCondition::SelectionCondition()
  107.         : m_rootID(-1)
  108. {
  109. }
  110.  
  111. SelectionCondition::SelectionCondition(const char* condition, const SelectionVariableDeclarations& variables)
  112.         : m_rootID(Parse(condition, variables))
  113. {
  114.         if (m_rootID >= 0)
  115.                 Optimise();
  116. }
  117.  
  118. int SelectionCondition::AddOp(const ConditionOp& op)
  119. {
  120.         m_conditionOps.push_back(op);
  121.         return (int)m_conditionOps.size() - 1;
  122. }
  123.  
  124. int SelectionCondition::ParseLogical(SimpleLexer& lex, int tok, const SelectionVariableDeclarations& variables)
  125. {
  126.         int leftID = ParseCompOp(lex, tok, variables);
  127.         if (leftID == -1)
  128.                 return -1;
  129.  
  130.         while ((tok = lex.peek()) && (tok == 'and') || (tok == 'or') || (tok == 'xor'))
  131.         {
  132.                 lex();
  133.  
  134.                 int rightID = ParseCompOp(lex, lex(), variables);
  135.                 if (rightID == -1)
  136.                         return -1;
  137.  
  138.                 switch (tok)
  139.                 {
  140.                 case 'or':
  141.                         leftID = AddOp(ConditionOp(ConditionOp::Or, leftID, rightID));
  142.                         break;
  143.                 case 'and':
  144.                         leftID = AddOp(ConditionOp(ConditionOp::And, leftID, rightID));
  145.                         break;
  146.                 case 'xor':
  147.                         leftID = AddOp(ConditionOp(ConditionOp::Xor, leftID, rightID));
  148.                         break;
  149.                 }
  150.         }
  151.  
  152.         return leftID;
  153. }
  154.  
  155. int SelectionCondition::ParseCompOp(SimpleLexer& lex, int tok, const SelectionVariableDeclarations& variables)
  156. {
  157.         int leftID = ParseUnary(lex, tok, variables);
  158.         if (leftID == -1)
  159.                 return -1;
  160.  
  161.         tok = lex.peek();
  162.         if ((tok == '==') || (tok == '!='))
  163.         {
  164.                 lex();
  165.  
  166.                 int rightID = ParseUnary(lex, lex(), variables);
  167.                 if (rightID == -1)
  168.                         return -1;
  169.  
  170.                 switch (tok)
  171.                 {
  172.                 case '==':
  173.                         return AddOp(ConditionOp(ConditionOp::Equal, leftID, rightID));
  174.                 case '!=':
  175.                         return AddOp(ConditionOp(ConditionOp::NotEqual, leftID, rightID));
  176.                 }
  177.         }
  178.  
  179.         return leftID;
  180. }
  181.  
  182. int SelectionCondition::ParseUnary(SimpleLexer& lex, int tok, const SelectionVariableDeclarations& variables)
  183. {
  184.         if (tok == '!')
  185.         {
  186.                 int opID = ParseValue(lex, lex(), variables);
  187.                 if (opID != -1)
  188.                         return AddOp(ConditionOp(ConditionOp::Not, opID, -1));
  189.                 return -1;
  190.         }
  191.  
  192.         return ParseValue(lex, tok, variables);
  193. }
  194.  
  195. int SelectionCondition::ParseValue(SimpleLexer& lex, int tok, const SelectionVariableDeclarations& variables)
  196. {
  197.         if (tok == '(')
  198.         {
  199.                 int opID = ParseLogical(lex, lex(), variables);
  200.                 if ((opID == -1) || (lex() != ')'))
  201.                         return -1;
  202.  
  203.                 return opID;
  204.         }
  205.         else if (tok == 'true')
  206.                 return AddOp(ConditionOp(ConditionOp::Constant, true));
  207.         else if (tok == 'fals')
  208.                 return AddOp(ConditionOp(ConditionOp::Constant, false));
  209.         else if (tok == 'var')
  210.         {
  211.                 if (SelectionVariableID variableID = variables.GetVariableID(lex.ident()))
  212.                         return AddOp(ConditionOp(ConditionOp::Variable, variableID));
  213.                 else
  214.                 {
  215.                         AIWarning("Unknown variable '%s' used in condition '%s'...", lex.ident(), lex.buf());
  216.                 }
  217.         }
  218.  
  219.         return -1;
  220. }
  221.  
  222. int SelectionCondition::Parse(const char* condition, const SelectionVariableDeclarations& variables)
  223. {
  224.         SimpleLexer lex = SimpleLexer(condition);
  225.         return ParseLogical(lex, lex(), variables);
  226. }
  227.  
  228. void SelectionCondition::Optimise()
  229. {
  230.         // TODO(M谩rcio)
  231. }
  232.  
  233. bool SelectionCondition::EvaluateOp(const SelectionVariables& variables, const ConditionOp& op) const
  234. {
  235.         switch (op.opType)
  236.         {
  237.         case ConditionOp::Variable:
  238.                 {
  239.                         bool value = false;
  240.                         variables.GetVariable(op.variableID, &value);
  241.  
  242.                         return value;
  243.                 }
  244.         case ConditionOp::Constant:
  245.                 return op.value;
  246.         case ConditionOp::Or:
  247.                 return EvaluateOp(variables, m_conditionOps[op.operandLeft])
  248.                        || EvaluateOp(variables, m_conditionOps[op.operandRight]);
  249.         case ConditionOp::And:
  250.                 return EvaluateOp(variables, m_conditionOps[op.operandLeft])
  251.                        && EvaluateOp(variables, m_conditionOps[op.operandRight]);
  252.         case ConditionOp::Xor:
  253.                 return EvaluateOp(variables, m_conditionOps[op.operandLeft])
  254.                        ^ EvaluateOp(variables, m_conditionOps[op.operandRight]);
  255.         case ConditionOp::Not:
  256.                 return !EvaluateOp(variables, m_conditionOps[op.operandLeft]);
  257.         case ConditionOp::Equal:
  258.                 return EvaluateOp(variables, m_conditionOps[op.operandLeft])
  259.                        == EvaluateOp(variables, m_conditionOps[op.operandRight]);
  260.         case ConditionOp::NotEqual:
  261.                 return EvaluateOp(variables, m_conditionOps[op.operandLeft])
  262.                        != EvaluateOp(variables, m_conditionOps[op.operandRight]);
  263.         }
  264.  
  265.         return false;
  266. }
  267.  
  268. bool SelectionCondition::Evaluate(const SelectionVariables& variables) const
  269. {
  270.         if (Valid())
  271.                 return EvaluateOp(variables, m_conditionOps[m_rootID]);
  272.  
  273.         return false;
  274. }
  275.  
  276. bool SelectionCondition::Valid() const
  277. {
  278.         return m_rootID >= 0;
  279. }
  280.  
downloadSelectionCondition.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