1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-28 20:36:42 +00:00

moved loading to a separate thread

This commit is contained in:
Marc Zinnschlag 2014-04-24 15:09:25 +02:00
parent e324450118
commit dbb192f084
7 changed files with 210 additions and 54 deletions

View file

@ -5,7 +5,7 @@ opencs_units (. editor)
set (CMAKE_BUILD_TYPE DEBUG) set (CMAKE_BUILD_TYPE DEBUG)
opencs_units (model/doc opencs_units (model/doc
document operation saving documentmanager document operation saving documentmanager loader
) )
opencs_units_noqt (model/doc opencs_units_noqt (model/doc

View file

@ -2219,68 +2219,32 @@ void CSMDoc::Document::createBase()
} }
} }
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, bool new_) CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
: mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir), const std::vector< boost::filesystem::path >& files,
mProjectPath ((configuration.getUserDataPath() / "projects") / const boost::filesystem::path& savePath, const boost::filesystem::path& resDir)
(savePath.filename().string() + ".project")), : mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir),
mSaving (*this, mProjectPath) mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")),
mSaving (*this, mProjectPath)
{ {
if (files.empty()) if (mContentFiles.empty())
throw std::runtime_error ("Empty content file sequence"); throw std::runtime_error ("Empty content file sequence");
if (new_ && files.size()==1) if (!boost::filesystem::exists (mProjectPath))
createBase();
else
{
std::vector<boost::filesystem::path>::const_iterator end = files.end();
if (new_)
--end;
load (files.begin(), end, !new_);
}
if (new_)
{
mData.setDescription ("");
mData.setAuthor ("");
}
bool filtersFound = false;
if (boost::filesystem::exists (mProjectPath))
{
filtersFound = true;
}
else
{ {
boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath()); boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath());
locCustomFiltersPath /= "defaultfilters"; locCustomFiltersPath /= "defaultfilters";
if (boost::filesystem::exists(locCustomFiltersPath)) if (boost::filesystem::exists (locCustomFiltersPath))
{ {
boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath); boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath);
filtersFound = true;
} }
else else
{ {
boost::filesystem::path filters(mResDir); boost::filesystem::copy_file (mResDir / "defaultfilters", mProjectPath);
filters /= "defaultfilters";
if (boost::filesystem::exists(filters))
{
boost::filesystem::copy_file(filters, mProjectPath);
filtersFound = true;
}
} }
} }
if (filtersFound)
getData().loadFile (mProjectPath, false, true);
addOptionalGmsts();
addOptionalGlobals();
connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool))); connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool)));
connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int)));
@ -2289,13 +2253,39 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co
connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int)));
connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int))); connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int)));
connect (&mSaving, SIGNAL (reportMessage (const QString&, int)), connect (&mSaving, SIGNAL (reportMessage (const QString&, int)),
this, SLOT (reportMessage (const QString&, int))); this, SLOT (reportMessage (const QString&, int)));
} }
CSMDoc::Document::~Document() CSMDoc::Document::~Document()
{ {
} }
void CSMDoc::Document::setupData (bool new_)
{
if (new_ && mContentFiles.size()==1)
createBase();
else
{
std::vector<boost::filesystem::path>::const_iterator end = mContentFiles.end();
if (new_)
--end;
load (mContentFiles.begin(), end, !new_);
}
if (new_)
{
mData.setDescription ("");
mData.setAuthor ("");
}
getData().loadFile (mProjectPath, false, true);
addOptionalGmsts();
addOptionalGlobals();
}
QUndoStack& CSMDoc::Document::getUndoStack() QUndoStack& CSMDoc::Document::getUndoStack()
{ {
return mUndoStack; return mUndoStack;

View file

@ -72,12 +72,13 @@ namespace CSMDoc
public: public:
Document (const Files::ConfigurationManager& configuration, Document (const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files, const std::vector< boost::filesystem::path >& files,
const boost::filesystem::path& savePath, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir);
const boost::filesystem::path& resDir, bool new_);
~Document(); ~Document();
void setupData (bool new_);
QUndoStack& getUndoStack(); QUndoStack& getUndoStack();
int getState() const; int getState() const;

View file

@ -19,10 +19,24 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con
if (!boost::filesystem::is_directory (projectPath)) if (!boost::filesystem::is_directory (projectPath))
boost::filesystem::create_directories (projectPath); boost::filesystem::create_directories (projectPath);
mLoader.moveToThread (&mLoaderThread);
mLoaderThread.start();
connect (&mLoader, SIGNAL (documentLoaded (Document *)),
this, SLOT (documentLoaded (Document *)));
connect (&mLoader, SIGNAL (documentNotLoaded (Document *, const std::string&)),
this, SLOT (documentNotLoaded (Document *, const std::string&)));
connect (this, SIGNAL (loadRequest (Document *, bool)),
&mLoader, SLOT (loadDocument (Document *, bool)));
} }
CSMDoc::DocumentManager::~DocumentManager() CSMDoc::DocumentManager::~DocumentManager()
{ {
mLoaderThread.quit();
mLoader.hasThingsToDo().wakeAll();
mLoaderThread.wait();
for (std::vector<Document *>::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++iter) for (std::vector<Document *>::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++iter)
delete *iter; delete *iter;
} }
@ -30,11 +44,13 @@ CSMDoc::DocumentManager::~DocumentManager()
void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath, void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
bool new_) bool new_)
{ {
Document *document = new Document (mConfiguration, files, savePath, mResDir, new_); Document *document = new Document (mConfiguration, files, savePath, mResDir);
mDocuments.push_back (document); mDocuments.push_back (document);
emit documentAdded (document); emit loadRequest (document, new_);
mLoader.hasThingsToDo().wakeAll();
} }
bool CSMDoc::DocumentManager::removeDocument (Document *document) bool CSMDoc::DocumentManager::removeDocument (Document *document)
@ -54,3 +70,15 @@ void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& par
{ {
mResDir = boost::filesystem::system_complete(parResDir); mResDir = boost::filesystem::system_complete(parResDir);
} }
void CSMDoc::DocumentManager::documentLoaded (Document *document)
{
emit documentAdded (document);
}
void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std::string& error)
{
removeDocument (document);
/// \todo report error
/// \todo handle removeDocument returning true
}

View file

@ -7,6 +7,9 @@
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <QObject> #include <QObject>
#include <QThread>
#include "loader.hpp"
namespace Files namespace Files
{ {
@ -23,6 +26,8 @@ namespace CSMDoc
std::vector<Document *> mDocuments; std::vector<Document *> mDocuments;
const Files::ConfigurationManager& mConfiguration; const Files::ConfigurationManager& mConfiguration;
QThread mLoaderThread;
Loader mLoader;
DocumentManager (const DocumentManager&); DocumentManager (const DocumentManager&);
DocumentManager& operator= (const DocumentManager&); DocumentManager& operator= (const DocumentManager&);
@ -47,9 +52,20 @@ namespace CSMDoc
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
private slots:
void documentLoaded (Document *document);
///< The ownership of \a document is not transferred.
void documentNotLoaded (Document *document, const std::string& error);
///< Document load has been interrupted either because of a call to abortLoading
/// or a problem during loading). In the former case error will be an empty string.
signals: signals:
void documentAdded (CSMDoc::Document *document); void documentAdded (CSMDoc::Document *document);
void loadRequest (Document *document, bool _new);
}; };
} }

View file

@ -0,0 +1,66 @@
#include "loader.hpp"
#include <QTimer>
#include "document.hpp"
CSMDoc::Loader::Loader()
{
QTimer *timer = new QTimer (this);
connect (timer, SIGNAL (timeout()), this, SLOT (load()));
timer->start (1000);
}
QWaitCondition& CSMDoc::Loader::hasThingsToDo()
{
return mThingsToDo;
}
void CSMDoc::Loader::load()
{
if (mDocuments.empty())
{
mMutex.lock();
mThingsToDo.wait (&mMutex);
mMutex.unlock();
return;
}
std::vector<std::pair<Document *, bool> >::iterator iter = mDocuments.begin();
Document *document = iter->first;
bool new_ = iter->second;
mDocuments.erase (iter);
try
{
document->setupData (new_);
emit documentLoaded (document);
}
catch (const std::exception& e)
{
emit documentNotLoaded (document, e.what());
}
}
void CSMDoc::Loader::loadDocument (Document *document, bool new_)
{
mDocuments.push_back (std::make_pair (document, new_));
}
void CSMDoc::Loader::abortLoading (Document *document)
{
for (std::vector<std::pair<Document *, bool> >::iterator iter = mDocuments.begin();
iter!=mDocuments.end(); ++iter)
{
if (iter->first==document)
{
mDocuments.erase (iter);
emit documentNotLoaded (document, "");
break;
}
}
}

View file

@ -0,0 +1,55 @@
#ifndef CSM_DOC_LOADER_H
#define CSM_DOC_LOADER_H
#include <vector>
#include <QObject>
#include <QMutex>
#include <QWaitCondition>
namespace CSMDoc
{
class Document;
class Loader : public QObject
{
Q_OBJECT
QMutex mMutex;
QWaitCondition mThingsToDo;
std::vector<std::pair<Document *, bool> > mDocuments;
public:
Loader();
QWaitCondition& hasThingsToDo();
private slots:
void load();
public slots:
void loadDocument (Document *document, bool new_);
///< The ownership of \a document is not transferred.
/// \param new_ Do not load the last content file in the files list specified in
/// \a document and instead create it in an appropriate way.
void abortLoading (Document *document);
///< Abort loading \a docuemnt (ignored if \a document has already finished being
/// loaded). Will result in a documentNotLoaded signal, once the Loader has finished
/// cleaning up.
signals:
void documentLoaded (Document *document);
///< The ownership of \a document is not transferred.
void documentNotLoaded (Document *document, const std::string& error);
///< Document load has been interrupted either because of a call to abortLoading
/// or a problem during loading). In the former case error will be an empty string.
};
}
#endif