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 }