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 "mergenode.h"
0023 
0024 #include <diceparser/parsingtoolbox.h>
0025 
0026 MergeNode::MergeNode() : m_diceResult(new DiceResult())
0027 {
0028     m_result= m_diceResult;
0029 }
0030 void MergeNode::run(ExecutionNode* previous)
0031 {
0032     if(nullptr == previous)
0033     {
0034         m_errors.insert(Dice::ERROR_CODE::NO_PREVIOUS_ERROR, QObject::tr("No previous node before Merge operator"));
0035         return;
0036     }
0037 
0038     m_previousNode= previous;
0039     m_result->setPrevious(previous->getResult());
0040     ExecutionNode* previousLast= nullptr;
0041     std::vector<Result*> pastResult;
0042     for(auto start : *m_startList)
0043     {
0044         ExecutionNode* last= getLatestNode(start);
0045         if(nullptr == last || nullptr == previousLast)
0046         {
0047             previousLast= last;
0048             continue;
0049         }
0050 
0051         auto startResult= start->getResult();
0052         if(nullptr == startResult)
0053             continue;
0054 
0055         startResult->setPrevious(previousLast->getResult());
0056         previousLast->setNextNode(start);
0057 
0058         previousLast= last;
0059         Result* tmpResult= last->getResult();
0060         while(nullptr != tmpResult)
0061         {
0062             DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult);
0063             if(nullptr != dice)
0064             {
0065                 ///@todo TODO improve here to set homogeneous while is really
0066                 m_diceResult->setHomogeneous(false);
0067                 for(auto& die : dice->getResultList())
0068                 {
0069                     if(!m_diceResult->getResultList().contains(die) && (!die->hasBeenDisplayed()))
0070                     {
0071                         Die* tmpdie= new Die(*die);
0072                         die->displayed();
0073                         m_diceResult->getResultList().append(tmpdie);
0074                     }
0075                 }
0076             }
0077             auto it= std::find_if(pastResult.begin(), pastResult.end(),
0078                                   [tmpResult](const Result* a) { return (a == tmpResult->getPrevious()); });
0079             if(it == pastResult.end())
0080             {
0081                 pastResult.push_back(previousLast->getResult());
0082                 tmpResult= tmpResult->getPrevious();
0083             }
0084             else
0085             {
0086                 tmpResult->setPrevious(nullptr);
0087                 tmpResult= nullptr;
0088             }
0089         }
0090     }
0091 
0092     auto first= m_startList->front();
0093     m_startList->clear();
0094     m_startList->push_back(first);
0095 
0096     if(nullptr != m_nextNode)
0097     {
0098         m_nextNode->run(this);
0099     }
0100 }
0101 #include <QDebug>
0102 ExecutionNode* MergeNode::getLatestNode(ExecutionNode* node)
0103 {
0104     ExecutionNode* next= node;
0105     while(nullptr != next->getNextNode() && (next->getNextNode() != this))
0106     {
0107         // qDebug() << "find latest node" << next->toString(true) << next->getNextNode()->toString(true);
0108         next= next->getNextNode();
0109     }
0110     return next;
0111 }
0112 QString MergeNode::toString(bool withLabel) const
0113 {
0114     if(withLabel)
0115     {
0116         return QString("%1 [label=\"Merge Node\"]").arg(m_id);
0117     }
0118     else
0119     {
0120         return m_id;
0121     }
0122 }
0123 qint64 MergeNode::getPriority() const
0124 {
0125     qint64 priority= 0;
0126     if(nullptr != m_previousNode)
0127     {
0128         priority= m_previousNode->getPriority();
0129     }
0130     return priority;
0131 }
0132 ExecutionNode* MergeNode::getCopy() const
0133 {
0134     MergeNode* node= new MergeNode();
0135     if(nullptr != m_nextNode)
0136     {
0137         node->setNextNode(m_nextNode->getCopy());
0138     }
0139     return node;
0140 }
0141 
0142 std::vector<ExecutionNode*>* MergeNode::getStartList() const
0143 {
0144     return m_startList;
0145 }
0146 
0147 void MergeNode::setStartList(std::vector<ExecutionNode*>* startList)
0148 {
0149     m_startList= startList;
0150 }