1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-04-02 16:06:39 +00:00

split up load function in a start and continue part

This commit is contained in:
Marc Zinnschlag 2014-05-03 15:05:02 +02:00
parent 0b309d9ef4
commit 6692d2dc72
4 changed files with 187 additions and 141 deletions

View file

@ -5,7 +5,7 @@
#include "document.hpp" #include "document.hpp"
CSMDoc::Loader::Stage::Stage() : mFile (0) {} CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLeft (false) {}
CSMDoc::Loader::Loader() CSMDoc::Loader::Loader()
@ -13,7 +13,7 @@ CSMDoc::Loader::Loader()
QTimer *timer = new QTimer (this); QTimer *timer = new QTimer (this);
connect (timer, SIGNAL (timeout()), this, SLOT (load())); connect (timer, SIGNAL (timeout()), this, SLOT (load()));
timer->start (1000); timer->start();
} }
QWaitCondition& CSMDoc::Loader::hasThingsToDo() QWaitCondition& CSMDoc::Loader::hasThingsToDo()
@ -44,19 +44,29 @@ void CSMDoc::Loader::load()
try try
{ {
if (iter->second.mRecordsLeft)
{
if (document->getData().continueLoading())
iter->second.mRecordsLeft = false;
return;
}
if (iter->second.mFile<size) if (iter->second.mFile<size)
{ {
boost::filesystem::path path = document->getContentFiles()[iter->second.mFile]; boost::filesystem::path path = document->getContentFiles()[iter->second.mFile];
emit nextStage (document, path.filename().string()); emit nextStage (document, path.filename().string());
document->getData().loadFile (path, iter->second.mFile<size-1, false); document->getData().startLoading (path, iter->second.mFile<size-1, false);
iter->second.mRecordsLeft = true;
} }
else if (iter->second.mFile==size) else if (iter->second.mFile==size)
{ {
emit nextStage (document, "Project File"); emit nextStage (document, "Project File");
document->getData().loadFile (document->getProjectPath(), false, true); document->getData().startLoading (document->getProjectPath(), false, true);
iter->second.mRecordsLeft = true;
} }
else else
{ {

View file

@ -18,6 +18,7 @@ namespace CSMDoc
struct Stage struct Stage
{ {
int mFile; int mFile;
bool mRecordsLeft;
Stage(); Stage();
}; };

View file

@ -55,7 +55,10 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
return number; return number;
} }
CSMWorld::Data::Data() : mRefs (mCells) CSMWorld::Data::Data()
/// \todo set encoding properly, once config implementation has been fixed.
: mEncoder (ToUTF8::calculateEncoding ("win1252")),
mRefs (mCells), mReader (0), mDialogue (0)
{ {
mGlobals.addColumn (new StringIdColumn<ESM::Global>); mGlobals.addColumn (new StringIdColumn<ESM::Global>);
mGlobals.addColumn (new RecordStateColumn<ESM::Global>); mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
@ -260,6 +263,8 @@ CSMWorld::Data::~Data()
{ {
for (std::vector<QAbstractItemModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter) for (std::vector<QAbstractItemModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
delete *iter; delete *iter;
delete mReader;
} }
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
@ -481,87 +486,100 @@ void CSMWorld::Data::merge()
mGlobals.merge(); mGlobals.merge();
} }
void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, bool project) int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base, bool project)
{ {
ESM::ESMReader reader; delete mReader;
mReader = 0;
mDialogue = 0;
/// \todo set encoding properly, once config implementation has been fixed. mReader = new ESM::ESMReader;
ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding ("win1252")); mReader->setEncoder (&mEncoder);
reader.setEncoder (&encoder); mReader->open (path.string());
reader.open (path.string()); mBase = base;
mProject = project;
const ESM::Dialogue *dialogue = 0; mAuthor = mReader->getAuthor();
mDescription = mReader->getDesc();
mAuthor = reader.getAuthor(); return mReader->getRecordCount();
mDescription = reader.getDesc(); }
// Note: We do not need to send update signals here, because at this point the model is not connected bool CSMWorld::Data::continueLoading()
// to any view. {
while (reader.hasMoreRecs()) if (!mReader)
throw std::logic_error ("can't continue loading, because no load has been started");
if (!mReader->hasMoreRecs())
{ {
ESM::NAME n = reader.getRecName(); delete mReader;
reader.getRecHeader(); mReader = 0;
mDialogue = 0;
return true;
}
ESM::NAME n = mReader->getRecName();
mReader->getRecHeader();
switch (n.val) switch (n.val)
{ {
case ESM::REC_GLOB: mGlobals.load (reader, base); break; case ESM::REC_GLOB: mGlobals.load (*mReader, mBase); break;
case ESM::REC_GMST: mGmsts.load (reader, base); break; case ESM::REC_GMST: mGmsts.load (*mReader, mBase); break;
case ESM::REC_SKIL: mSkills.load (reader, base); break; case ESM::REC_SKIL: mSkills.load (*mReader, mBase); break;
case ESM::REC_CLAS: mClasses.load (reader, base); break; case ESM::REC_CLAS: mClasses.load (*mReader, mBase); break;
case ESM::REC_FACT: mFactions.load (reader, base); break; case ESM::REC_FACT: mFactions.load (*mReader, mBase); break;
case ESM::REC_RACE: mRaces.load (reader, base); break; case ESM::REC_RACE: mRaces.load (*mReader, mBase); break;
case ESM::REC_SOUN: mSounds.load (reader, base); break; case ESM::REC_SOUN: mSounds.load (*mReader, mBase); break;
case ESM::REC_SCPT: mScripts.load (reader, base); break; case ESM::REC_SCPT: mScripts.load (*mReader, mBase); break;
case ESM::REC_REGN: mRegions.load (reader, base); break; case ESM::REC_REGN: mRegions.load (*mReader, mBase); break;
case ESM::REC_BSGN: mBirthsigns.load (reader, base); break; case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break;
case ESM::REC_SPEL: mSpells.load (reader, base); break; case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break;
case ESM::REC_CELL: case ESM::REC_CELL:
mCells.load (reader, base); mCells.load (*mReader, mBase);
mRefs.load (reader, mCells.getSize()-1, base); mRefs.load (*mReader, mCells.getSize()-1, mBase);
break; break;
case ESM::REC_ACTI: mReferenceables.load (reader, base, UniversalId::Type_Activator); break; case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break;
case ESM::REC_ALCH: mReferenceables.load (reader, base, UniversalId::Type_Potion); break; case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break;
case ESM::REC_APPA: mReferenceables.load (reader, base, UniversalId::Type_Apparatus); break; case ESM::REC_APPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Apparatus); break;
case ESM::REC_ARMO: mReferenceables.load (reader, base, UniversalId::Type_Armor); break; case ESM::REC_ARMO: mReferenceables.load (*mReader, mBase, UniversalId::Type_Armor); break;
case ESM::REC_BOOK: mReferenceables.load (reader, base, UniversalId::Type_Book); break; case ESM::REC_BOOK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Book); break;
case ESM::REC_CLOT: mReferenceables.load (reader, base, UniversalId::Type_Clothing); break; case ESM::REC_CLOT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Clothing); break;
case ESM::REC_CONT: mReferenceables.load (reader, base, UniversalId::Type_Container); break; case ESM::REC_CONT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Container); break;
case ESM::REC_CREA: mReferenceables.load (reader, base, UniversalId::Type_Creature); break; case ESM::REC_CREA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Creature); break;
case ESM::REC_DOOR: mReferenceables.load (reader, base, UniversalId::Type_Door); break; case ESM::REC_DOOR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Door); break;
case ESM::REC_INGR: mReferenceables.load (reader, base, UniversalId::Type_Ingredient); break; case ESM::REC_INGR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Ingredient); break;
case ESM::REC_LEVC: case ESM::REC_LEVC:
mReferenceables.load (reader, base, UniversalId::Type_CreatureLevelledList); break; mReferenceables.load (*mReader, mBase, UniversalId::Type_CreatureLevelledList); break;
case ESM::REC_LEVI: case ESM::REC_LEVI:
mReferenceables.load (reader, base, UniversalId::Type_ItemLevelledList); break; mReferenceables.load (*mReader, mBase, UniversalId::Type_ItemLevelledList); break;
case ESM::REC_LIGH: mReferenceables.load (reader, base, UniversalId::Type_Light); break; case ESM::REC_LIGH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Light); break;
case ESM::REC_LOCK: mReferenceables.load (reader, base, UniversalId::Type_Lockpick); break; case ESM::REC_LOCK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Lockpick); break;
case ESM::REC_MISC: case ESM::REC_MISC:
mReferenceables.load (reader, base, UniversalId::Type_Miscellaneous); break; mReferenceables.load (*mReader, mBase, UniversalId::Type_Miscellaneous); break;
case ESM::REC_NPC_: mReferenceables.load (reader, base, UniversalId::Type_Npc); break; case ESM::REC_NPC_: mReferenceables.load (*mReader, mBase, UniversalId::Type_Npc); break;
case ESM::REC_PROB: mReferenceables.load (reader, base, UniversalId::Type_Probe); break; case ESM::REC_PROB: mReferenceables.load (*mReader, mBase, UniversalId::Type_Probe); break;
case ESM::REC_REPA: mReferenceables.load (reader, base, UniversalId::Type_Repair); break; case ESM::REC_REPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Repair); break;
case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; case ESM::REC_STAT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Static); break;
case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break; case ESM::REC_WEAP: mReferenceables.load (*mReader, mBase, UniversalId::Type_Weapon); break;
case ESM::REC_DIAL: case ESM::REC_DIAL:
{ {
std::string id = reader.getHNOString ("NAME"); std::string id = mReader->getHNOString ("NAME");
ESM::Dialogue record; ESM::Dialogue record;
record.mId = id; record.mId = id;
record.load (reader); record.load (*mReader);
if (record.mType==ESM::Dialogue::Journal) if (record.mType==ESM::Dialogue::Journal)
{ {
mJournals.load (record, base); mJournals.load (record, mBase);
dialogue = &mJournals.getRecord (id).get(); mDialogue = &mJournals.getRecord (id).get();
} }
else if (record.mType==ESM::Dialogue::Deleted) else if (record.mType==ESM::Dialogue::Deleted)
{ {
dialogue = 0; // record vector can be shuffled around which would make pointer mDialogue = 0; // record vector can be shuffled around which would make pointer
// to record invalid // to record invalid
if (mJournals.tryDelete (id)) if (mJournals.tryDelete (id))
@ -579,8 +597,8 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, b
} }
else else
{ {
mTopics.load (record, base); mTopics.load (record, mBase);
dialogue = &mTopics.getRecord (id).get(); mDialogue = &mTopics.getRecord (id).get();
} }
break; break;
@ -588,26 +606,26 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, b
case ESM::REC_INFO: case ESM::REC_INFO:
{ {
if (!dialogue) if (!mDialogue)
{ {
/// \todo INFO record without matching DIAL record -> report to user /// \todo INFO record without matching DIAL record -> report to user
reader.skipRecord(); mReader->skipRecord();
break; break;
} }
if (dialogue->mType==ESM::Dialogue::Journal) if (mDialogue->mType==ESM::Dialogue::Journal)
mJournalInfos.load (reader, base, *dialogue); mJournalInfos.load (*mReader, mBase, *mDialogue);
else else
mTopicInfos.load (reader, base, *dialogue); mTopicInfos.load (*mReader, mBase, *mDialogue);
break; break;
} }
case ESM::REC_FILT: case ESM::REC_FILT:
if (project) if (mProject)
{ {
mFilters.load (reader, base); mFilters.load (*mReader, mBase);
mFilters.setData (mFilters.getSize()-1, mFilters.setData (mFilters.getSize()-1,
mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope), mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope),
static_cast<int> (CSMFilter::Filter::Scope_Project)); static_cast<int> (CSMFilter::Filter::Scope_Project));
@ -620,9 +638,10 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, b
/// \todo throw an exception instead, once all records are implemented /// \todo throw an exception instead, once all records are implemented
/// or maybe report error and continue? /// or maybe report error and continue?
reader.skipRecord(); mReader->skipRecord();
}
} }
return false;
} }
bool CSMWorld::Data::hasId (const std::string& id) const bool CSMWorld::Data::hasId (const std::string& id) const

View file

@ -33,12 +33,19 @@
class QAbstractItemModel; class QAbstractItemModel;
namespace ESM
{
class ESMReader;
struct Dialogue;
}
namespace CSMWorld namespace CSMWorld
{ {
class Data : public QObject class Data : public QObject
{ {
Q_OBJECT Q_OBJECT
ToUTF8::Utf8Encoder mEncoder;
IdCollection<ESM::Global> mGlobals; IdCollection<ESM::Global> mGlobals;
IdCollection<ESM::GameSetting> mGmsts; IdCollection<ESM::GameSetting> mGmsts;
IdCollection<ESM::Skill> mSkills; IdCollection<ESM::Skill> mSkills;
@ -62,6 +69,10 @@ namespace CSMWorld
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex; std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
std::string mAuthor; std::string mAuthor;
std::string mDescription; std::string mDescription;
ESM::ESMReader *mReader;
const ESM::Dialogue *mDialogue; // last loaded dialogue
bool mBase;
bool mProject;
// not implemented // not implemented
Data (const Data&); Data (const Data&);
@ -167,10 +178,15 @@ namespace CSMWorld
void merge(); void merge();
///< Merge modified into base. ///< Merge modified into base.
void loadFile (const boost::filesystem::path& path, bool base, bool project); int startLoading (const boost::filesystem::path& path, bool base, bool project);
///< Merging content of a file into base or modified. ///< Begin merging content of a file into base or modified.
/// ///
/// \param project load project file instead of content file /// \param project load project file instead of content file
///
///< \return estimated number of records
bool continueLoading();
///< \return Finished?
bool hasId (const std::string& id) const; bool hasId (const std::string& id) const;