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:
parent
e324450118
commit
dbb192f084
7 changed files with 210 additions and 54 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
66
apps/opencs/model/doc/loader.cpp
Normal file
66
apps/opencs/model/doc/loader.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
55
apps/opencs/model/doc/loader.hpp
Normal file
55
apps/opencs/model/doc/loader.hpp
Normal 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
|
Loading…
Reference in a new issue