2012-12-08 11:59:13 +01:00
|
|
|
#include "tools.hpp"
|
|
|
|
|
|
|
|
#include <QThreadPool>
|
|
|
|
|
2012-12-08 14:44:03 +01:00
|
|
|
#include "../doc/state.hpp"
|
2013-09-14 15:16:31 +02:00
|
|
|
#include "../doc/operation.hpp"
|
2014-07-21 12:15:21 +02:00
|
|
|
#include "../doc/document.hpp"
|
2012-12-08 11:59:13 +01:00
|
|
|
|
2012-12-08 23:27:59 +01:00
|
|
|
#include "../world/data.hpp"
|
2012-12-11 15:35:47 +01:00
|
|
|
#include "../world/universalid.hpp"
|
2012-12-08 23:27:59 +01:00
|
|
|
|
2012-12-11 15:35:47 +01:00
|
|
|
#include "reportmodel.hpp"
|
2012-12-08 23:27:59 +01:00
|
|
|
#include "mandatoryid.hpp"
|
2013-03-25 11:07:04 +01:00
|
|
|
#include "skillcheck.hpp"
|
2013-04-04 10:10:26 +02:00
|
|
|
#include "classcheck.hpp"
|
2013-04-04 10:39:43 +02:00
|
|
|
#include "factioncheck.hpp"
|
2013-04-06 17:35:36 +02:00
|
|
|
#include "racecheck.hpp"
|
2013-04-06 21:48:52 +02:00
|
|
|
#include "soundcheck.hpp"
|
2013-04-07 19:39:13 +02:00
|
|
|
#include "regioncheck.hpp"
|
2013-04-07 23:25:35 +02:00
|
|
|
#include "birthsigncheck.hpp"
|
2013-04-09 12:44:49 +02:00
|
|
|
#include "spellcheck.hpp"
|
2013-12-20 20:02:42 +01:00
|
|
|
#include "referenceablecheck.hpp"
|
2014-02-14 13:38:30 +01:00
|
|
|
#include "scriptcheck.hpp"
|
2014-08-26 21:55:31 +06:00
|
|
|
#include "bodypartcheck.hpp"
|
2015-02-13 04:11:36 +01:00
|
|
|
#include "referencecheck.hpp"
|
2015-03-05 11:24:01 +01:00
|
|
|
#include "startscriptcheck.hpp"
|
2015-03-27 16:33:54 +01:00
|
|
|
#include "searchoperation.hpp"
|
2015-05-27 22:12:11 +10:00
|
|
|
#include "pathgridcheck.hpp"
|
2015-06-13 19:08:31 +03:00
|
|
|
#include "soundgencheck.hpp"
|
2015-08-03 19:08:01 +03:00
|
|
|
#include "magiceffectcheck.hpp"
|
2015-08-13 12:03:20 +02:00
|
|
|
#include "mergeoperation.hpp"
|
2016-01-17 21:55:03 -05:00
|
|
|
#include "gmstcheck.hpp"
|
2016-02-17 15:38:30 -05:00
|
|
|
#include "topicinfocheck.hpp"
|
2016-02-22 17:01:15 -05:00
|
|
|
#include "journalcheck.hpp"
|
2018-08-30 01:21:27 +03:00
|
|
|
#include "enchantmentcheck.hpp"
|
2012-12-08 23:27:59 +01:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
CSMDoc::OperationHolder *CSMTools::Tools::get (int type)
|
2012-12-08 17:00:58 +01:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
2015-03-14 12:00:24 +01:00
|
|
|
case CSMDoc::State_Verifying: return &mVerifier;
|
2015-03-17 12:30:47 +01:00
|
|
|
case CSMDoc::State_Searching: return &mSearch;
|
2015-08-13 12:03:20 +02:00
|
|
|
case CSMDoc::State_Merging: return &mMerge;
|
2012-12-08 17:00:58 +01:00
|
|
|
}
|
|
|
|
|
2020-11-13 11:39:47 +04:00
|
|
|
return nullptr;
|
2012-12-08 17:00:58 +01:00
|
|
|
}
|
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
const CSMDoc::OperationHolder *CSMTools::Tools::get (int type) const
|
2012-12-08 17:00:58 +01:00
|
|
|
{
|
2013-12-30 18:41:16 +01:00
|
|
|
return const_cast<Tools *> (this)->get (type);
|
2012-12-08 17:00:58 +01:00
|
|
|
}
|
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
|
2012-12-08 11:59:13 +01:00
|
|
|
{
|
2015-03-14 12:00:24 +01:00
|
|
|
if (!mVerifierOperation)
|
2012-12-08 11:59:13 +01:00
|
|
|
{
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
|
2012-12-08 11:59:13 +01:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
|
|
|
connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
2015-06-20 17:56:42 +02:00
|
|
|
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
|
|
|
this, SLOT (verifierMessage (const CSMDoc::Message&, int)));
|
2012-12-08 23:27:59 +01:00
|
|
|
|
2018-05-03 19:56:01 +03:00
|
|
|
std::vector<std::string> mandatoryIds {"Day", "DaysPassed", "GameHour", "Month", "PCRace"};
|
2012-12-08 23:27:59 +01:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new MandatoryIdStage (mData.getGlobals(),
|
2013-12-30 18:41:16 +01:00
|
|
|
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
|
2013-03-25 11:07:04 +01:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new SkillCheckStage (mData.getSkills()));
|
2013-04-04 10:10:26 +02:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new ClassCheckStage (mData.getClasses()));
|
2013-04-04 10:39:43 +02:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new FactionCheckStage (mData.getFactions()));
|
2013-04-06 17:35:36 +02:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new RaceCheckStage (mData.getRaces()));
|
2013-04-06 21:48:52 +02:00
|
|
|
|
2018-08-25 00:47:38 +03:00
|
|
|
mVerifierOperation->appendStage (new SoundCheckStage (mData.getSounds(), mData.getResources (CSMWorld::UniversalId::Type_SoundsRes)));
|
2013-04-07 19:39:13 +02:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new RegionCheckStage (mData.getRegions()));
|
2013-04-07 23:25:35 +02:00
|
|
|
|
2018-08-24 17:37:07 +03:00
|
|
|
mVerifierOperation->appendStage (new BirthsignCheckStage (mData.getBirthsigns(), mData.getResources (CSMWorld::UniversalId::Type_Textures)));
|
2013-04-09 12:44:49 +02:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells()));
|
2013-12-30 13:23:16 +01:00
|
|
|
|
2018-08-25 01:22:41 +03:00
|
|
|
mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions(), mData.getScripts(),
|
2018-08-26 13:00:39 +03:00
|
|
|
mData.getResources (CSMWorld::UniversalId::Type_Meshes), mData.getResources (CSMWorld::UniversalId::Type_Icons),
|
|
|
|
mData.getBodyParts()));
|
2014-02-14 13:38:30 +01:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions()));
|
2015-02-13 04:11:36 +01:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new ScriptCheckStage (mDocument));
|
2014-08-26 21:55:31 +06:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage (new StartScriptCheckStage (mData.getStartScripts(), mData.getScripts()));
|
2015-03-05 11:24:01 +01:00
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifierOperation->appendStage(
|
2014-08-26 21:55:31 +06:00
|
|
|
new BodyPartCheckStage(
|
|
|
|
mData.getBodyParts(),
|
|
|
|
mData.getResources(
|
|
|
|
CSMWorld::UniversalId( CSMWorld::UniversalId::Type_Meshes )),
|
|
|
|
mData.getRaces() ));
|
2015-03-14 12:00:24 +01:00
|
|
|
|
2015-05-27 22:12:11 +10:00
|
|
|
mVerifierOperation->appendStage (new PathgridCheckStage (mData.getPathgrids()));
|
|
|
|
|
2015-06-13 19:08:31 +03:00
|
|
|
mVerifierOperation->appendStage (new SoundGenCheckStage (mData.getSoundGens(),
|
|
|
|
mData.getSounds(),
|
|
|
|
mData.getReferenceables()));
|
|
|
|
|
2015-08-03 19:08:01 +03:00
|
|
|
mVerifierOperation->appendStage (new MagicEffectCheckStage (mData.getMagicEffects(),
|
|
|
|
mData.getSounds(),
|
|
|
|
mData.getReferenceables(),
|
|
|
|
mData.getResources (CSMWorld::UniversalId::Type_Icons),
|
|
|
|
mData.getResources (CSMWorld::UniversalId::Type_Textures)));
|
2016-02-17 15:38:30 -05:00
|
|
|
|
2016-01-18 12:34:33 -05:00
|
|
|
mVerifierOperation->appendStage (new GmstCheckStage (mData.getGmsts()));
|
2015-08-03 19:08:01 +03:00
|
|
|
|
2016-02-17 15:38:30 -05:00
|
|
|
mVerifierOperation->appendStage (new TopicInfoCheckStage (mData.getTopicInfos(),
|
|
|
|
mData.getCells(),
|
|
|
|
mData.getClasses(),
|
|
|
|
mData.getFactions(),
|
|
|
|
mData.getGmsts(),
|
|
|
|
mData.getGlobals(),
|
|
|
|
mData.getJournals(),
|
|
|
|
mData.getRaces(),
|
|
|
|
mData.getRegions(),
|
|
|
|
mData.getTopics(),
|
|
|
|
mData.getReferenceables().getDataSet(),
|
|
|
|
mData.getResources (CSMWorld::UniversalId::Type_SoundsRes)));
|
|
|
|
|
2016-02-22 17:01:15 -05:00
|
|
|
mVerifierOperation->appendStage (new JournalCheckStage(mData.getJournals(), mData.getJournalInfos()));
|
|
|
|
|
2018-08-30 01:21:27 +03:00
|
|
|
mVerifierOperation->appendStage (new EnchantmentCheckStage(mData.getEnchantments()));
|
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
mVerifier.setOperation (mVerifierOperation);
|
2012-12-08 11:59:13 +01:00
|
|
|
}
|
|
|
|
|
2015-03-14 12:00:24 +01:00
|
|
|
return &mVerifier;
|
2012-12-08 11:59:13 +01:00
|
|
|
}
|
|
|
|
|
2015-08-16 18:27:17 +02:00
|
|
|
CSMTools::Tools::Tools (CSMDoc::Document& document, ToUTF8::FromType encoding)
|
2020-11-13 11:39:47 +04:00
|
|
|
: mDocument (document), mData (document.getData()), mVerifierOperation (nullptr),
|
|
|
|
mSearchOperation (nullptr), mMergeOperation (nullptr), mNextReportNumber (0), mEncoding (encoding)
|
2012-12-08 11:59:13 +01:00
|
|
|
{
|
2014-05-10 12:04:36 +02:00
|
|
|
// index 0: load error log
|
|
|
|
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
|
|
|
mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0));
|
2015-03-27 16:33:54 +01:00
|
|
|
|
|
|
|
connect (&mSearch, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
|
|
|
connect (&mSearch, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
2015-06-20 17:56:42 +02:00
|
|
|
connect (&mSearch, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
|
|
|
this, SLOT (verifierMessage (const CSMDoc::Message&, int)));
|
2015-08-13 14:49:32 +02:00
|
|
|
|
|
|
|
connect (&mMerge, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
|
|
|
connect (&mMerge, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
|
|
|
// don't need to connect report message, since there are no messages for merge
|
2012-12-08 11:59:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
CSMTools::Tools::~Tools()
|
|
|
|
{
|
2015-03-14 12:00:24 +01:00
|
|
|
if (mVerifierOperation)
|
|
|
|
{
|
|
|
|
mVerifier.abortAndWait();
|
|
|
|
delete mVerifierOperation;
|
|
|
|
}
|
2014-05-06 11:44:20 +02:00
|
|
|
|
2015-03-17 12:30:47 +01:00
|
|
|
if (mSearchOperation)
|
|
|
|
{
|
|
|
|
mSearch.abortAndWait();
|
|
|
|
delete mSearchOperation;
|
|
|
|
}
|
2015-05-27 15:55:00 +10:00
|
|
|
|
2015-08-13 12:03:20 +02:00
|
|
|
if (mMergeOperation)
|
|
|
|
{
|
|
|
|
mMerge.abortAndWait();
|
|
|
|
delete mMergeOperation;
|
|
|
|
}
|
|
|
|
|
2014-05-06 11:44:20 +02:00
|
|
|
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
|
|
|
|
delete iter->second;
|
2012-12-08 11:59:13 +01:00
|
|
|
}
|
|
|
|
|
2015-06-25 12:03:40 +02:00
|
|
|
CSMWorld::UniversalId CSMTools::Tools::runVerifier (const CSMWorld::UniversalId& reportId)
|
2012-12-08 11:59:13 +01:00
|
|
|
{
|
2015-06-25 12:03:40 +02:00
|
|
|
int reportNumber = reportId.getType()==CSMWorld::UniversalId::Type_VerificationResults ?
|
|
|
|
reportId.getIndex() : mNextReportNumber++;
|
|
|
|
|
|
|
|
if (mReports.find (reportNumber)==mReports.end())
|
|
|
|
mReports.insert (std::make_pair (reportNumber, new ReportModel));
|
2015-08-13 12:03:20 +02:00
|
|
|
|
2015-06-25 12:03:40 +02:00
|
|
|
mActiveReports[CSMDoc::State_Verifying] = reportNumber;
|
2012-12-11 15:35:47 +01:00
|
|
|
|
2012-12-08 11:59:13 +01:00
|
|
|
getVerifier()->start();
|
2012-12-11 15:35:47 +01:00
|
|
|
|
2015-06-25 12:03:40 +02:00
|
|
|
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, reportNumber);
|
2012-12-08 11:59:13 +01:00
|
|
|
}
|
|
|
|
|
2015-03-17 12:30:47 +01:00
|
|
|
CSMWorld::UniversalId CSMTools::Tools::newSearch()
|
|
|
|
{
|
2015-06-20 19:04:19 +02:00
|
|
|
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel (true, false)));
|
2015-03-17 12:30:47 +01:00
|
|
|
|
2015-05-27 15:55:00 +10:00
|
|
|
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Search, mNextReportNumber-1);
|
2015-03-17 12:30:47 +01:00
|
|
|
}
|
|
|
|
|
2015-03-27 16:33:54 +01:00
|
|
|
void CSMTools::Tools::runSearch (const CSMWorld::UniversalId& searchId, const Search& search)
|
|
|
|
{
|
|
|
|
mActiveReports[CSMDoc::State_Searching] = searchId.getIndex();
|
|
|
|
|
|
|
|
if (!mSearchOperation)
|
|
|
|
{
|
|
|
|
mSearchOperation = new SearchOperation (mDocument);
|
2015-05-27 15:55:00 +10:00
|
|
|
mSearch.setOperation (mSearchOperation);
|
2015-03-27 16:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mSearchOperation->configure (search);
|
2015-05-27 15:55:00 +10:00
|
|
|
|
2015-03-27 16:33:54 +01:00
|
|
|
mSearch.start();
|
|
|
|
}
|
|
|
|
|
2017-04-28 17:30:26 +02:00
|
|
|
void CSMTools::Tools::runMerge (std::unique_ptr<CSMDoc::Document> target)
|
2015-08-13 12:03:20 +02:00
|
|
|
{
|
|
|
|
// not setting an active report, because merge does not produce messages
|
|
|
|
|
|
|
|
if (!mMergeOperation)
|
|
|
|
{
|
2015-08-16 18:27:17 +02:00
|
|
|
mMergeOperation = new MergeOperation (mDocument, mEncoding);
|
2015-08-13 12:03:20 +02:00
|
|
|
mMerge.setOperation (mMergeOperation);
|
2015-08-16 15:24:48 +02:00
|
|
|
connect (mMergeOperation, SIGNAL (mergeDone (CSMDoc::Document*)),
|
|
|
|
this, SIGNAL (mergeDone (CSMDoc::Document*)));
|
2015-08-13 12:03:20 +02:00
|
|
|
}
|
|
|
|
|
2015-08-23 12:37:45 +02:00
|
|
|
target->flagAsDirty();
|
|
|
|
|
2017-04-28 17:30:26 +02:00
|
|
|
mMergeOperation->setTarget (std::move(target));
|
2015-08-13 12:03:20 +02:00
|
|
|
|
|
|
|
mMerge.start();
|
|
|
|
}
|
|
|
|
|
2013-12-30 18:41:16 +01:00
|
|
|
void CSMTools::Tools::abortOperation (int type)
|
2012-12-08 11:59:13 +01:00
|
|
|
{
|
2015-03-14 12:00:24 +01:00
|
|
|
if (CSMDoc::OperationHolder *operation = get (type))
|
2012-12-08 17:00:58 +01:00
|
|
|
operation->abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
int CSMTools::Tools::getRunningOperations() const
|
|
|
|
{
|
|
|
|
static const int sOperations[] =
|
|
|
|
{
|
2013-12-30 18:41:16 +01:00
|
|
|
CSMDoc::State_Verifying,
|
2015-03-17 12:30:47 +01:00
|
|
|
CSMDoc::State_Searching,
|
2015-08-13 12:03:20 +02:00
|
|
|
CSMDoc::State_Merging,
|
2012-12-08 17:00:58 +01:00
|
|
|
-1
|
|
|
|
};
|
|
|
|
|
|
|
|
int result = 0;
|
|
|
|
|
2013-12-30 18:41:16 +01:00
|
|
|
for (int i=0; sOperations[i]!=-1; ++i)
|
2015-03-14 12:00:24 +01:00
|
|
|
if (const CSMDoc::OperationHolder *operation = get (sOperations[i]))
|
2012-12-08 17:00:58 +01:00
|
|
|
if (operation->isRunning())
|
|
|
|
result |= sOperations[i];
|
2012-12-08 11:59:13 +01:00
|
|
|
|
2012-12-08 17:00:58 +01:00
|
|
|
return result;
|
2012-12-08 11:59:13 +01:00
|
|
|
}
|
|
|
|
|
2013-12-30 18:41:16 +01:00
|
|
|
CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id)
|
2012-12-11 15:35:47 +01:00
|
|
|
{
|
2014-05-10 12:04:36 +02:00
|
|
|
if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults &&
|
2015-03-17 12:30:47 +01:00
|
|
|
id.getType()!=CSMWorld::UniversalId::Type_LoadErrorLog &&
|
|
|
|
id.getType()!=CSMWorld::UniversalId::Type_Search)
|
2013-12-30 18:41:16 +01:00
|
|
|
throw std::logic_error ("invalid request for report model: " + id.toString());
|
2015-05-27 15:55:00 +10:00
|
|
|
|
2013-12-30 18:41:16 +01:00
|
|
|
return mReports.at (id.getIndex());
|
2012-12-11 15:35:47 +01:00
|
|
|
}
|
|
|
|
|
2015-06-20 17:56:42 +02:00
|
|
|
void CSMTools::Tools::verifierMessage (const CSMDoc::Message& message, int type)
|
2012-12-08 18:38:36 +01:00
|
|
|
{
|
2013-12-30 18:41:16 +01:00
|
|
|
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
2012-12-08 18:38:36 +01:00
|
|
|
|
2013-12-30 18:41:16 +01:00
|
|
|
if (iter!=mActiveReports.end())
|
2015-06-20 17:56:42 +02:00
|
|
|
mReports[iter->second]->add (message);
|
2013-12-20 20:02:42 +01:00
|
|
|
}
|