1 #include "operation.hpp"
2
3 #include <string>
4 #include <vector>
5
6 #include <QTimer>
7
8 #include "../world/universalid.hpp"
9
10 #include "stage.hpp"
11
prepareStages()12 void CSMDoc::Operation::prepareStages()
13 {
14 mCurrentStage = mStages.begin();
15 mCurrentStep = 0;
16 mCurrentStepTotal = 0;
17 mTotalSteps = 0;
18 mError = false;
19
20 for (std::vector<std::pair<Stage *, int> >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter)
21 {
22 iter->second = iter->first->setup();
23 mTotalSteps += iter->second;
24 }
25 }
26
Operation(int type,bool ordered,bool finalAlways)27 CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways)
28 : mType (type), mStages(std::vector<std::pair<Stage *, int> >()), mCurrentStage(mStages.begin()),
29 mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered),
30 mFinalAlways (finalAlways), mError(false), mConnected (false), mPrepared (false),
31 mDefaultSeverity (Message::Severity_Error)
32 {
33 mTimer = new QTimer (this);
34 }
35
~Operation()36 CSMDoc::Operation::~Operation()
37 {
38 for (std::vector<std::pair<Stage *, int> >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter)
39 delete iter->first;
40 }
41
run()42 void CSMDoc::Operation::run()
43 {
44 mTimer->stop();
45
46 if (!mConnected)
47 {
48 connect (mTimer, SIGNAL (timeout()), this, SLOT (executeStage()));
49 mConnected = true;
50 }
51
52 mPrepared = false;
53
54 mTimer->start (0);
55 }
56
appendStage(Stage * stage)57 void CSMDoc::Operation::appendStage (Stage *stage)
58 {
59 mStages.emplace_back (stage, 0);
60 }
61
setDefaultSeverity(Message::Severity severity)62 void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity)
63 {
64 mDefaultSeverity = severity;
65 }
66
hasError() const67 bool CSMDoc::Operation::hasError() const
68 {
69 return mError;
70 }
71
abort()72 void CSMDoc::Operation::abort()
73 {
74 if (!mTimer->isActive())
75 return;
76
77 mError = true;
78
79 if (mFinalAlways)
80 {
81 if (mStages.begin()!=mStages.end() && mCurrentStage!=--mStages.end())
82 {
83 mCurrentStep = 0;
84 mCurrentStage = --mStages.end();
85 }
86 }
87 else
88 mCurrentStage = mStages.end();
89 }
90
executeStage()91 void CSMDoc::Operation::executeStage()
92 {
93 if (!mPrepared)
94 {
95 prepareStages();
96 mPrepared = true;
97 }
98
99 Messages messages (mDefaultSeverity);
100
101 while (mCurrentStage!=mStages.end())
102 {
103 if (mCurrentStep>=mCurrentStage->second)
104 {
105 mCurrentStep = 0;
106 ++mCurrentStage;
107 }
108 else
109 {
110 try
111 {
112 mCurrentStage->first->perform (mCurrentStep++, messages);
113 }
114 catch (const std::exception& e)
115 {
116 emit reportMessage (Message (CSMWorld::UniversalId(), e.what(), "", Message::Severity_SeriousError), mType);
117 abort();
118 }
119
120 ++mCurrentStepTotal;
121 break;
122 }
123 }
124
125 emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
126
127 for (Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter)
128 emit reportMessage (*iter, mType);
129
130 if (mCurrentStage==mStages.end())
131 operationDone();
132 }
133
operationDone()134 void CSMDoc::Operation::operationDone()
135 {
136 mTimer->stop();
137 emit done (mType, mError);
138 }
139