1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-04 02:41:19 +00:00
OpenMW/apps/opencs/model/doc/loader.cpp

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

164 lines
4.4 KiB
C++
Raw Normal View History

2014-04-24 13:09:25 +00:00
#include "loader.hpp"
2022-10-19 17:02:00 +00:00
#include <algorithm>
#include <exception>
#include <filesystem>
#include <apps/opencs/model/doc/messages.hpp>
#include <apps/opencs/model/world/data.hpp>
#include <apps/opencs/model/world/universalid.hpp>
#include <components/debug/debuglog.hpp>
#include <components/files/conversion.hpp>
2022-10-09 10:39:43 +00:00
#include <QTimer>
2014-04-24 13:09:25 +00:00
2014-05-10 10:04:36 +00:00
#include "../tools/reportmodel.hpp"
2014-04-24 13:09:25 +00:00
#include "document.hpp"
CSMDoc::Loader::Loader()
: mShouldStop(false)
2014-04-24 13:09:25 +00:00
{
mTimer = new QTimer(this);
2014-04-24 13:09:25 +00:00
connect(mTimer, &QTimer::timeout, this, &Loader::load);
mTimer->start();
2014-04-24 13:09:25 +00:00
}
QWaitCondition& CSMDoc::Loader::hasThingsToDo()
{
return mThingsToDo;
}
void CSMDoc::Loader::stop()
{
mShouldStop = true;
}
2014-04-24 13:09:25 +00:00
void CSMDoc::Loader::load()
{
if (mDocuments.empty())
{
mMutex.lock();
mThingsToDo.wait(&mMutex);
mMutex.unlock();
if (mShouldStop)
mTimer->stop();
2014-04-24 13:09:25 +00:00
return;
}
if (!mStart.has_value())
mStart = std::chrono::steady_clock::now();
std::vector<std::pair<Document*, Stage>>::iterator iter = mDocuments.begin();
2014-04-24 13:09:25 +00:00
Document* document = iter->first;
int size = static_cast<int>(document->getContentFiles().size());
int editedIndex = size - 1; // index of the file to be edited/created
if (document->isNew())
--size;
bool done = false;
2014-04-24 13:09:25 +00:00
try
{
if (iter->second.mRecordsLeft)
{
Messages messages(Message::Severity_Error);
2016-01-03 17:20:34 +00:00
const int batchingSize = 50;
2014-05-03 13:33:35 +00:00
for (int i = 0; i < batchingSize; ++i) // do not flood the system with update signals
2014-05-10 10:04:36 +00:00
if (document->getData().continueLoading(messages))
2014-05-03 13:33:35 +00:00
{
iter->second.mRecordsLeft = false;
break;
}
2014-06-26 09:41:21 +00:00
else
++(iter->second.mRecordsLoaded);
2014-05-03 13:33:35 +00:00
2014-05-10 10:04:36 +00:00
CSMWorld::UniversalId log(CSMWorld::UniversalId::Type_LoadErrorLog, 0);
2014-06-26 09:41:21 +00:00
{ // silence a g++ warning
2016-10-15 16:34:54 +00:00
for (CSMDoc::Messages::Iterator messageIter(messages.begin()); messageIter != messages.end();
++messageIter)
{
2016-10-15 16:34:54 +00:00
document->getReport(log)->add(*messageIter);
emit loadMessage(document, messageIter->mMessage);
}
2014-06-26 09:41:21 +00:00
}
2014-05-10 10:04:36 +00:00
2014-06-26 09:41:21 +00:00
emit nextRecord(document, iter->second.mRecordsLoaded);
return;
}
if (iter->second.mFile < size) // start loading the files
{
2024-05-19 16:55:37 +00:00
const std::filesystem::path& path = document->getContentFiles()[iter->second.mFile];
2014-05-03 11:01:29 +00:00
int steps = document->getData().startLoading(path, iter->second.mFile != editedIndex, /*project*/ false);
iter->second.mRecordsLeft = true;
2014-06-26 09:41:21 +00:00
iter->second.mRecordsLoaded = 0;
2014-05-03 13:33:35 +00:00
emit nextStage(document, Files::pathToUnicodeString(path.filename()), steps);
}
else if (iter->second.mFile == size) // start loading the last (project) file
{
int steps = document->getData().startLoading(document->getProjectPath(), /*base*/ false, true);
iter->second.mRecordsLeft = true;
2014-06-26 09:41:21 +00:00
iter->second.mRecordsLoaded = 0;
2014-05-03 13:33:35 +00:00
2014-06-26 09:41:21 +00:00
emit nextStage(document, "Project File", steps);
}
else
{
document->getData().finishLoading();
done = true;
}
++(iter->second.mFile);
2014-04-24 13:09:25 +00:00
}
catch (const std::exception& e)
{
mDocuments.erase(iter);
2014-04-24 13:09:25 +00:00
emit documentNotLoaded(document, e.what());
return;
}
if (done)
{
if (mStart.has_value())
{
const auto duration = std::chrono::steady_clock::now() - *mStart;
Log(Debug::Verbose) << "Loaded content files in "
<< std::chrono::duration_cast<std::chrono::duration<double>>(duration).count() << 's';
mStart.reset();
}
mDocuments.erase(iter);
emit documentLoaded(document);
2014-04-24 13:09:25 +00:00
}
}
void CSMDoc::Loader::loadDocument(CSMDoc::Document* document)
2014-04-24 13:09:25 +00:00
{
2020-10-17 08:26:35 +00:00
mDocuments.emplace_back(document, Stage());
2014-04-24 13:09:25 +00:00
}
2014-05-03 14:44:50 +00:00
void CSMDoc::Loader::abortLoading(CSMDoc::Document* document)
2014-04-24 13:09:25 +00:00
{
for (std::vector<std::pair<Document*, Stage>>::iterator iter = mDocuments.begin(); iter != mDocuments.end(); ++iter)
2014-04-24 13:09:25 +00:00
{
if (iter->first == document)
{
mDocuments.erase(iter);
emit documentNotLoaded(document, "");
break;
}
}
2014-05-03 14:44:50 +00:00
}