aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/libparser/node/executionnode.cpp
blob: b231416e140c2e00f955bc643e4e84bef08551df (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "executionnode.h"

#include <QUuid>

namespace
{
#ifdef QT_DEBUG
constexpr int WaitingTime{2 * 1000 * 60};
#else
constexpr int WaitingTime{30 * 60 * 1000};
#endif

} // namespace

ExecutionNode::ExecutionNode()
    : m_previousNode(nullptr)
    , m_result(nullptr)
    , m_nextNode(nullptr)
    , m_errors(QMap<Dice::ERROR_CODE, QString>())
    , m_id(QString("\"%1\"").arg(QUuid::createUuid().toString()))
{
}
ExecutionNode::~ExecutionNode()
{
    if(nullptr != m_result)
    {
        delete m_result;
        m_result= nullptr;
    }
    if(nullptr != m_nextNode)
    {
        delete m_nextNode;
        m_nextNode= nullptr;
    }
}

Result* ExecutionNode::getResult()
{
    return m_result;
}
void ExecutionNode::setNextNode(ExecutionNode* node)
{
    m_nextNode= node;
}
void ExecutionNode::setPreviousNode(ExecutionNode* node)
{
    m_previousNode= node;
}
ExecutionNode* ExecutionNode::getNextNode()
{
    return m_nextNode;
}

void ExecutionNode::execute(ExecutionNode* previous)
{
    QElapsedTimer timer;
    timer.start();

    auto errorCount= m_errors.count();

    run(previous);

    auto timeLimit= timer.hasExpired(WaitingTime);

    if(m_nextNode && errorCount == m_errors.count() && !timeLimit)
        m_nextNode->execute(this);
    else if(timeLimit)
        qDebug() << "Error too long" << WaitingTime << timeLimit << timer.elapsed();
}

QMap<Dice::ERROR_CODE, QString> ExecutionNode::getExecutionErrorMap()
{
    if(nullptr != m_nextNode)
    {
        auto const& keys= m_nextNode->getExecutionErrorMap().keys();
        for(auto& key : keys)
        {
            m_errors.insert(key, m_nextNode->getExecutionErrorMap().value(key));
        }
    }
    return m_errors;
}
QString ExecutionNode::getHelp()
{
    return QString();
}
ExecutionNode* ExecutionNode::getPreviousNode() const
{
    return m_previousNode;
}
void ExecutionNode::generateDotTree(QString& s)
{
    auto str= toString(true);
    if(s.contains(str))
        return;
    s.append(toString(true));
    s.append(";\n");

    if(nullptr != m_nextNode)
    {
        s.append(toString(false));
        s.append(" -> ");
        s.append(m_nextNode->toString(false));
        s.append("[label=\"next\"];\n");
        //        s.append(" [label=\"nextNode\"];\n");
        m_nextNode->generateDotTree(s);
    }
    else
    {
        s.append(toString(false));
        s.append(" -> ");
        s.append("nullptr;\n");
    }
    if(nullptr != m_result)
    {
        s.append(toString(false));
        s.append(" ->");
        s.append(m_result->toString(false));
        s.append(" [label=\"Result\", style=\"dashed\"];\n");
        if(nullptr == m_nextNode)
            m_result->generateDotTree(s);
    }
}
qint64 ExecutionNode::getScalarResult()
{
    if(m_result == nullptr)
        return 0;
    return m_result->getResult(Dice::RESULT_TYPE::SCALAR).toInt();
}

bool ExecutionNode::isValid(bool condition, Dice::ERROR_CODE code, const QString& errorTxt, bool error)
{
    if(condition)
        error ? m_errors.insert(code, errorTxt) : m_warnings.insert(code, errorTxt);

    return condition;
}