moved loading to a separate thread

deque
Marc Zinnschlag 11 years ago
parent e324450118
commit dbb192f084

@ -5,7 +5,7 @@ opencs_units (. editor)
set (CMAKE_BUILD_TYPE DEBUG)
opencs_units (model/doc
document operation saving documentmanager
document operation saving documentmanager loader
)
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_)
: mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir),
mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")),
mSaving (*this, mProjectPath)
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files,
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir)
: mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir),
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");
if (new_ && files.size()==1)
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
if (!boost::filesystem::exists (mProjectPath))
{
boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath());
locCustomFiltersPath /= "defaultfilters";
if (boost::filesystem::exists(locCustomFiltersPath))
if (boost::filesystem::exists (locCustomFiltersPath))
{
boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath);
filtersFound = true;
}
else
{
boost::filesystem::path filters(mResDir);
filters /= "defaultfilters";
if (boost::filesystem::exists(filters))
{
boost::filesystem::copy_file(filters, mProjectPath);
filtersFound = true;
}
boost::filesystem::copy_file (mResDir / "defaultfilters", mProjectPath);
}
}
if (filtersFound)
getData().loadFile (mProjectPath, false, true);
addOptionalGmsts();
addOptionalGlobals();
connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool)));
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 (done (int)), this, SLOT (operationDone (int)));
connect (&mSaving, SIGNAL (reportMessage (const QString&, int)),
this, SLOT (reportMessage (const QString&, int)));
this, SLOT (reportMessage (const QString&, int)));
}
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()
{
return mUndoStack;

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

@ -19,10 +19,24 @@ CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& con
if (!boost::filesystem::is_directory (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()
{
mLoaderThread.quit();
mLoader.hasThingsToDo().wakeAll();
mLoaderThread.wait();
for (std::vector<Document *>::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++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,
bool new_)
{
Document *document = new Document (mConfiguration, files, savePath, mResDir, new_);
Document *document = new Document (mConfiguration, files, savePath, mResDir);
mDocuments.push_back (document);
emit documentAdded (document);
emit loadRequest (document, new_);
mLoader.hasThingsToDo().wakeAll();
}
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);
}
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 <QObject>
#include <QThread>
#include "loader.hpp"
namespace Files
{
@ -23,6 +26,8 @@ namespace CSMDoc
std::vector<Document *> mDocuments;
const Files::ConfigurationManager& mConfiguration;
QThread mLoaderThread;
Loader mLoader;
DocumentManager (const DocumentManager&);
DocumentManager& operator= (const DocumentManager&);
@ -47,9 +52,20 @@ namespace CSMDoc
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:
void documentAdded (CSMDoc::Document *document);
void loadRequest (Document *document, bool _new);
};
}

@ -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;
}
}
}

@ -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…
Cancel
Save