File indexing completed on 2024-05-12 05:39:28
0001 /*************************************************************************** 0002 * Copyright (C) 2014 by Renaud Guezennec * 0003 * https://rolisteam.org/contact * 0004 * * 0005 * This file is part of DiceParser * 0006 * * 0007 * DiceParser is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published by * 0009 * the Free Software Foundation; either version 2 of the License, or * 0010 * (at your option) any later version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0015 * GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License * 0018 * along with this program; if not, write to the * 0019 * Free Software Foundation, Inc., * 0020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0021 ***************************************************************************/ 0022 #include "scalaroperatornode.h" 0023 0024 #include "result/diceresult.h" 0025 #include <QDebug> 0026 0027 ScalarOperatorNode::ScalarOperatorNode() 0028 : m_internalNode(nullptr), m_scalarResult(new ScalarResult()), m_arithmeticOperator(Dice::ArithmeticOperator::PLUS) 0029 { 0030 m_result= m_scalarResult; 0031 } 0032 ScalarOperatorNode::~ScalarOperatorNode() 0033 { 0034 if(nullptr != m_internalNode) 0035 { 0036 delete m_internalNode; 0037 m_internalNode= nullptr; 0038 } 0039 } 0040 0041 void ScalarOperatorNode::run(ExecutionNode* previous) 0042 { 0043 m_previousNode= previous; 0044 if(nullptr != m_internalNode) 0045 { 0046 m_internalNode->run(this); 0047 } 0048 if(nullptr != previous) 0049 { 0050 auto previousResult= previous->getResult(); 0051 0052 if(nullptr != previousResult) 0053 { 0054 ExecutionNode* internal= m_internalNode; 0055 if(nullptr != internal) 0056 { 0057 while(nullptr != internal->getNextNode()) 0058 { 0059 internal= internal->getNextNode(); 0060 } 0061 0062 Result* internalResult= internal->getResult(); 0063 m_result->setPrevious(internalResult); 0064 if(nullptr != m_internalNode->getResult()) 0065 { 0066 m_internalNode->getResult()->setPrevious(previousResult); 0067 } 0068 0069 if(internalResult == nullptr) 0070 { 0071 m_errors.insert(Dice::ERROR_CODE::NO_VALID_RESULT, 0072 QObject::tr("No Valid result in arithmetic operation: %1").arg(toString(true))); 0073 return; 0074 } 0075 0076 switch(m_arithmeticOperator) 0077 { 0078 case Dice::ArithmeticOperator::PLUS: 0079 m_scalarResult->setValue(add(previousResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal(), 0080 internalResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal())); 0081 break; 0082 case Dice::ArithmeticOperator::MINUS: 0083 m_scalarResult->setValue(substract(previousResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal(), 0084 internalResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal())); 0085 break; 0086 case Dice::ArithmeticOperator::MULTIPLICATION: 0087 m_scalarResult->setValue(multiple(previousResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal(), 0088 internalResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal())); 0089 break; 0090 case Dice::ArithmeticOperator::DIVIDE: 0091 m_scalarResult->setValue(divide(previousResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal(), 0092 internalResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal())); 0093 break; 0094 case Dice::ArithmeticOperator::INTEGER_DIVIDE: 0095 m_scalarResult->setValue( 0096 static_cast<int>(divide(previousResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal(), 0097 internalResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal()))); 0098 break; 0099 case Dice::ArithmeticOperator::POW: 0100 m_scalarResult->setValue(pow(previousResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal(), 0101 internalResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal())); 0102 break; 0103 } 0104 } 0105 0106 if(nullptr != m_nextNode) 0107 { 0108 m_nextNode->run(this); 0109 } 0110 } 0111 } 0112 } 0113 /*bool ScalarOperatorNode::setOperatorChar(QChar c) 0114 { 0115 if(m_scalarOperationList.contains(c)) 0116 { 0117 m_operator = m_scalarOperationList.value(c); 0118 return true; 0119 } 0120 return false; 0121 }*/ 0122 0123 void ScalarOperatorNode::setInternalNode(ExecutionNode* node) 0124 { 0125 m_internalNode= node; 0126 } 0127 qint64 ScalarOperatorNode::add(qreal a, qreal b) 0128 { 0129 return static_cast<qint64>(a + b); 0130 } 0131 qint64 ScalarOperatorNode::substract(qreal a, qreal b) 0132 { 0133 return static_cast<qint64>(a - b); 0134 } 0135 qreal ScalarOperatorNode::divide(qreal a, qreal b) 0136 { 0137 if(qFuzzyCompare(b, 0)) 0138 { 0139 m_errors.insert(Dice::ERROR_CODE::DIVIDE_BY_ZERO, QObject::tr("Division by zero")); 0140 return 0; 0141 } 0142 return static_cast<qreal>(a / b); 0143 } 0144 qint64 ScalarOperatorNode::multiple(qreal a, qreal b) 0145 { 0146 return static_cast<qint64>(a * b); 0147 } 0148 qint64 ScalarOperatorNode::pow(qreal a, qreal b) 0149 { 0150 return static_cast<qint64>(std::pow(a, b)); 0151 } 0152 Dice::ArithmeticOperator ScalarOperatorNode::getArithmeticOperator() const 0153 { 0154 return m_arithmeticOperator; 0155 } 0156 0157 void ScalarOperatorNode::setArithmeticOperator(const Dice::ArithmeticOperator& arithmeticOperator) 0158 { 0159 m_arithmeticOperator= arithmeticOperator; 0160 } 0161 0162 QString ScalarOperatorNode::toString(bool wl) const 0163 { 0164 QString op= ""; 0165 switch(m_arithmeticOperator) 0166 { 0167 case Dice::ArithmeticOperator::PLUS: 0168 op= "+"; 0169 break; 0170 case Dice::ArithmeticOperator::MINUS: 0171 op= "-"; 0172 break; 0173 case Dice::ArithmeticOperator::MULTIPLICATION: 0174 op= "*"; 0175 break; 0176 case Dice::ArithmeticOperator::DIVIDE: 0177 op= "/"; 0178 break; 0179 case Dice::ArithmeticOperator::INTEGER_DIVIDE: 0180 op= "|"; 0181 break; 0182 case Dice::ArithmeticOperator::POW: 0183 op= "^"; 0184 break; 0185 } 0186 if(wl) 0187 { 0188 return QString("%1 [label=\"ScalarOperatorNode %2\"]").arg(m_id, op); 0189 } 0190 else 0191 { 0192 return m_id; 0193 } 0194 } 0195 qint64 ScalarOperatorNode::getPriority() const 0196 { 0197 if((m_arithmeticOperator == Dice::ArithmeticOperator::PLUS) 0198 || (m_arithmeticOperator == Dice::ArithmeticOperator::MINUS)) 0199 { 0200 return 1; 0201 } 0202 else if(m_arithmeticOperator == Dice::ArithmeticOperator::POW) 0203 { 0204 return 3; 0205 } 0206 else 0207 { 0208 return 2; 0209 } 0210 } 0211 void ScalarOperatorNode::generateDotTree(QString& s) 0212 { 0213 auto id= toString(true); 0214 if(s.contains(id)) 0215 return; 0216 s.append(id); 0217 s.append(";\n"); 0218 0219 if(nullptr != m_nextNode) 0220 { 0221 s.append(toString(false)); 0222 s.append(" -> "); 0223 s.append(m_nextNode->toString(false)); 0224 s.append("[label=\"nextNode\"];\n"); 0225 m_nextNode->generateDotTree(s); 0226 } 0227 else 0228 { 0229 s.append(toString(false)); 0230 s.append(" -> "); 0231 s.append("nullptr"); 0232 s.append(" [label=\"nextNode\"];\n"); 0233 } 0234 0235 if(nullptr != m_result) 0236 { 0237 s.append(toString(false)); 0238 s.append(" ->"); 0239 s.append(m_result->toString(false)); 0240 s.append(" [label=\"Result\", style=\"dashed\"];\n"); 0241 if(nullptr == m_nextNode) 0242 m_result->generateDotTree(s); 0243 } 0244 QString str; 0245 str.append("\n"); 0246 if(nullptr != m_internalNode) 0247 { 0248 str.append(toString(false)); 0249 str.append(" -> "); 0250 str.append(m_internalNode->toString(false)); 0251 str.append(" [label=\"internalNode\"];\n"); 0252 m_internalNode->generateDotTree(str); 0253 } 0254 s.append(str); 0255 } 0256 QMap<Dice::ERROR_CODE, QString> ScalarOperatorNode::getExecutionErrorMap() 0257 { 0258 if(nullptr != m_internalNode) 0259 { 0260 auto keys= m_internalNode->getExecutionErrorMap().keys(); 0261 for(const auto& key : keys) 0262 { 0263 m_errors.insert(key, m_internalNode->getExecutionErrorMap().value(key)); 0264 } 0265 } 0266 if(nullptr != m_nextNode) 0267 { 0268 auto keys= m_nextNode->getExecutionErrorMap().keys(); 0269 for(auto const& key : keys) 0270 { 0271 m_errors.insert(key, m_nextNode->getExecutionErrorMap().value(key)); 0272 } 0273 } 0274 return m_errors; 0275 } 0276 ExecutionNode* ScalarOperatorNode::getCopy() const 0277 { 0278 ScalarOperatorNode* node= new ScalarOperatorNode(); 0279 node->setInternalNode(m_internalNode->getCopy()); 0280 node->setArithmeticOperator(m_arithmeticOperator); 0281 if(nullptr != m_nextNode) 0282 { 0283 node->setNextNode(m_nextNode->getCopy()); 0284 } 0285 return node; 0286 }