Skip to content

Commit

Permalink
GameTracker now running in its own thread, to avoid running its (some…
Browse files Browse the repository at this point in the history
…how expensive) functions in the UI thread.
  • Loading branch information
cristian64 committed Jan 19, 2019
1 parent 8497e41 commit 363ee48
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 10 deletions.
65 changes: 56 additions & 9 deletions Source/Core/DolphinQt/GameList/GameTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "DolphinQt/GameList/GameTracker.h"

#include <cassert>

#include <QDir>
#include <QDirIterator>
#include <QFile>
Expand All @@ -24,8 +26,10 @@ static const QStringList game_filters{
QStringLiteral("*.[wW][aA][dD]"), QStringLiteral("*.[eE][lL][fF]"),
QStringLiteral("*.[dD][oO][lL]")};

GameTracker::GameTracker(QObject* parent) : QObject(parent)
GameTracker::GameTracker(QObject* parent) : QThread(parent)
{
moveToThread(this);

qRegisterMetaType<std::shared_ptr<const UICommon::GameFile>>();
qRegisterMetaType<std::string>();

Expand All @@ -48,17 +52,60 @@ GameTracker::GameTracker(QObject* parent) : QObject(parent)
Settings::Instance().NotifyMetadataRefreshComplete();
});

QThread::start(QThread::IdlePriority);

LoadCache();

// TODO: When language changes, reload m_title_database and call m_cache.UpdateAdditionalMetadata
}

GameTracker::~GameTracker()
{
QThread::quit();
const bool joined = QThread::wait(5000);
assert(joined && "Thread is taking too long to finish");
if (!joined)
{
QThread::terminate();
}
}

void GameTracker::Start()
{
QMetaObject::invokeMethod(this, "StartSlot");
}

void GameTracker::AddDirectory(const QString& dir)
{
QMetaObject::invokeMethod(this, "AddDirectorySlot", Q_ARG(QString, dir));
}

void GameTracker::RemoveDirectory(const QString& dir)
{
QMetaObject::invokeMethod(this, "RemoveDirectorySlot", Q_ARG(QString, dir));
}

void GameTracker::RefreshAll()
{
QMetaObject::invokeMethod(this, "RefreshAllSlot");
}

void GameTracker::PurgeCache()
{
QMetaObject::invokeMethod(this, "PurgeCacheSlot");
}

void GameTracker::LoadCache()
{
QMetaObject::invokeMethod(this, "LoadCacheSlot");
}

void GameTracker::LoadCacheSlot()
{
m_cache.Load();
}

void GameTracker::Start()
void GameTracker::StartSlot()
{
if (m_started)
return;
Expand Down Expand Up @@ -118,7 +165,7 @@ bool GameTracker::RemovePath(const QString& dir)
return true;
}

void GameTracker::AddDirectory(const QString& dir)
void GameTracker::AddDirectorySlot(const QString& dir)
{
if (!QFileInfo(dir).exists())
return;
Expand All @@ -134,7 +181,7 @@ static std::unique_ptr<QDirIterator> GetIterator(const QString& dir)
QDirIterator::NoIteratorFlags);
}

void GameTracker::RemoveDirectory(const QString& dir)
void GameTracker::RemoveDirectorySlot(const QString& dir)
{
RemovePath(dir);
auto it = GetIterator(dir);
Expand All @@ -155,7 +202,7 @@ void GameTracker::RemoveDirectory(const QString& dir)
}
}

void GameTracker::RefreshAll()
void GameTracker::RefreshAllSlot()
{
for (auto& file : m_tracked_files.keys())
emit GameRemoved(file.toStdString());
Expand All @@ -164,8 +211,8 @@ void GameTracker::RefreshAll()

for (const QString& dir : Settings::Instance().GetPaths())
{
RemoveDirectory(dir);
AddDirectory(dir);
RemoveDirectorySlot(dir);
AddDirectorySlot(dir);
}
}

Expand Down Expand Up @@ -260,8 +307,8 @@ void GameTracker::LoadGame(const QString& path)
}
}

void GameTracker::PurgeCache()
void GameTracker::PurgeCacheSlot()
{
m_cache.Clear(UICommon::GameFileCache::DeleteOnDisk::Yes);
RefreshAll();
RefreshAllSlot();
}
12 changes: 11 additions & 1 deletion Source/Core/DolphinQt/GameList/GameTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <QMap>
#include <QSet>
#include <QString>
#include <QThread>
#include <QVector>

#include "UICommon/GameFileCache.h"
Expand All @@ -23,12 +24,13 @@ class GameFile;
// Watches directories and loads GameFiles in a separate thread.
// To use this, just add directories using AddDirectory, and listen for the
// GameLoaded and GameRemoved signals.
class GameTracker final : public QObject
class GameTracker final : public QThread
{
Q_OBJECT

public:
explicit GameTracker(QObject* parent = nullptr);
~GameTracker() override;

// A GameTracker won't emit any signals until this function has been called.
// Before you call this function, make sure to call AddDirectory for all
Expand All @@ -46,6 +48,14 @@ class GameTracker final : public QObject
void GameUpdated(const std::shared_ptr<const UICommon::GameFile>& game);
void GameRemoved(const std::string& path);

private slots:
void StartSlot();
void AddDirectorySlot(const QString& dir);
void RemoveDirectorySlot(const QString& dir);
void RefreshAllSlot();
void PurgeCacheSlot();
void LoadCacheSlot();

private:
void LoadCache();
void UpdateDirectory(const QString& dir);
Expand Down

0 comments on commit 363ee48

Please sign in to comment.