From 9e7d2edd4f15e3e8d5c2fe7c078aba4538545285 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 10 Jan 2017 20:13:34 -0800 Subject: [PATCH] Qt: Load No-Intro DB on a thread --- src/feature/sqlite3/no-intro.c | 2 +- src/platform/qt/GBAApp.cpp | 42 +++++++++++++++++++++++++++++----- src/platform/qt/GBAApp.h | 22 ++++++++++++++++++ 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/feature/sqlite3/no-intro.c b/src/feature/sqlite3/no-intro.c index 6e5fef1bb..00a1429e6 100644 --- a/src/feature/sqlite3/no-intro.c +++ b/src/feature/sqlite3/no-intro.c @@ -19,7 +19,7 @@ struct NoIntroDB { struct NoIntroDB* NoIntroDBLoad(const char* path) { struct NoIntroDB* db = malloc(sizeof(*db)); - if (sqlite3_open(path, &db->db)) { + if (sqlite3_open_v2(path, &db->db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL)) { goto error; } diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index 32ee71fbb..59e0a8320 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -105,6 +105,11 @@ GBAApp::GBAApp(int& argc, char* argv[]) w->multiplayerChanged(); } +GBAApp::~GBAApp() { + m_parseThread.quit(); + m_parseThread.wait(); +} + bool GBAApp::event(QEvent* event) { if (event->type() == QEvent::FileOpen) { m_windows[0]->controller()->loadGame(static_cast(event)->file()); @@ -208,25 +213,32 @@ QString GBAApp::dataDir() { return path; } -bool GBAApp::reloadGameDB() { #ifdef USE_SQLITE3 +bool GBAApp::reloadGameDB() { NoIntroDB* db = nullptr; db = NoIntroDBLoad((m_configController.configDir() + "/nointro.sqlite3").toLocal8Bit().constData()); if (db && m_db) { NoIntroDBDestroy(m_db); } if (db) { - VFile* vf = VFileDevice::open(dataDir() + "/nointro.dat", O_RDONLY); - if (vf) { - NoIntroDBLoadClrMamePro(db, vf); - vf->close(vf); + if (m_parseThread.isRunning()) { + m_parseThread.quit(); + m_parseThread.wait(); } + GameDBParser* parser = new GameDBParser(db); + m_parseThread.start(); + parser->moveToThread(&m_parseThread); + QMetaObject::invokeMethod(parser, "parseNoIntroDB"); m_db = db; return true; } -#endif return false; } +#else +bool GBAApp::loadGameDB() { + return false; +} +#endif GBAApp::FileDialog::FileDialog(GBAApp* app, QWidget* parent, const QString& caption, const QString& filter) : QFileDialog(parent, caption, app->m_configController.getOption("lastDirectory"), filter) @@ -245,3 +257,21 @@ int GBAApp::FileDialog::exec() { m_app->continueAll(&paused); return didAccept; } + +#ifdef USE_SQLITE3 +GameDBParser::GameDBParser(NoIntroDB* db, QObject* parent) + : QObject(parent) + , m_db(db) +{ + // Nothing to do +} + +void GameDBParser::parseNoIntroDB() { + VFile* vf = VFileDevice::open(GBAApp::dataDir() + "/nointro.dat", O_RDONLY); + if (vf) { + NoIntroDBLoadClrMamePro(m_db, vf); + vf->close(vf); + } +} + +#endif diff --git a/src/platform/qt/GBAApp.h b/src/platform/qt/GBAApp.h index a0e13a60e..06fb510a9 100644 --- a/src/platform/qt/GBAApp.h +++ b/src/platform/qt/GBAApp.h @@ -8,6 +8,7 @@ #include #include +#include #include "ConfigController.h" #include "MultiplayerController.h" @@ -23,11 +24,28 @@ namespace QGBA { class GameController; class Window; +#ifdef USE_SQLITE3 +class GameDBParser : public QObject { +Q_OBJECT + +public: + GameDBParser(NoIntroDB* db, QObject* parent = nullptr); + +public slots: + void parseNoIntroDB(); + +private: + NoIntroDB* m_db; +}; +#endif + + class GBAApp : public QApplication { Q_OBJECT public: GBAApp(int& argc, char* argv[]); + ~GBAApp(); static GBAApp* app(); static QString dataDir(); @@ -66,7 +84,11 @@ private: ConfigController m_configController; Window* m_windows[MAX_GBAS]; MultiplayerController m_multiplayer; + +#ifdef USE_SQLITE3 NoIntroDB* m_db; + QThread m_parseThread; +#endif }; }