Qt: Move library loading to a separate thread
Vicki Pfau vi@endrift.com
Wed, 18 Jan 2017 11:57:09 -0800
4 files changed,
75 insertions(+),
7 deletions(-)
M
src/platform/qt/ArchiveInspector.cpp
→
src/platform/qt/ArchiveInspector.cpp
@@ -16,6 +16,9 @@ : QDialog(parent)
, m_model(ConfigController::configDir() + "/library.sqlite3") { m_ui.setupUi(this); + connect(&m_model, &LibraryModel::doneLoading, [this]() { + m_ui.loading->hide(); + }); m_model.loadDirectory(filename); m_model.constrainBase(filename); m_ui.archiveListing->setModel(&m_model);
M
src/platform/qt/ArchiveInspector.ui
→
src/platform/qt/ArchiveInspector.ui
@@ -14,14 +14,21 @@ <property name="windowTitle">
<string>Open in archive...</string> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="0"> + <item row="2" column="1"> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Open</set> </property> </widget> </item> - <item row="0" column="0"> + <item row="2" column="0"> + <widget class="QLabel" name="loading"> + <property name="text"> + <string>Loading...</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> <widget class="QListView" name="archiveListing"/> </item> </layout>
M
src/platform/qt/LibraryModel.cpp
→
src/platform/qt/LibraryModel.cpp
@@ -21,17 +21,27 @@ m_library = mLibraryCreateEmpty();
} memset(&m_constraints, 0, sizeof(m_constraints)); m_constraints.platform = PLATFORM_NONE; + + if (!m_library) { + return; + } + m_loader = new LibraryLoader(m_library); + connect(m_loader, SIGNAL(directoryLoaded(const QString&)), this, SLOT(directoryLoaded(const QString&))); + m_loader->moveToThread(&m_loaderThread); + m_loaderThread.setObjectName("Library Loader Thread"); + m_loaderThread.start(); } LibraryModel::~LibraryModel() { clearConstraints(); mLibraryDestroy(m_library); + m_loaderThread.quit(); + m_loaderThread.wait(); } void LibraryModel::loadDirectory(const QString& path) { - beginResetModel(); - mLibraryLoadDirectory(m_library, path.toUtf8().constData()); - endResetModel(); + m_queue.append(path); + QMetaObject::invokeMethod(m_loader, "loadDirectory", Q_ARG(const QString&, path)); } bool LibraryModel::entryAt(int row, mLibraryEntry* out) const {@@ -136,3 +146,23 @@ free(const_cast<char*>(m_constraints.title));
} memset(&m_constraints, 0, sizeof(m_constraints)); } + +void LibraryModel::directoryLoaded(const QString& path) { + m_queue.removeOne(path); + beginResetModel(); + endResetModel(); + if (m_queue.empty()) { + emit doneLoading(); + } +} + +LibraryLoader::LibraryLoader(mLibrary* library, QObject* parent) + : QObject(parent) + , m_library(library) +{ +} + +void LibraryLoader::loadDirectory(const QString& path) { + mLibraryLoadDirectory(m_library, path.toUtf8().constData()); + emit directoryLoaded(path); +}
M
src/platform/qt/LibraryModel.h
→
src/platform/qt/LibraryModel.h
@@ -7,6 +7,8 @@ #ifndef QGBA_LIBRARY_MODEL
#define QGBA_LIBRARY_MODEL #include <QAbstractItemModel> +#include <QStringList> +#include <QThread> #include <mgba/core/library.h>@@ -15,6 +17,7 @@ struct VFile;
namespace QGBA { +class LibraryLoader; class LibraryModel : public QAbstractItemModel { Q_OBJECT@@ -22,8 +25,6 @@ public:
LibraryModel(const QString& path, QObject* parent = nullptr); virtual ~LibraryModel(); - void loadDirectory(const QString& path); - bool entryAt(int row, mLibraryEntry* out) const; VFile* openVFile(const QModelIndex& index) const;@@ -35,14 +36,41 @@ virtual QModelIndex parent(const QModelIndex& index) const override;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + +signals: + void doneLoading(); public slots: + void loadDirectory(const QString& path); + void constrainBase(const QString& path); void clearConstraints(); +private slots: + void directoryLoaded(const QString& path); + private: mLibrary* m_library; mLibraryEntry m_constraints; + LibraryLoader* m_loader; + QThread m_loaderThread; + QStringList m_queue; +}; + +class LibraryLoader : public QObject { +Q_OBJECT + +public: + LibraryLoader(mLibrary* library, QObject* parent = nullptr); + +public slots: + void loadDirectory(const QString& path); + +signals: + void directoryLoaded(const QString& path); + +private: + mLibrary* m_library; }; }