File indexing completed on 2024-05-12 05:39:29
0001 /*************************************************************************** 0002 * Copyright (C) 2021 by Renaud Guezennec * 0003 * http://www.rolisteam.org/contact * 0004 * * 0005 * This software is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "switchcasenode.h" 0021 0022 #include "stringresult.h" 0023 #include <QDebug> 0024 #include <diceparser/parsingtoolbox.h> 0025 #include <memory> 0026 0027 SwitchCaseNode::SwitchCaseNode() : m_stringResult(new StringResult) 0028 { 0029 m_result= m_stringResult; 0030 } 0031 0032 void SwitchCaseNode::setStopAtFirt(bool b) 0033 { 0034 m_stopAtFirst= b; 0035 } 0036 0037 void SwitchCaseNode::run(ExecutionNode* previous) 0038 { 0039 m_previousNode= previous; 0040 if(nullptr == previous) 0041 { 0042 m_errors.insert(Dice::ERROR_CODE::NO_PREVIOUS_ERROR, 0043 QStringLiteral("No previous node before Switch/Case operator")); 0044 return; 0045 } 0046 auto previousResult= previous->getResult(); 0047 m_result->setPrevious(previousResult); 0048 0049 if(nullptr == previousResult 0050 || (!previousResult->hasResultOfType(Dice::RESULT_TYPE::SCALAR) 0051 && !previousResult->hasResultOfType(Dice::RESULT_TYPE::DICE_LIST))) 0052 { 0053 m_errors.insert(Dice::ERROR_CODE::NO_VALID_RESULT, 0054 QStringLiteral("No scalar or dice result before Switch/Case operator")); 0055 return; 0056 } 0057 0058 auto diceResult= dynamic_cast<DiceResult*>(previousResult); 0059 0060 QStringList finalResultList; 0061 if(diceResult) 0062 { 0063 for(auto die : diceResult->getResultList()) 0064 { 0065 QStringList resultList; 0066 for(auto const& info : qAsConst(m_branchList)) 0067 { 0068 if(m_stopAtFirst && !resultList.isEmpty()) 0069 break; 0070 if(info->validatorList) 0071 { 0072 if(info->validatorList->hasValid(die, true)) 0073 { 0074 auto lastNode= ParsingToolBox::getLeafNode(info->node); 0075 if(lastNode && lastNode->getResult()) 0076 { 0077 resultList << lastNode->getResult()->getStringResult(); 0078 } 0079 } 0080 } 0081 else if(resultList.isEmpty()) 0082 { 0083 info->node->run(m_previousNode); 0084 auto lastNode= ParsingToolBox::getLeafNode(info->node); 0085 if(lastNode && lastNode->getResult()) 0086 { 0087 resultList << lastNode->getResult()->getStringResult(); 0088 } 0089 else 0090 resultList << QString(); 0091 } 0092 } 0093 finalResultList << resultList; 0094 } 0095 } 0096 else 0097 { 0098 auto scalar= previousResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal(); 0099 for(auto const& info : qAsConst(m_branchList)) 0100 { 0101 if(m_stopAtFirst && !finalResultList.isEmpty()) 0102 break; 0103 0104 if(info->validatorList) 0105 { 0106 auto die= std::make_unique<Die>(); 0107 die->insertRollValue(scalar); 0108 if(info->validatorList->hasValid(die.get(), true)) 0109 { 0110 auto lastNode= ParsingToolBox::getLeafNode(info->node); 0111 if(lastNode && lastNode->getResult()) 0112 { 0113 finalResultList << lastNode->getResult()->getStringResult(); 0114 } 0115 } 0116 } 0117 else if(finalResultList.isEmpty()) 0118 { 0119 info->node->run(m_previousNode); 0120 auto lastNode= ParsingToolBox::getLeafNode(info->node); 0121 if(lastNode && lastNode->getResult()) 0122 { 0123 finalResultList << lastNode->getResult()->getStringResult(); 0124 } 0125 else 0126 finalResultList << QString(); 0127 } 0128 } 0129 } 0130 0131 for(auto const& str : qAsConst(finalResultList)) 0132 m_stringResult->addText(str); 0133 0134 if(m_stringResult->getText().isEmpty()) 0135 m_errors.insert(Dice::ERROR_CODE::NO_VALID_RESULT, QStringLiteral("No value fits the Switch/Case operator")); 0136 0137 if(nullptr != m_nextNode) 0138 { 0139 m_nextNode->run(this); 0140 } 0141 } 0142 0143 QString SwitchCaseNode::toString(bool withLabel) const 0144 { 0145 if(withLabel) 0146 { 0147 return QString("%1 [label=\"SwitchCaseNode\"]").arg(m_id); 0148 } 0149 else 0150 { 0151 return m_id; 0152 } 0153 } 0154 0155 qint64 SwitchCaseNode::getPriority() const 0156 { 0157 qint64 priority= 0; 0158 if(nullptr != m_previousNode) 0159 { 0160 priority= m_previousNode->getPriority(); 0161 } 0162 return priority; 0163 } 0164 0165 ExecutionNode* SwitchCaseNode::getCopy() const 0166 { 0167 SwitchCaseNode* node= new SwitchCaseNode(); 0168 for(auto const& info : qAsConst(m_branchList)) 0169 { 0170 node->insertCase(info->node, info->validatorList); 0171 } 0172 0173 if(nullptr != m_nextNode) 0174 { 0175 node->setNextNode(m_nextNode->getCopy()); 0176 } 0177 return node; 0178 } 0179 0180 void SwitchCaseNode::insertCase(ExecutionNode* node, ValidatorList* validator) 0181 { 0182 std::unique_ptr<Dice::CaseInfo> info(new Dice::CaseInfo{validator, node}); 0183 m_branchList.push_back(std::move(info)); 0184 }