1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-23 20:53:54 +00:00
openmw/apps/opencs/model/doc/operation.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

190 lines
4.3 KiB
C++
Raw Normal View History

2012-12-08 14:25:50 +00:00
#include "operation.hpp"
2022-10-19 17:02:00 +00:00
#include <algorithm>
#include <exception>
#include <vector>
2012-12-08 14:25:50 +00:00
#include <QTimer>
#include <components/debug/debuglog.hpp>
2022-10-19 17:02:00 +00:00
#include <apps/opencs/model/doc/messages.hpp>
#include "../world/universalid.hpp"
2012-12-08 16:53:45 +00:00
#include "stage.hpp"
namespace CSMDoc
{
namespace
{
std::string_view operationToString(State value)
{
switch (value)
{
case State_Saving:
return "Saving";
case State_Merging:
return "Merging";
case State_Verifying:
return "Verifying";
case State_Searching:
return "Searching";
case State_Loading:
return "Loading";
default:
break;
}
return "Unknown";
}
}
}
void CSMDoc::Operation::prepareStages()
2012-12-08 16:53:45 +00:00
{
mCurrentStage = mStages.begin();
mCurrentStep = 0;
mCurrentStepTotal = 0;
mTotalSteps = 0;
mError = false;
2012-12-08 16:53:45 +00:00
for (std::vector<std::pair<Stage*, int>>::iterator iter(mStages.begin()); iter != mStages.end(); ++iter)
{
2012-12-08 22:27:59 +00:00
iter->second = iter->first->setup();
mTotalSteps += iter->second;
2012-12-08 16:53:45 +00:00
}
}
CSMDoc::Operation::Operation(State type, bool ordered, bool finalAlways)
: mType(type)
, mStages(std::vector<std::pair<Stage*, int>>())
, mCurrentStage(mStages.begin())
, mCurrentStep(0)
, mCurrentStepTotal(0)
, mTotalSteps(0)
, mOrdered(ordered)
, mFinalAlways(finalAlways)
, mError(false)
, mConnected(false)
, mPrepared(false)
, mDefaultSeverity(Message::Severity_Error)
2013-09-15 09:35:12 +00:00
{
mTimer = new QTimer(this);
2013-09-15 09:35:12 +00:00
}
2012-12-08 14:25:50 +00:00
CSMDoc::Operation::~Operation()
2012-12-08 16:53:45 +00:00
{
for (std::vector<std::pair<Stage*, int>>::iterator iter(mStages.begin()); iter != mStages.end(); ++iter)
delete iter->first;
}
void CSMDoc::Operation::run()
2012-12-08 14:25:50 +00:00
{
mTimer->stop();
if (!mConnected)
{
connect(mTimer, &QTimer::timeout, this, &Operation::executeStage);
mConnected = true;
}
mPrepared = false;
mStart = std::chrono::steady_clock::now();
2012-12-08 14:25:50 +00:00
mTimer->start(0);
2012-12-08 14:25:50 +00:00
}
void CSMDoc::Operation::appendStage(Stage* stage)
2012-12-08 16:53:45 +00:00
{
2020-10-17 08:26:35 +00:00
mStages.emplace_back(stage, 0);
2012-12-08 16:53:45 +00:00
}
void CSMDoc::Operation::setDefaultSeverity(Message::Severity severity)
{
mDefaultSeverity = severity;
}
bool CSMDoc::Operation::hasError() const
{
return mError;
}
void CSMDoc::Operation::abort()
2012-12-08 14:25:50 +00:00
{
if (!mTimer->isActive())
return;
mError = true;
if (mFinalAlways)
{
if (mStages.begin() != mStages.end() && mCurrentStage != --mStages.end())
{
mCurrentStep = 0;
mCurrentStage = --mStages.end();
}
}
else
mCurrentStage = mStages.end();
2012-12-08 14:25:50 +00:00
}
2013-09-15 07:32:20 +00:00
void CSMDoc::Operation::executeStage()
2012-12-08 14:25:50 +00:00
{
if (!mPrepared)
{
prepareStages();
mPrepared = true;
}
Messages messages(mDefaultSeverity);
2012-12-08 16:53:45 +00:00
while (mCurrentStage != mStages.end())
{
if (mCurrentStep >= mCurrentStage->second)
{
mCurrentStep = 0;
++mCurrentStage;
}
else
{
try
{
mCurrentStage->first->perform(mCurrentStep++, messages);
}
catch (const std::exception& e)
{
emit reportMessage(
Message(CSMWorld::UniversalId(), e.what(), "", Message::Severity_SeriousError), mType);
abort();
}
2012-12-08 16:53:45 +00:00
++mCurrentStepTotal;
break;
}
}
emit progress(mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
2012-12-08 14:25:50 +00:00
for (Messages::Iterator iter(messages.begin()); iter != messages.end(); ++iter)
emit reportMessage(*iter, mType);
2012-12-08 16:53:45 +00:00
if (mCurrentStage == mStages.end())
{
if (mStart.has_value())
{
const auto duration = std::chrono::steady_clock::now() - *mStart;
Log(Debug::Verbose) << operationToString(mType) << " operation is completed in "
<< std::chrono::duration_cast<std::chrono::duration<double>>(duration).count() << 's';
mStart.reset();
}
operationDone();
}
2013-09-15 09:35:12 +00:00
}
void CSMDoc::Operation::operationDone()
{
mTimer->stop();
emit done(mType, mError);
}