From d3fe9ff1faed52da8f647d9294e9ce371b0361e4 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 16 Feb 2020 18:57:38 -0500 Subject: moved TimeThis to uibase fixed progress bar --- src/directoryrefresher.cpp | 34 +++++++++++++++----- src/directoryrefresher.h | 74 ++++++++++++++++++++++++++++++++++++++++---- src/mainwindow.cpp | 16 +++++++--- src/mainwindow.h | 4 ++- src/shared/fileregisterfwd.h | 2 ++ src/shared/util.cpp | 20 ------------ src/shared/util.h | 15 +-------- 7 files changed, 113 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 5e1c05a8..599dd815 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -326,8 +326,10 @@ void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure } } + struct ModThread { + DirectoryRefreshProgress* progress = nullptr; DirectoryEntry* ds = nullptr; std::wstring modName; std::wstring path; @@ -375,6 +377,11 @@ struct ModThread modName, path, prio, archives, enabledArchives, lo, *stats); } + if (progress) { + progress->addDone(); + } + + SetThisThreadName(QString::fromStdWString(L"idle refresher")); ready = false; } }; @@ -382,13 +389,22 @@ struct ModThread env::ThreadPool g_threads; +void DirectoryRefresher::updateProgress(const DirectoryRefreshProgress* p) +{ + // careful: called from multiple threads + emit progress(p); +} void DirectoryRefresher::addMultipleModsFilesToStructure( MOShared::DirectoryEntry *directoryStructure, - const std::vector& entries, bool emitProgress) + const std::vector& entries, DirectoryRefreshProgress* progress) { std::vector stats(entries.size()); + if (progress) { + progress->start(entries.size()); + } + log::debug("refresher: using {} threads", m_threadCount); g_threads.setMax(m_threadCount); @@ -405,9 +421,14 @@ void DirectoryRefresher::addMultipleModsFilesToStructure( if (e.stealFiles.length() > 0) { stealModFilesIntoStructure( directoryStructure, e.modName, prio, e.absolutePath, e.stealFiles); + + if (progress) { + progress->addDone(); + } } else { auto& mt = g_threads.request(); + mt.progress = progress; mt.ds = directoryStructure; mt.modName = e.modName.toStdWString(); mt.path = QDir::toNativeSeparators(e.absolutePath).toStdWString(); @@ -430,10 +451,6 @@ void DirectoryRefresher::addMultipleModsFilesToStructure( } catch (const std::exception& ex) { emit error(tr("failed to read mod (%1): %2").arg(e.modName, ex.what())); } - - if (emitProgress) { - emit progress((static_cast(i) * 100) / static_cast(entries.size()) + 1); - } } g_threads.waitForAll(); @@ -447,6 +464,7 @@ void DirectoryRefresher::refresh() { SetThisThreadName("DirectoryRefresher"); TimeThis tt("refresh"); + auto* p = new DirectoryRefreshProgress(this); { QMutexLocker locker(&m_RefreshLock); @@ -468,7 +486,7 @@ void DirectoryRefresher::refresh() return lhs.priority < rhs.priority; }); - addMultipleModsFilesToStructure(m_Root.get(), m_Mods, true); + addMultipleModsFilesToStructure(m_Root.get(), m_Mods, p); m_Root->getFileRegister()->sortOrigins(); @@ -478,6 +496,8 @@ void DirectoryRefresher::refresh() log::debug("refresher saw {} files", m_lastFileCount); } - emit progress(100); + p->finish(); + + emit progress(p); emit refreshed(); } diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h index e81b55dd..bd08dad6 100644 --- a/src/directoryrefresher.h +++ b/src/directoryrefresher.h @@ -20,14 +20,14 @@ along with Mod Organizer. If not, see . #ifndef DIRECTORYREFRESHER_H #define DIRECTORYREFRESHER_H +#include "fileregisterfwd.h" +#include "profile.h" #include #include #include #include #include #include -#include "profile.h" - /** * @brief used to asynchronously generate the virtual view of the combined data directory @@ -38,11 +38,15 @@ class DirectoryRefresher : public QObject Q_OBJECT public: - struct EntryInfo { + struct EntryInfo + { EntryInfo(const QString &modName, const QString &absolutePath, const QStringList &stealFiles, const QStringList &archives, int priority) : modName(modName), absolutePath(absolutePath), stealFiles(stealFiles) - , archives(archives), priority(priority) {} + , archives(archives), priority(priority) + { + } + QString modName; QString absolutePath; QStringList stealFiles; @@ -121,7 +125,10 @@ public: void addMultipleModsFilesToStructure( MOShared::DirectoryEntry *directoryStructure, - const std::vector& entries, bool emitProgress=false); + const std::vector& entries, + DirectoryRefreshProgress* progress=nullptr); + + void updateProgress(const DirectoryRefreshProgress* p); public slots: @@ -132,7 +139,7 @@ public slots: signals: - void progress(int progress); + void progress(const DirectoryRefreshProgress* p); void error(const QString &error); void refreshed(); @@ -149,4 +156,59 @@ private: int priority, const QString &directory, const QStringList &stealFiles); }; + +class DirectoryRefreshProgress : QObject +{ + Q_OBJECT; + +public: + DirectoryRefreshProgress(DirectoryRefresher* r) : + QObject(r), m_refresher(r), m_modCount(0), m_modDone(0), m_finished(false) + { + } + + void start(std::size_t modCount) + { + m_modCount = modCount; + m_modDone = 0; + m_finished = false; + } + + + bool finished() const + { + return m_finished; + } + + int percentDone() const + { + int percent = 100; + + if (m_modCount > 0) { + const double d = static_cast(m_modDone) / m_modCount; + percent = static_cast(d * 100); + } + + return percent; + } + + + void finish() + { + m_finished = true; + } + + void addDone() + { + ++m_modDone; + m_refresher->updateProgress(this); + } + +private: + DirectoryRefresher* m_refresher; + std::size_t m_modCount; + std::atomic m_modDone; + bool m_finished; +}; + #endif // DIRECTORYREFRESHER_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f5749392..21a6fa41 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -367,7 +367,10 @@ MainWindow::MainWindow(Settings &settings connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(espFilterChanged(QString))); connect(m_OrganizerCore.directoryRefresher(), SIGNAL(refreshed()), this, SLOT(directory_refreshed())); - connect(m_OrganizerCore.directoryRefresher(), SIGNAL(progress(int)), this, SLOT(refresher_progress(int))); + connect( + m_OrganizerCore.directoryRefresher(), + &DirectoryRefresher::progress, + this, &MainWindow::refresherProgress); connect(m_OrganizerCore.directoryRefresher(), SIGNAL(error(QString)), this, SLOT(showError(QString))); connect(&m_SavesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(refreshSavesIfOpen())); @@ -2382,10 +2385,15 @@ void MainWindow::setESPListSorting(int index) } } -void MainWindow::refresher_progress(int percent) +void MainWindow::refresherProgress(const DirectoryRefreshProgress* p) { - setEnabled(percent == 100); - ui->statusBar->setProgress(percent); + if (p->finished()) { + setEnabled(true); + ui->statusBar->setProgress(100); + } else { + setEnabled(false); + ui->statusBar->setProgress(p->percentDone()); + } } void MainWindow::directory_refreshed() diff --git a/src/mainwindow.h b/src/mainwindow.h index 6530d8ad..b839e85e 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -31,6 +31,7 @@ along with Mod Organizer. If not, see . #include "tutorialcontrol.h" #include "plugincontainer.h" //class PluginContainer; #include "iplugingame.h" //namespace MOBase { class IPluginGame; } +#include "shared/fileregisterfwd.h" #include class Executable; @@ -155,7 +156,8 @@ public: public slots: void modorder_changed(); void esplist_changed(); - void refresher_progress(int percent); + void refresherProgress(const DirectoryRefreshProgress* p); + void directory_refreshed(); void toolPluginInvoke(); diff --git a/src/shared/fileregisterfwd.h b/src/shared/fileregisterfwd.h index 6348fee1..720e6e30 100644 --- a/src/shared/fileregisterfwd.h +++ b/src/shared/fileregisterfwd.h @@ -1,6 +1,8 @@ #ifndef MO_REGISTER_FILEREGISTERFWD_INCLUDED #define MO_REGISTER_FILEREGISTERFWD_INCLUDED +class DirectoryRefreshProgress; + namespace MOShared { diff --git a/src/shared/util.cpp b/src/shared/util.cpp index 74e386a3..483b36a9 100644 --- a/src/shared/util.cpp +++ b/src/shared/util.cpp @@ -382,26 +382,6 @@ void checkDuplicateShortcuts(const QMenu& m) } // namespace MOShared -TimeThis::TimeThis(QString what) - : m_what(std::move(what)), m_start(Clock::now()) -{ -} - -TimeThis::~TimeThis() -{ - using namespace std::chrono; - - const auto end = Clock::now(); - const auto d = duration_cast(end - m_start).count(); - - if (m_what.isEmpty()) { - log::debug("{} ms", d); - } else { - log::debug("{} {} ms", m_what, d); - } -} - - static bool g_exiting = false; static bool g_canClose = false; diff --git a/src/shared/util.h b/src/shared/util.h index 1d3cce82..2761b64f 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -20,6 +20,7 @@ along with Mod Organizer. If not, see . #ifndef UTIL_H #define UTIL_H +#include #include #include #include @@ -64,20 +65,6 @@ inline FILETIME ToFILETIME(std::filesystem::file_time_type t) } // namespace MOShared -class TimeThis -{ -public: - TimeThis(QString what={}); - ~TimeThis(); - -private: - using Clock = std::chrono::high_resolution_clock; - - QString m_what; - Clock::time_point m_start; -}; - - enum class Exit { None = 0x00, -- cgit v1.3.1