From 3db95eb4043b8da20e99dd7476bc82468a4609fb Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sun, 9 Feb 2020 04:14:46 -0500
Subject: customizable columns for mod and plugin lists
---
src/organizercore.cpp | 2 --
1 file changed, 2 deletions(-)
(limited to 'src/organizercore.cpp')
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 04d78ca8..8124be1d 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -234,8 +234,6 @@ void OrganizerCore::setUserInterface(IUserInterface* ui)
SLOT(removeMod_clicked()));
connect(&m_ModList, SIGNAL(clearOverwrite()), w,
SLOT(clearOverwrite()));
- connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), w,
- SLOT(displayColumnSelection(QPoint)));
connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), w,
SLOT(fileMoved(QString, QString, QString)));
connect(&m_ModList, SIGNAL(modorder_changed()), w,
--
cgit v1.3.1
From 3423b0a59337cf4cf99a24a1421ea33c4c641a22 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Mon, 10 Feb 2020 14:53:04 -0500
Subject: threaded refresher
---
src/directoryrefresher.cpp | 188 ++++++++++++++++++++++++++++++++----------
src/directoryrefresher.h | 42 ++++++----
src/envfs.cpp | 130 +++++++++++++++++------------
src/envfs.h | 88 ++++++++++++++++++++
src/organizercore.cpp | 23 +++---
src/settings.cpp | 10 +++
src/settings.h | 5 ++
src/shared/directoryentry.cpp | 27 ++++++
src/shared/directoryentry.h | 8 ++
9 files changed, 395 insertions(+), 126 deletions(-)
(limited to 'src/organizercore.cpp')
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index b7dd51ba..5bff9d37 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -24,6 +24,7 @@ along with Mod Organizer. If not, see .
#include "report.h"
#include "modinfo.h"
#include "settings.h"
+#include "envfs.h"
#include
#include
@@ -36,8 +37,8 @@ using namespace MOBase;
using namespace MOShared;
-DirectoryRefresher::DirectoryRefresher()
- : m_DirectoryStructure(nullptr)
+DirectoryRefresher::DirectoryRefresher(std::size_t threadCount)
+ : m_DirectoryStructure(nullptr), m_threadCount(threadCount)
{
}
@@ -116,59 +117,160 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure
}
}
-void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructure, const QString &modName,
- int priority, const QString &directory, const QStringList &stealFiles)
+void DirectoryRefresher::stealModFilesIntoStructure(
+ DirectoryEntry *directoryStructure, const QString &modName,
+ int priority, const QString &directory, const QStringList &stealFiles)
{
std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
- if (stealFiles.length() > 0) {
- // instead of adding all the files of the target directory, we just change the root of the specified
- // files to this mod
- FilesOrigin &origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
- for (const QString &filename : stealFiles) {
- if (filename.isEmpty()) {
- log::warn("Trying to find file with no name");
- continue;
- }
- QFileInfo fileInfo(filename);
- FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
- if (file.get() != nullptr) {
- if (file->getOrigin() == 0) {
- // replace data as the origin on this bsa
- file->removeOrigin(0);
- }
- origin.addFile(file->getIndex());
- file->addOrigin(origin.getID(), file->getFileTime(), L"", -1);
- } else {
- QString warnStr = fileInfo.absolutePath();
- if (warnStr.isEmpty())
- warnStr = filename;
- log::warn("file not found: {}", warnStr);
+ // instead of adding all the files of the target directory, we just change the root of the specified
+ // files to this mod
+ FilesOrigin &origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
+ for (const QString &filename : stealFiles) {
+ if (filename.isEmpty()) {
+ log::warn("Trying to find file with no name");
+ continue;
+ }
+ QFileInfo fileInfo(filename);
+ FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
+ if (file.get() != nullptr) {
+ if (file->getOrigin() == 0) {
+ // replace data as the origin on this bsa
+ file->removeOrigin(0);
}
+ origin.addFile(file->getIndex());
+ file->addOrigin(origin.getID(), file->getFileTime(), L"", -1);
+ } else {
+ QString warnStr = fileInfo.absolutePath();
+ if (warnStr.isEmpty())
+ warnStr = filename;
+ log::warn("file not found: {}", warnStr);
}
+ }
+}
+
+void DirectoryRefresher::addModFilesToStructure(
+ DirectoryEntry *directoryStructure, const QString &modName,
+ int priority, const QString &directory, const QStringList &stealFiles)
+{
+ TimeThis tt("addModFilesToStructure()");
+
+ std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
+
+ if (stealFiles.length() > 0) {
+ stealModFilesIntoStructure(
+ directoryStructure, modName, priority, directory, stealFiles);
} else {
directoryStructure->addFromOrigin(ToWString(modName), directoryW, priority);
}
}
void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
- , const QString &modName
- , int priority
- , const QString &directory
- , const QStringList &stealFiles
- , const QStringList &archives)
+ , const QString &modName
+ , int priority
+ , const QString &directory
+ , const QStringList &stealFiles
+ , const QStringList &archives)
{
- addModFilesToStructure(directoryStructure, modName, priority, directory, stealFiles);
+ TimeThis tt("addModToStructure()");
+
+ if (stealFiles.length() > 0) {
+ stealModFilesIntoStructure(
+ directoryStructure, modName, priority, directory, stealFiles);
+ } else {
+ std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
+ directoryStructure->addFromOrigin(ToWString(modName), directoryW, priority);
+ }
if (Settings::instance().archiveParsing()) {
addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
}
}
+struct ModThread
+{
+ std::wstring path;
+ env::Directory* dir = nullptr;
+ std::condition_variable cv;
+ std::mutex mutex;
+ bool ready = false;
+
+ void wakeup()
+ {
+ ready = true;
+ cv.notify_one();
+ }
+
+ void run()
+ {
+ std::unique_lock lock(mutex);
+ cv.wait(lock, [&]{ return ready; });
+
+ *dir = env::getFilesAndDirs(path);
+
+ ready = false;
+ }
+};
+
+void DirectoryRefresher::addMultipleModsFilesToStructure(
+ MOShared::DirectoryEntry *directoryStructure,
+ const std::vector& entries, bool emitProgress)
+{
+ TimeThis tt(QString("add %1 mods").arg(entries.size()));
+
+ env::ThreadPool threads(m_threadCount);
+ std::vector dirs(entries.size());
+
+ for (std::size_t i=0; i(i + 1);
+
+ try {
+ if (e.stealFiles.length() > 0) {
+ stealModFilesIntoStructure(
+ directoryStructure, e.modName, prio, e.absolutePath, e.stealFiles);
+ } else {
+ auto& mt = threads.request();
+
+ mt.path = QDir::toNativeSeparators(e.absolutePath).toStdWString();
+ mt.dir = &dirs[i];
+
+ mt.wakeup();
+ }
+ } 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);
+ }
+ }
+
+ threads.join();
+
+ for (std::size_t i=0; i(i + 1);
+
+ directoryStructure->addFromList(
+ entries[i].modName.toStdWString(),
+ entries[i].absolutePath.toStdWString(),
+ dirs[i],
+ prio);
+
+ if (Settings::instance().archiveParsing()) {
+ addModBSAToStructure(
+ directoryStructure,
+ entries[i].modName,
+ prio,
+ entries[i].absolutePath,
+ entries[i].archives);
+ }
+ }
+}
+
void DirectoryRefresher::refresh()
{
SetThisThreadName("DirectoryRefresher");
- TimeThis tt("DirectoryRefresher::refresh()");
QMutexLocker locker(&m_RefreshLock);
@@ -178,20 +280,16 @@ void DirectoryRefresher::refresh()
IPluginGame *game = qApp->property("managed_game").value();
- std::wstring dataDirectory = QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
+ std::wstring dataDirectory =
+ QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
+
m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0);
- std::sort(m_Mods.begin(), m_Mods.end(), [](auto lhs, auto rhs){return lhs.priority < rhs.priority;});
- auto iter = m_Mods.begin();
+ std::sort(m_Mods.begin(), m_Mods.end(), [](auto lhs, auto rhs) {
+ return lhs.priority < rhs.priority;
+ });
- for (int i = 1; iter != m_Mods.end(); ++iter, ++i) {
- try {
- addModToStructure(m_DirectoryStructure, iter->modName, i, iter->absolutePath, iter->stealFiles, iter->archives);
- } catch (const std::exception &e) {
- emit error(tr("failed to read mod (%1): %2").arg(iter->modName, e.what()));
- }
- emit progress((i * 100) / static_cast(m_Mods.size()) + 1);
- }
+ addMultipleModsFilesToStructure(m_DirectoryStructure, m_Mods, true);
m_DirectoryStructure->getFileRegister()->sortOrigins();
diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h
index a4fc5dbc..c531ba39 100644
--- a/src/directoryrefresher.h
+++ b/src/directoryrefresher.h
@@ -39,12 +39,23 @@ class DirectoryRefresher : public QObject
Q_OBJECT
public:
+ 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) {}
+ QString modName;
+ QString absolutePath;
+ QStringList stealFiles;
+ QStringList archives;
+ int priority;
+ };
/**
* @brief constructor
*
**/
- DirectoryRefresher();
+ DirectoryRefresher(std::size_t threadCount);
~DirectoryRefresher();
@@ -53,7 +64,7 @@ public:
*
* returns a pointer to the updated directory structure. DirectoryRefresher
* deletes its own pointer and the caller takes custody of the pointer
- *
+ *
* @return updated directory structure
**/
MOShared::DirectoryEntry *getDirectoryStructure();
@@ -107,7 +118,13 @@ public:
* @param directory
* @param stealFiles
*/
- void addModFilesToStructure(MOShared::DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &stealFiles);
+ void addModFilesToStructure(
+ MOShared::DirectoryEntry *directoryStructure, const QString &modName,
+ int priority, const QString &directory, const QStringList &stealFiles);
+
+ void addMultipleModsFilesToStructure(
+ MOShared::DirectoryEntry *directoryStructure,
+ const std::vector& entries, bool emitProgress=false);
public slots:
@@ -123,26 +140,15 @@ signals:
void refreshed();
private:
-
- 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) {}
- QString modName;
- QString absolutePath;
- QStringList stealFiles;
- QStringList archives;
- int priority;
- };
-
-private:
-
std::vector m_Mods;
std::set m_EnabledArchives;
MOShared::DirectoryEntry *m_DirectoryStructure;
QMutex m_RefreshLock;
+ std::size_t m_threadCount;
+ void stealModFilesIntoStructure(
+ MOShared::DirectoryEntry *directoryStructure, const QString &modName,
+ int priority, const QString &directory, const QStringList &stealFiles);
};
#endif // DIRECTORYREFRESHER_H
diff --git a/src/envfs.cpp b/src/envfs.cpp
index 81a0d3ef..2716737f 100644
--- a/src/envfs.cpp
+++ b/src/envfs.cpp
@@ -150,44 +150,62 @@ QString toString(POBJECT_ATTRIBUTES poa)
}
-constexpr std::size_t AllocSize = 1024 * 1024;
-std::vector> g_buffers;
-
-
-struct HandleCloserThread
+class HandleCloserThread
{
- std::vector handles;
- std::thread thread;
- std::atomic busy;
-
+public:
HandleCloserThread()
- : busy(false)
+ : m_ready(false)
{
+ m_handles.reserve(50'000);
}
- ~HandleCloserThread()
+ void add(HANDLE h)
{
- if (thread.joinable()) {
- thread.join();
- }
+ m_handles.push_back(h);
+ }
+
+ void wakeup()
+ {
+ m_ready = true;
+ m_cv.notify_one();
+ }
+
+ void run()
+ {
+ std::unique_lock lock(m_mutex);
+ m_cv.wait(lock, [&]{ return m_ready; });
+
+ closeHandles();
}
+private:
+ std::vector m_handles;
+ std::condition_variable m_cv;
+ std::mutex m_mutex;
+ bool m_ready;
+
void closeHandles()
{
- for (auto& h : handles) {
+ for (auto& h : m_handles) {
NtClose(h);
}
- handles.clear();
- busy = false;
+ m_handles.clear();
+ m_ready = false;
}
};
-std::array g_handleCloserThreads;
+constexpr std::size_t AllocSize = 1024 * 1024;
+static ThreadPool g_handleClosers;
+void setHandleCloserThreadCount(std::size_t n)
+{
+ g_handleClosers.setMax(n);
+}
void forEachEntryImpl(
- void* cx, HandleCloserThread& hc, POBJECT_ATTRIBUTES poa, std::size_t depth,
+ void* cx, HandleCloserThread& hc, std::vector>& buffers,
+ POBJECT_ATTRIBUTES poa, std::size_t depth,
DirStartF* dirStartF, DirEndF* dirEndF, FileF* fileF)
{
IO_STATUS_BLOCK iosb;
@@ -207,14 +225,14 @@ void forEachEntryImpl(
return;
}
- hc.handles.push_back(oa.RootDirectory);
+ hc.add(oa.RootDirectory);
unsigned char* buffer;
- if (depth >= g_buffers.size()) {
- g_buffers.emplace_back(std::make_unique(AllocSize));
- buffer = g_buffers.back().get();
+ if (depth >= buffers.size()) {
+ buffers.emplace_back(std::make_unique(AllocSize));
+ buffer = buffers.back().get();
} else {
- buffer = g_buffers[depth].get();
+ buffer = buffers[depth].get();
}
union
@@ -268,7 +286,7 @@ void forEachEntryImpl(
if (DirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
dirStartF(cx, toStringView(&oa));
- forEachEntryImpl(cx, hc, &oa, depth+1, dirStartF, dirEndF, fileF);
+ forEachEntryImpl(cx, hc, buffers, &oa, depth+1, dirStartF, dirEndF, fileF);
dirEndF(cx, toStringView(&oa));
} else {
//log::debug("{}{}", std::wstring((depth + 1) * 2, L' '), toString(&oa));
@@ -293,35 +311,13 @@ void forEachEntryImpl(
}
}
-std::size_t findHandleCloserThread()
-{
- for (;;) {
- for (std::size_t i=0; i> buffers;
if (!NtOpenFile) {
HMODULE m = ::LoadLibraryW(L"ntdll.dll");
@@ -342,9 +338,41 @@ void forEachEntry(
oa.Length = sizeof(oa);
oa.ObjectName = &ObjectName;
- forEachEntryImpl(cx, hc, &oa, 0, dirStartF, dirEndF, fileF);
+ forEachEntryImpl(cx, hc, buffers, &oa, 0, dirStartF, dirEndF, fileF);
+ hc.wakeup();
+}
+
+Directory getFilesAndDirs(const std::wstring& path)
+{
+ struct Context
+ {
+ std::stack current;
+ };
+
+ Directory root;
+
+ Context cx;
+ cx.current.push(&root);
+
+ env::forEachEntry(path, &cx,
+ [](void* pcx, std::wstring_view path) {
+ Context* cx = (Context*)pcx;
+ cx->current.top()->dirs.push_back({std::wstring(path.begin(), path.end())});
+ cx->current.push(&cx->current.top()->dirs.back());
+ },
+
+ [](void* pcx, std::wstring_view path) {
+ Context* cx = (Context*)pcx;
+ cx->current.pop();
+ },
+
+ [](void* pcx, std::wstring_view path, FILETIME ft) {
+ Context* cx = (Context*)pcx;
+ cx->current.top()->files.push_back({std::wstring(path.begin(), path.end()), ft});
+ }
+ );
- hc.thread = std::thread([hci]{ g_handleCloserThreads[hci].closeHandles(); });
+ return root;
}
} // namespace
diff --git a/src/envfs.h b/src/envfs.h
index aeaa6796..1fc53bcf 100644
--- a/src/envfs.h
+++ b/src/envfs.h
@@ -1,17 +1,105 @@
#ifndef ENV_ENVFS_H
#define ENV_ENVFS_H
+#include
+
namespace env
{
+struct File
+{
+ std::wstring name;
+ FILETIME ft;
+};
+
+struct Directory
+{
+ std::wstring name;
+ std::list dirs;
+ std::list files;
+};
+
+
+template
+class ThreadPool
+{
+public:
+ ThreadPool(std::size_t max=1)
+ : m_threads(max)
+ {
+ }
+
+ ~ThreadPool()
+ {
+ join();
+ }
+
+ void setMax(std::size_t n)
+ {
+ m_threads.resize(n);
+ }
+
+ void join()
+ {
+ for (auto& ti : m_threads) {
+ if (ti.thread.joinable()) {
+ ti.thread.join();
+ }
+ }
+ }
+
+ T& request()
+ {
+ if (m_threads.empty()) {
+ std::terminate();
+ }
+
+ for (;;) {
+ for (auto& ti : m_threads) {
+ bool expected = false;
+
+ if (ti.busy.compare_exchange_strong(expected, true)) {
+ if (ti.thread.joinable()) {
+ ti.thread.join();
+ }
+
+ ti.thread = std::thread([&]{
+ ti.o.run();
+ ti.busy = false;
+ });
+
+ return ti.o;
+ }
+ }
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ }
+ }
+
+private:
+ struct ThreadInfo
+ {
+ std::thread thread;
+ std::atomic busy;
+ T o;
+ };
+
+ std::list m_threads;
+};
+
+
using DirStartF = void (void*, std::wstring_view);
using DirEndF = void (void*, std::wstring_view);
using FileF = void (void*, std::wstring_view, FILETIME);
+void setHandleCloserThreadCount(std::size_t n);
+
void forEachEntry(
const std::wstring& path, void* cx,
DirStartF* dirStartF, DirEndF* dirEndF, FileF* fileF);
+Directory getFilesAndDirs(const std::wstring& path);
+
} // namespace
#endif // ENV_ENVFS_H
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 8124be1d..86abeb35 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -88,24 +88,19 @@ QStringList toStringList(InputIterator current, InputIterator end)
OrganizerCore::OrganizerCore(Settings &settings)
: m_UserInterface(nullptr)
, m_PluginContainer(nullptr)
- , m_GameName()
, m_CurrentProfile(nullptr)
, m_Settings(settings)
, m_Updater(NexusInterface::instance(m_PluginContainer))
- , m_AboutToRun()
- , m_FinishedRun()
- , m_ModInstalled()
, m_ModList(m_PluginContainer, this)
, m_PluginList(this)
- , m_DirectoryRefresher()
+ , m_DirectoryRefresher(settings.refreshThreadCount())
, m_DirectoryStructure(new DirectoryEntry(L"data", nullptr, 0))
, m_DownloadManager(NexusInterface::instance(m_PluginContainer), this)
- , m_InstallationManager()
- , m_RefresherThread()
, m_DirectoryUpdate(false)
, m_ArchivesInit(false)
, m_PluginListsWriter(std::bind(&OrganizerCore::savePluginList, this))
{
+ env::setHandleCloserThreadCount(settings.refreshThreadCount());
m_DownloadManager.setOutputDirectory(m_Settings.paths().downloads(), false);
NexusInterface::instance(m_PluginContainer)->setCacheDirectory(
@@ -1245,13 +1240,17 @@ void OrganizerCore::updateModInDirectoryStructure(unsigned int index,
void OrganizerCore::updateModsInDirectoryStructure(QMap modInfo)
{
+ std::vector entries;
+
for (auto idx : modInfo.keys()) {
- // add files of the bsa to the directory structure
- m_DirectoryRefresher.addModFilesToStructure(
- m_DirectoryStructure, modInfo[idx]->name(),
- m_CurrentProfile->getModPriority(idx), modInfo[idx]->absolutePath(),
- modInfo[idx]->stealFiles());
+ entries.push_back({
+ modInfo[idx]->name(), modInfo[idx]->absolutePath(),
+ modInfo[idx]->stealFiles(), {}, m_CurrentProfile->getModPriority(idx)});
}
+
+ m_DirectoryRefresher.addMultipleModsFilesToStructure(
+ m_DirectoryStructure, entries);
+
DirectoryRefresher::cleanStructure(m_DirectoryStructure);
// need to refresh plugin list now so we can activate esps
refreshESPList(true);
diff --git a/src/settings.cpp b/src/settings.cpp
index 761cd669..f0496fe8 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -209,6 +209,16 @@ void Settings::setUseSplash(bool b)
set(m_Settings, "Settings", "use_splash", b);
}
+std::size_t Settings::refreshThreadCount() const
+{
+ return get(m_Settings, "Settings", "refresh_thread_count", 10);
+}
+
+void Settings::setRefreshThreadCount(std::size_t n) const
+{
+ return set(m_Settings, "Settings", "refresh_thread_count", n);
+}
+
std::optional Settings::version() const
{
if (auto v=getOptional(m_Settings, "General", "version")) {
diff --git a/src/settings.h b/src/settings.h
index 3d37bdd8..b2cb6be5 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -731,6 +731,11 @@ public:
bool useSplash() const;
void setUseSplash(bool b);
+ // number of threads to use when refreshing
+ //
+ std::size_t refreshThreadCount() const;
+ void setRefreshThreadCount(std::size_t n) const;
+
GameSettings& game();
const GameSettings& game() const;
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index d171be38..b7329833 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -691,6 +691,33 @@ void DirectoryEntry::addFromOrigin(
m_Populated = true;
}
+void DirectoryEntry::addFromList(
+ const std::wstring &originName, const std::wstring &directory,
+ env::Directory& root, int priority)
+{
+ FilesOrigin &origin = createOrigin(originName, directory, priority);
+ addDir(origin, root);
+}
+
+void DirectoryEntry::addDir(FilesOrigin& origin, env::Directory& d)
+{
+ for (auto& sd : d.dirs) {
+ auto* sdirEntry = getSubDirectory(sd.name, true, origin.getID());
+ sdirEntry->addDir(origin, sd);
+ }
+
+ for (auto& f : d.files) {
+ insert(f.name, origin, f.ft, L"", -1);
+ }
+
+ std::sort(
+ m_SubDirectories.begin(),
+ m_SubDirectories.end(),
+ &DirCompareByName);
+
+ m_Populated = true;
+}
+
void DirectoryEntry::addFromBSA(
const std::wstring &originName, std::wstring &directory,
const std::wstring &fileName, int priority, int order)
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index 58e70ffa..772899d7 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -33,7 +33,9 @@ along with Mod Organizer. If not, see .
#include
#include
#endif
+
#include "util.h"
+#include "envfs.h"
namespace MOShared { struct DirectoryEntryFileKey; }
@@ -358,6 +360,10 @@ public:
const std::wstring &originName, std::wstring &directory,
const std::wstring &fileName, int priority, int order);
+ void addFromList(
+ const std::wstring &originName, const std::wstring &directory,
+ env::Directory& root, int priority);
+
void propagateOrigin(int origin);
const std::wstring &getName() const
@@ -511,6 +517,8 @@ private:
FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime,
const std::wstring &archiveName, int order);
+ void addDir(FilesOrigin& origin, env::Directory& d);
+
DirectoryEntry* getSubDirectory(
std::wstring_view name, bool create, int originID = -1);
--
cgit v1.3.1
From 567fe019ac21ee78a07beae1a387ab5688e7f97b Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 14 Feb 2020 01:53:59 -0500
Subject: removed some unnecessary counters delete old structure in thread
---
src/directoryrefresher.cpp | 69 ++++++++++++++++++-------------------------
src/directoryrefresher.h | 2 +-
src/organizercore.cpp | 68 +++++++++++++++++++++++++++++++-----------
src/organizercore.h | 2 ++
src/shared/directoryentry.cpp | 48 ------------------------------
src/shared/directoryentry.h | 3 --
6 files changed, 82 insertions(+), 110 deletions(-)
(limited to 'src/organizercore.cpp')
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index a59ddf9d..cb5bfc5b 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -48,7 +48,7 @@ DirectoryRefresher::~DirectoryRefresher()
delete m_DirectoryStructure;
}
-DirectoryEntry *DirectoryRefresher::getDirectoryStructure()
+DirectoryEntry *DirectoryRefresher::stealDirectoryStructure()
{
QMutexLocker locker(&m_RefreshLock);
DirectoryEntry *result = m_DirectoryStructure;
@@ -279,58 +279,50 @@ void DirectoryRefresher::addMultipleModsFilesToStructure(
g_threads.setMax(m_threadCount);
- {
- TimeThis tt("walk dirs");
-
- for (std::size_t i=0; i(i + 1);
+ for (std::size_t i=0; i(i + 1);
- stats[i].mod = entries[i].modName.toStdString();
+ stats[i].mod = entries[i].modName.toStdString();
- try
- {
- if (e.stealFiles.length() > 0) {
- stealModFilesIntoStructure(
- directoryStructure, e.modName, prio, e.absolutePath, e.stealFiles);
- } else {
- auto& mt = g_threads.request();
-
- mt.ds = directoryStructure;
- mt.modName = entries[i].modName.toStdWString();
- mt.path = QDir::toNativeSeparators(e.absolutePath).toStdWString();
- mt.prio = prio;
- mt.stats = &stats[i];
-
- mt.wakeup();
- }
- } 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);
+ try
+ {
+ if (e.stealFiles.length() > 0) {
+ stealModFilesIntoStructure(
+ directoryStructure, e.modName, prio, e.absolutePath, e.stealFiles);
+ } else {
+ auto& mt = g_threads.request();
+
+ mt.ds = directoryStructure;
+ mt.modName = entries[i].modName.toStdWString();
+ mt.path = QDir::toNativeSeparators(e.absolutePath).toStdWString();
+ mt.prio = prio;
+ mt.stats = &stats[i];
+
+ mt.wakeup();
}
+ } catch (const std::exception& ex) {
+ emit error(tr("failed to read mod (%1): %2").arg(e.modName, ex.what()));
}
- g_threads.waitForAll();
+ if (emitProgress) {
+ emit progress((static_cast(i) * 100) / static_cast(entries.size()) + 1);
+ }
}
+ g_threads.waitForAll();
+
dumpStats(stats);
}
-namespace MOShared{ void logcounts(std::string w); }
-
void DirectoryRefresher::refresh()
{
SetThisThreadName("DirectoryRefresher");
+ TimeThis tt("refresh");
for (int i=0; i<1; ++i) {
QMutexLocker locker(&m_RefreshLock);
-
- //logcounts("before delete");
delete m_DirectoryStructure;
- //logcounts("after delete");
m_DirectoryStructure = new DirectoryEntry(L"data", nullptr, 0);
@@ -355,9 +347,6 @@ void DirectoryRefresher::refresh()
cleanStructure(m_DirectoryStructure);
}
- emit progress(100);
-
+ emit progress(100);
emit refreshed();
-
- //logcounts("after refresh");
}
diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h
index c531ba39..18bfed4d 100644
--- a/src/directoryrefresher.h
+++ b/src/directoryrefresher.h
@@ -67,7 +67,7 @@ public:
*
* @return updated directory structure
**/
- MOShared::DirectoryEntry *getDirectoryStructure();
+ MOShared::DirectoryEntry* stealDirectoryStructure();
/**
* @brief sets up the mods to be included in the directory structure
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 86abeb35..a3202153 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -144,6 +144,10 @@ OrganizerCore::~OrganizerCore()
m_RefresherThread.exit();
m_RefresherThread.wait();
+ if (m_StructureDeleter.joinable()) {
+ m_StructureDeleter.join();
+ }
+
saveCurrentProfile();
// profile has to be cleaned up before the modinfo-buffer is cleared
@@ -1379,46 +1383,74 @@ std::vector OrganizerCore::enabledArchives()
void OrganizerCore::refreshDirectoryStructure()
{
- if (!m_DirectoryUpdate) {
- m_CurrentProfile->writeModlistNow(true);
+ if (m_DirectoryUpdate) {
+ log::debug("can't refresh, already in progress");
+ return;
+ }
- m_DirectoryUpdate = true;
- std::vector> activeModList
- = m_CurrentProfile->getActiveMods();
- auto archives = enabledArchives();
- m_DirectoryRefresher.setMods(
- activeModList, std::set(archives.begin(), archives.end()));
+ log::debug("refreshing structure");
+ m_DirectoryUpdate = true;
- QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh()));
- }
+ m_CurrentProfile->writeModlistNow(true);
+ const auto activeModList = m_CurrentProfile->getActiveMods();
+ const auto archives = enabledArchives();
+
+ m_DirectoryRefresher.setMods(
+ activeModList, std::set(archives.begin(), archives.end()));
+
+ // runs refresh() in a thread
+ QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh()));
}
void OrganizerCore::directory_refreshed()
{
- DirectoryEntry *newStructure = m_DirectoryRefresher.getDirectoryStructure();
+ log::debug("structure refreshed");
+
+ DirectoryEntry *newStructure = m_DirectoryRefresher.stealDirectoryStructure();
Q_ASSERT(newStructure != m_DirectoryStructure);
- if (newStructure != nullptr) {
- std::swap(m_DirectoryStructure, newStructure);
- delete newStructure;
- } else {
+
+ if (newStructure == nullptr) {
// TODO: don't know why this happens, this slot seems to get called twice
// with only one emit
return;
}
+
+ std::swap(m_DirectoryStructure, newStructure);
+
+ if (m_StructureDeleter.joinable()) {
+ m_StructureDeleter.join();
+ }
+
+ m_StructureDeleter = std::thread([=]{
+ log::debug("structure deleter thread start");
+ delete newStructure;
+ log::debug("structure deleter thread done");
+ });
+
m_DirectoryUpdate = false;
+ log::debug("clearing caches");
for (int i = 0; i < m_ModList.rowCount(); ++i) {
ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
modInfo->clearCaches();
}
- for (auto task : m_PostRefreshTasks) {
- task();
+
+ if (!m_PostRefreshTasks.empty()) {
+ log::debug("running {} post refresh tasks", m_PostRefreshTasks.size());
+
+ for (auto task : m_PostRefreshTasks) {
+ task();
+ }
+
+ m_PostRefreshTasks.clear();
}
- m_PostRefreshTasks.clear();
if (m_CurrentProfile != nullptr) {
+ log::debug("refreshing lists");
refreshLists();
}
+
+ log::debug("refresh done");
}
void OrganizerCore::profileRefresh()
diff --git a/src/organizercore.h b/src/organizercore.h
index a63dc959..223eb6cb 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -346,6 +346,8 @@ private:
QThread m_RefresherThread;
+ std::thread m_StructureDeleter;
+
bool m_DirectoryUpdate;
bool m_ArchivesInit;
bool m_ArchiveParsing{ m_Settings.archiveParsing() };
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index 4e64d1c1..c5702026 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -40,13 +40,6 @@ namespace MOShared
using namespace MOBase;
static const int MAXPATH_UNICODE = 32767;
-
-static std::atomic FileEntryCount(0);
-static std::atomic FilesOriginCount(0);
-static std::atomic FileRegisterCount(0);
-static std::atomic DirectoryEntryCount(0);
-static std::atomic OriginConnectionCount(0);
-
template
std::chrono::nanoseconds elapsed(F&& f)
{
@@ -56,13 +49,6 @@ std::chrono::nanoseconds elapsed(F&& f)
return (end - start);
}
-void logcounts(std::string w)
-{
- log::debug(
- "{}: FileEntry={} FilesOrigin={} FileRegister={} DirectoryEntry={} OriginConnection={}",
- w, FileEntryCount, FilesOriginCount, FileRegisterCount, DirectoryEntryCount, OriginConnectionCount);
-}
-
static std::wstring tail(const std::wstring &source, const size_t count)
{
@@ -203,12 +189,6 @@ public:
OriginConnection()
: m_NextID(0)
{
- ++OriginConnectionCount;
- }
-
- ~OriginConnection()
- {
- --OriginConnectionCount;
}
std::pair getOrCreate(
@@ -350,7 +330,6 @@ FileEntry::FileEntry() :
m_FileSize(NoFileSize), m_CompressedFileSize(NoFileSize),
m_LastAccessed(time(nullptr))
{
- ++FileEntryCount;
}
FileEntry::FileEntry(Index index, std::wstring name, DirectoryEntry *parent) :
@@ -358,16 +337,6 @@ FileEntry::FileEntry(Index index, std::wstring name, DirectoryEntry *parent) :
m_FileSize(NoFileSize), m_CompressedFileSize(NoFileSize),
m_LastAccessed(time(nullptr))
{
- ++FileEntryCount;
-}
-
-FileEntry::~FileEntry()
-{
- while (!m_Alternatives.empty()) {
- m_Alternatives.pop_back();
- }
-
- --FileEntryCount;
}
void FileEntry::addOrigin(
@@ -606,7 +575,6 @@ bool FileEntry::recurseParents(std::wstring &path, const DirectoryEntry *parent)
FilesOrigin::FilesOrigin()
: m_ID(0), m_Disabled(false), m_Name(), m_Path(), m_Priority(0)
{
- ++FilesOriginCount;
}
FilesOrigin::FilesOrigin(const FilesOrigin &reference)
@@ -618,7 +586,6 @@ FilesOrigin::FilesOrigin(const FilesOrigin &reference)
, m_FileRegister(reference.m_FileRegister)
, m_OriginConnection(reference.m_OriginConnection)
{
- ++FilesOriginCount;
}
FilesOrigin::FilesOrigin(
@@ -629,12 +596,6 @@ FilesOrigin::FilesOrigin(
m_Priority(priority), m_FileRegister(fileRegister),
m_OriginConnection(originConnection)
{
- ++FilesOriginCount;
-}
-
-FilesOrigin::~FilesOrigin()
-{
- --FilesOriginCount;
}
void FilesOrigin::setPriority(int priority)
@@ -733,12 +694,6 @@ bool FilesOrigin::containsArchive(std::wstring archiveName)
FileRegister::FileRegister(boost::shared_ptr originConnection)
: m_OriginConnection(originConnection)
{
- ++FileRegisterCount;
-}
-
-FileRegister::~FileRegister()
-{
- --FileRegisterCount;
}
bool FileRegister::indexValid(FileEntry::Index index) const
@@ -907,7 +862,6 @@ DirectoryEntry::DirectoryEntry(
m_OriginConnection(new OriginConnection),
m_Name(std::move(name)), m_Parent(parent), m_Populated(false), m_TopLevel(true)
{
- ++DirectoryEntryCount;
m_FileRegister.reset(new FileRegister(m_OriginConnection));
m_Origins.insert(originID);
}
@@ -919,13 +873,11 @@ DirectoryEntry::DirectoryEntry(
m_FileRegister(fileRegister), m_OriginConnection(originConnection),
m_Name(std::move(name)), m_Parent(parent), m_Populated(false), m_TopLevel(false)
{
- ++DirectoryEntryCount;
m_Origins.insert(originID);
}
DirectoryEntry::~DirectoryEntry()
{
- --DirectoryEntryCount;
clear();
}
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index 2a70d486..94ea068d 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -121,7 +121,6 @@ public:
FileEntry();
FileEntry(Index index, std::wstring name, DirectoryEntry *parent);
- ~FileEntry();
Index getIndex() const
{
@@ -237,7 +236,6 @@ class FilesOrigin
public:
FilesOrigin();
FilesOrigin(const FilesOrigin &reference);
- ~FilesOrigin();
// sets priority for this origin, but it will overwrite the existing mapping
// for this priority, the previous origin will no longer be referenced
@@ -307,7 +305,6 @@ class FileRegister
{
public:
FileRegister(boost::shared_ptr originConnection);
- ~FileRegister();
bool indexValid(FileEntry::Index index) const;
--
cgit v1.3.1
From b1cf498924e461556c8f2fe961172685d92bb03f Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 15 Feb 2020 13:24:56 -0500
Subject: split directoryentry made classes noncopyable, fixed a few unintended
copies
---
src/CMakeLists.txt | 21 +-
src/datatab.cpp | 1 -
src/directoryrefresher.cpp | 11 +-
src/directoryrefresher.h | 5 +-
src/filetree.cpp | 3 +
src/filetreeitem.h | 6 +-
src/filetreemodel.cpp | 12 +-
src/filetreemodel.h | 6 +-
src/loglist.h | 3 +-
src/main.cpp | 1 +
src/mainwindow.cpp | 14 +-
src/modinfodialog.cpp | 2 +
src/modinfodialogconflicts.cpp | 21 +-
src/modinfodialogconflicts.h | 14 +-
src/modinfodialogtab.cpp | 2 +-
src/modinfowithconflictinfo.cpp | 11 +-
src/modlist.cpp | 8 +-
src/modlist.h | 1 -
src/organizercore.cpp | 7 +-
src/organizercore.h | 1 -
src/pch.h | 4 +
src/pluginlist.cpp | 16 +-
src/pluginlist.h | 1 -
src/shared/directoryentry.cpp | 745 ++--------------------------------------
src/shared/directoryentry.h | 368 ++------------------
src/shared/fileentry.cpp | 251 ++++++++++++++
src/shared/fileentry.h | 125 +++++++
src/shared/fileregister.cpp | 184 ++++++++++
src/shared/fileregister.h | 58 ++++
src/shared/fileregisterfwd.h | 89 +++++
src/shared/filesorigin.cpp | 137 ++++++++
src/shared/filesorigin.h | 87 +++++
src/shared/originconnection.cpp | 145 ++++++++
src/shared/originconnection.h | 59 ++++
src/syncoverwritedialog.cpp | 7 +-
src/syncoverwritedialog.h | 11 +-
36 files changed, 1310 insertions(+), 1127 deletions(-)
create mode 100644 src/shared/fileentry.cpp
create mode 100644 src/shared/fileentry.h
create mode 100644 src/shared/fileregister.cpp
create mode 100644 src/shared/fileregister.h
create mode 100644 src/shared/fileregisterfwd.h
create mode 100644 src/shared/filesorigin.cpp
create mode 100644 src/shared/filesorigin.h
create mode 100644 src/shared/originconnection.cpp
create mode 100644 src/shared/originconnection.h
(limited to 'src/organizercore.cpp')
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e121c572..85d8af0f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -155,6 +155,10 @@ SET(organizer_SRCS
shared/windows_error.cpp
shared/error_report.cpp
shared/directoryentry.cpp
+ shared/fileentry.cpp
+ shared/filesorigin.cpp
+ shared/fileregister.cpp
+ shared/originconnection.cpp
shared/util.cpp
shared/appconfig.cpp
shared/leaktrace.cpp
@@ -286,6 +290,10 @@ SET(organizer_HDRS
shared/windows_error.h
shared/error_report.h
shared/directoryentry.h
+ shared/fileentry.h
+ shared/filesorigin.h
+ shared/fileregister.h
+ shared/originconnection.h
shared/util.h
shared/appconfig.h
shared/appconfig.inc
@@ -350,8 +358,6 @@ set(browser
set(core
categories
- shared/directoryentry
- directoryrefresher
installationmanager
instancemanager
loadmechanism
@@ -470,6 +476,15 @@ set(profiles
profilesdialog
)
+set(register
+ shared/directoryentry
+ shared/fileentry
+ shared/filesorigin
+ shared/fileregister
+ shared/originconnection
+ directoryrefresher
+)
+
set(settings
settings
settingsutilities
@@ -521,7 +536,7 @@ set(widgets
set(src_filters
application core browser dialogs downloads env executables loot mainwindow
- modinfo modinfo\\dialog modlist plugins previews profiles settings
+ modinfo modinfo\\dialog modlist plugins previews profiles register settings
settingsdialog utilities widgets
)
diff --git a/src/datatab.cpp b/src/datatab.cpp
index 19bfa134..b6119d52 100644
--- a/src/datatab.cpp
+++ b/src/datatab.cpp
@@ -2,7 +2,6 @@
#include "ui_mainwindow.h"
#include "settings.h"
#include "organizercore.h"
-#include "directoryentry.h"
#include "messagedialog.h"
#include "filetree.h"
#include "filetreemodel.h"
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index 8bf349f1..3b92389a 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -18,6 +18,9 @@ along with Mod Organizer. If not, see .
*/
#include "directoryrefresher.h"
+#include "shared/fileentry.h"
+#include "shared/filesorigin.h"
+#include "shared/directoryentry.h"
#include "iplugingame.h"
#include "utility.h"
@@ -26,12 +29,16 @@ along with Mod Organizer. If not, see .
#include "settings.h"
#include "envfs.h"
#include "modinfodialogfwd.h"
+#include "util.h"
+
+#include
#include
#include
#include
#include
-#include
+
+#include
using namespace MOBase;
@@ -136,7 +143,7 @@ void DirectoryRefresher::stealModFilesIntoStructure(
continue;
}
QFileInfo fileInfo(filename);
- FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
+ FileEntryPtr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
if (file.get() != nullptr) {
if (file->getOrigin() == 0) {
// replace data as the origin on this bsa
diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h
index 5c829980..2102140c 100644
--- a/src/directoryrefresher.h
+++ b/src/directoryrefresher.h
@@ -20,7 +20,6 @@ along with Mod Organizer. If not, see .
#ifndef DIRECTORYREFRESHER_H
#define DIRECTORYREFRESHER_H
-#include
#include
#include
#include
@@ -59,6 +58,10 @@ public:
~DirectoryRefresher();
+ // noncopyable
+ DirectoryRefresher(const DirectoryRefresher&) = delete;
+ DirectoryRefresher& operator=(const DirectoryRefresher&) = delete;
+
/**
* @brief retrieve the updated directory structure
*
diff --git a/src/filetree.cpp b/src/filetree.cpp
index f628dff3..cdcf2feb 100644
--- a/src/filetree.cpp
+++ b/src/filetree.cpp
@@ -3,6 +3,9 @@
#include "filetreeitem.h"
#include "organizercore.h"
#include "envshell.h"
+#include "shared/fileentry.h"
+#include "shared/directoryentry.h"
+#include "shared/filesorigin.h"
#include
#include
diff --git a/src/filetreeitem.h b/src/filetreeitem.h
index 390d5499..2092782e 100644
--- a/src/filetreeitem.h
+++ b/src/filetreeitem.h
@@ -1,7 +1,7 @@
#ifndef MODORGANIZER_FILETREEITEM_INCLUDED
#define MODORGANIZER_FILETREEITEM_INCLUDED
-#include "directoryentry.h"
+#include "shared/fileregisterfwd.h"
#include
class FileTreeModel;
@@ -126,7 +126,7 @@ public:
return m_wsLcFile;
}
- const MOShared::DirectoryEntry::FileKey& key() const
+ const MOShared::DirectoryEntryFileKey& key() const
{
return m_key;
}
@@ -288,7 +288,7 @@ private:
const QString m_virtualParentPath;
const std::wstring m_wsFile, m_wsLcFile;
- const MOShared::DirectoryEntry::FileKey m_key;
+ const MOShared::DirectoryEntryFileKey m_key;
const QString m_file;
const bool m_isDirectory;
diff --git a/src/filetreemodel.cpp b/src/filetreemodel.cpp
index 2130bf89..1a5433c5 100644
--- a/src/filetreemodel.cpp
+++ b/src/filetreemodel.cpp
@@ -1,5 +1,9 @@
#include "filetreemodel.h"
#include "organizercore.h"
+#include "filesorigin.h"
+#include "util.h"
+#include "shared/directoryentry.h"
+#include "shared/fileentry.h"
#include
using namespace MOBase;
@@ -637,7 +641,7 @@ bool FileTreeModel::updateFiles(
// removeDisappearingFiles() will add files that are in the tree and still on
// the filesystem to this set; addNewFiless() will use this to figure out if
// a file is new or not
- std::unordered_set seen;
+ std::unordered_set seen;
int firstFileRow = 0;
@@ -647,7 +651,7 @@ bool FileTreeModel::updateFiles(
void FileTreeModel::removeDisappearingFiles(
FileTreeItem& parentItem, const MOShared::DirectoryEntry& parentEntry,
- int& firstFileRow, std::unordered_set& seen)
+ int& firstFileRow, std::unordered_set& seen)
{
auto& children = parentItem.children();
auto itor = children.begin();
@@ -708,7 +712,7 @@ void FileTreeModel::removeDisappearingFiles(
bool FileTreeModel::addNewFiles(
FileTreeItem& parentItem, const MOShared::DirectoryEntry& parentEntry,
const std::wstring& parentPath, const int firstFileRow,
- const std::unordered_set& seen)
+ const std::unordered_set& seen)
{
// keeps track of the contiguous files that need to be added to
// avoid calling beginAddRows(), etc. for each item
@@ -958,7 +962,7 @@ std::wstring FileTreeModel::makeModName(
{
static const std::wstring Unmanaged = UnmanagedModName().toStdWString();
- const auto origin = m_core.directoryStructure()->getOriginByID(originID);
+ const auto& origin = m_core.directoryStructure()->getOriginByID(originID);
if (origin.getID() == 0) {
return Unmanaged;
diff --git a/src/filetreemodel.h b/src/filetreemodel.h
index 093407b0..5bfb75aa 100644
--- a/src/filetreemodel.h
+++ b/src/filetreemodel.h
@@ -3,7 +3,7 @@
#include "filetreeitem.h"
#include "iconfetcher.h"
-#include "directoryentry.h"
+#include "shared/fileregisterfwd.h"
#include
class OrganizerCore;
@@ -126,12 +126,12 @@ private:
void removeDisappearingFiles(
FileTreeItem& parentItem, const MOShared::DirectoryEntry& parentEntry,
- int& firstFileRow, std::unordered_set& seen);
+ int& firstFileRow, std::unordered_set& seen);
bool addNewFiles(
FileTreeItem& parentItem, const MOShared::DirectoryEntry& parentEntry,
const std::wstring& parentPath, int firstFileRow,
- const std::unordered_set& seen);
+ const std::unordered_set& seen);
FileTreeItem::Ptr createDirectoryItem(
diff --git a/src/loglist.h b/src/loglist.h
index 56b95d65..b26f1561 100644
--- a/src/loglist.h
+++ b/src/loglist.h
@@ -20,8 +20,9 @@ along with Mod Organizer. If not, see .
#ifndef LOGBUFFER_H
#define LOGBUFFER_H
-#include
#include
+#include
+#include
class OrganizerCore;
diff --git a/src/main.cpp b/src/main.cpp
index 6e2220ae..105299a8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -48,6 +48,7 @@ along with Mod Organizer. If not, see .
#include "organizercore.h"
#include "env.h"
#include "envmodule.h"
+#include "util.h"
#include
#include
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index f9f1dfe5..adbac94e 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -20,8 +20,6 @@ along with Mod Organizer. If not, see .
#include "mainwindow.h"
#include "ui_mainwindow.h"
-#include "directoryentry.h"
-#include "directoryrefresher.h"
#include "executableinfo.h"
#include "executableslist.h"
#include "guessedvalue.h"
@@ -89,6 +87,10 @@ along with Mod Organizer. If not, see .
#include "envshortcut.h"
#include "browserdialog.h"
+#include "shared/directoryentry.h"
+#include "shared/fileentry.h"
+#include "shared/filesorigin.h"
+
#include
#include
#include
@@ -1870,7 +1872,7 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString
std::vector> items;
BSAInvalidation * invalidation = m_OrganizerCore.managedGame()->feature();
- std::vector files = m_OrganizerCore.directoryStructure()->getFiles();
+ std::vector files = m_OrganizerCore.directoryStructure()->getFiles();
QStringList plugins = m_OrganizerCore.findFiles("", [](const QString &fileName) -> bool {
return fileName.endsWith(".esp", Qt::CaseInsensitive)
@@ -1889,7 +1891,7 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString
return false;
};
- for (FileEntry::Ptr current : files) {
+ for (FileEntryPtr current : files) {
QFileInfo fileInfo(ToQString(current->getName().c_str()));
if (fileInfo.suffix().toLower() == "bsa" || fileInfo.suffix().toLower() == "ba2") {
@@ -1942,7 +1944,7 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString
for (auto iter = items.begin(); iter != items.end(); ++iter) {
int originID = iter->second->data(1, Qt::UserRole).toInt();
- FilesOrigin origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID);
+ const FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID);
QString modName;
const unsigned int modIndex = ModInfo::getIndex(ToQString(origin.getName()));
@@ -2504,7 +2506,7 @@ void MainWindow::modRenamed(const QString &oldName, const QString &newName)
void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName)
{
- const FileEntry::Ptr filePtr = m_OrganizerCore.directoryStructure()->findFile(ToWString(filePath));
+ const FileEntryPtr filePtr = m_OrganizerCore.directoryStructure()->findFile(ToWString(filePath));
if (filePtr.get() != nullptr) {
try {
if (m_OrganizerCore.directoryStructure()->originExists(ToWString(newOriginName))) {
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index bfb8d2c7..c3239e0d 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -29,6 +29,8 @@ along with Mod Organizer. If not, see .
#include "modinfodialogcategories.h"
#include "modinfodialognexus.h"
#include "modinfodialogfiletree.h"
+#include "shared/directoryentry.h"
+#include "shared/filesorigin.h"
#include
using namespace MOBase;
diff --git a/src/modinfodialogconflicts.cpp b/src/modinfodialogconflicts.cpp
index 63d89a1a..b61dbb7b 100644
--- a/src/modinfodialogconflicts.cpp
+++ b/src/modinfodialogconflicts.cpp
@@ -4,6 +4,9 @@
#include "utility.h"
#include "settings.h"
#include "organizercore.h"
+#include "shared/directoryentry.h"
+#include "shared/filesorigin.h"
+#include "shared/fileentry.h"
using namespace MOShared;
using namespace MOBase;
@@ -17,7 +20,7 @@ class ConflictItem
public:
ConflictItem(
QString before, QString relativeName, QString after,
- FileEntry::Index index, QString fileName,
+ FileIndex index, QString fileName,
bool hasAltOrigins, QString altOrigin, bool archive) :
m_before(std::move(before)),
m_relativeName(std::move(relativeName)),
@@ -65,7 +68,7 @@ public:
return m_isArchive;
}
- FileEntry::Index fileIndex() const
+ FileIndex fileIndex() const
{
return m_index;
}
@@ -104,7 +107,7 @@ private:
QString m_before;
QString m_relativeName;
QString m_after;
- FileEntry::Index m_index;
+ FileIndex m_index;
QString m_fileName;
bool m_hasAltOrigins;
QString m_altOrigin;
@@ -1006,8 +1009,8 @@ bool GeneralConflictsTab::update()
}
ConflictItem GeneralConflictsTab::createOverwriteItem(
- FileEntry::Index index, bool archive, QString fileName, QString relativeName,
- const FileEntry::AlternativesVector& alternatives)
+ FileIndex index, bool archive, QString fileName, QString relativeName,
+ const MOShared::AlternativesVector& alternatives)
{
const auto& ds = *m_core.directoryStructure();
std::wstring altString;
@@ -1028,7 +1031,7 @@ ConflictItem GeneralConflictsTab::createOverwriteItem(
}
ConflictItem GeneralConflictsTab::createNoConflictItem(
- FileEntry::Index index, bool archive, QString fileName, QString relativeName)
+ FileIndex index, bool archive, QString fileName, QString relativeName)
{
return ConflictItem(
QString(), std::move(relativeName), QString(), index,
@@ -1036,7 +1039,7 @@ ConflictItem GeneralConflictsTab::createNoConflictItem(
}
ConflictItem GeneralConflictsTab::createOverwrittenItem(
- FileEntry::Index index, int fileOrigin, bool archive,
+ FileIndex index, int fileOrigin, bool archive,
QString fileName, QString relativeName)
{
const auto& ds = *m_core.directoryStructure();
@@ -1205,9 +1208,9 @@ void AdvancedConflictsTab::update()
}
std::optional AdvancedConflictsTab::createItem(
- FileEntry::Index index, int fileOrigin, bool archive,
+ FileIndex index, int fileOrigin, bool archive,
QString fileName, QString relativeName,
- const MOShared::FileEntry::AlternativesVector& alternatives)
+ const MOShared::AlternativesVector& alternatives)
{
const auto& ds = *m_core.directoryStructure();
diff --git a/src/modinfodialogconflicts.h b/src/modinfodialogconflicts.h
index c4845019..945f464d 100644
--- a/src/modinfodialogconflicts.h
+++ b/src/modinfodialogconflicts.h
@@ -4,7 +4,7 @@
#include "modinfodialogtab.h"
#include "expanderwidget.h"
#include "filterwidget.h"
-#include "directoryentry.h"
+#include "shared/fileregisterfwd.h"
#include
#include
@@ -52,16 +52,16 @@ private:
FilterWidget m_filterNoConflicts;
ConflictItem createOverwriteItem(
- MOShared::FileEntry::Index index, bool archive,
+ MOShared::FileIndex index, bool archive,
QString fileName, QString relativeName,
- const MOShared::FileEntry::AlternativesVector& alternatives);
+ const MOShared::AlternativesVector& alternatives);
ConflictItem createNoConflictItem(
- MOShared::FileEntry::Index index, bool archive,
+ MOShared::FileIndex index, bool archive,
QString fileName, QString relativeName);
ConflictItem createOverwrittenItem(
- MOShared::FileEntry::Index index, int fileOrigin, bool archive,
+ MOShared::FileIndex index, int fileOrigin, bool archive,
QString fileName, QString relativeName);
void onOverwriteActivated(const QModelIndex& index);
@@ -94,9 +94,9 @@ private:
ConflictListModel* m_model;
std::optional createItem(
- MOShared::FileEntry::Index index, int fileOrigin, bool archive,
+ MOShared::FileIndex index, int fileOrigin, bool archive,
QString fileName, QString relativeName,
- const MOShared::FileEntry::AlternativesVector& alternatives);
+ const MOShared::AlternativesVector& alternatives);
};
diff --git a/src/modinfodialogtab.cpp b/src/modinfodialogtab.cpp
index 9748d059..d662e2b2 100644
--- a/src/modinfodialogtab.cpp
+++ b/src/modinfodialogtab.cpp
@@ -1,8 +1,8 @@
#include "modinfodialogtab.h"
#include "ui_modinfodialog.h"
#include "texteditor.h"
-#include "directoryentry.h"
#include "modinfo.h"
+#include "shared/filesorigin.h"
ModInfoDialogTab::ModInfoDialogTab(ModInfoDialogTabContext cx) :
ui(cx.ui), m_core(cx.core), m_plugin(cx.plugin), m_parent(cx.parent),
diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp
index 861782d9..2b4fa11c 100644
--- a/src/modinfowithconflictinfo.cpp
+++ b/src/modinfowithconflictinfo.cpp
@@ -1,7 +1,8 @@
#include "modinfowithconflictinfo.h"
-
-#include "directoryentry.h"
#include "utility.h"
+#include "shared/directoryentry.h"
+#include "shared/filesorigin.h"
+#include "shared/fileentry.h"
#include
using namespace MOBase;
@@ -98,11 +99,11 @@ void ModInfoWithConflictInfo::doConflictCheck() const
if ((*m_DirectoryStructure)->originExists(name)) {
FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name);
- std::vector files = origin.getFiles();
+ std::vector files = origin.getFiles();
std::set checkedDirs;
// for all files in this origin
- for (FileEntry::Ptr file : files) {
+ for (FileEntryPtr file : files) {
// skip hiidden file check if already found one
if (!hasHiddenFiles) {
@@ -267,7 +268,7 @@ bool ModInfoWithConflictInfo::isRedundant() const
std::wstring name = ToWString(this->name());
if ((*m_DirectoryStructure)->originExists(name)) {
FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name);
- std::vector files = origin.getFiles();
+ std::vector files = origin.getFiles();
bool ignore = false;
for (auto iter = files.begin(); iter != files.end(); ++iter) {
if ((*iter)->getOrigin(ignore) == origin.getID()) {
diff --git a/src/modlist.cpp b/src/modlist.cpp
index afc1b65f..e84910fd 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -27,6 +27,10 @@ along with Mod Organizer. If not, see .
#include "pluginlist.h"
#include "settings.h"
#include "modinforegular.h"
+#include "shared/directoryentry.h"
+#include "shared/fileentry.h"
+#include "shared/filesorigin.h"
+
#include
#include
#include
@@ -872,7 +876,7 @@ void ModList::highlightMods(const QItemSelectionModel *selection, const MOShared
for (QModelIndex idx : selection->selectedRows(PluginList::COL_NAME)) {
QString modName = idx.data().toString();
- const MOShared::FileEntry::Ptr fileEntry = directoryEntry.findFile(modName.toStdWString());
+ const MOShared::FileEntryPtr fileEntry = directoryEntry.findFile(modName.toStdWString());
if (fileEntry.get() != nullptr) {
bool archive = false;
std::vector>> origins;
@@ -881,7 +885,7 @@ void ModList::highlightMods(const QItemSelectionModel *selection, const MOShared
origins.insert(origins.end(), std::pair>(fileEntry->getOrigin(archive), fileEntry->getArchive()));
}
for (auto originInfo : origins) {
- MOShared::FilesOrigin &origin = directoryEntry.getOriginByID(originInfo.first);
+ MOShared::FilesOrigin& origin = directoryEntry.getOriginByID(originInfo.first);
for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
if (ModInfo::getByIndex(i)->internalName() == QString::fromStdWString(origin.getName())) {
ModInfo::getByIndex(i)->setPluginSelected(true);
diff --git a/src/modlist.h b/src/modlist.h
index 7452b28b..d8980dec 100644
--- a/src/modlist.h
+++ b/src/modlist.h
@@ -27,7 +27,6 @@ along with Mod Organizer. If not, see .
#include "profile.h"
#include
-#include
#include
#include
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index a3202153..c9c0bee5 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -22,7 +22,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -34,6 +33,10 @@
#include "previewdialog.h"
#include "env.h"
#include "envmodule.h"
+#include "envfs.h"
+#include "shared/directoryentry.h"
+#include "shared/filesorigin.h"
+#include "shared/fileentry.h"
#include
#include
@@ -810,7 +813,7 @@ QString OrganizerCore::resolvePath(const QString &fileName) const
if (m_DirectoryStructure == nullptr) {
return QString();
}
- const FileEntry::Ptr file
+ const FileEntryPtr file
= m_DirectoryStructure->searchFile(ToWString(fileName), nullptr);
if (file.get() != nullptr) {
return ToQString(file->getFullPath());
diff --git a/src/organizercore.h b/src/organizercore.h
index 223eb6cb..980156d3 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -15,7 +15,6 @@
#include "moshortcut.h"
#include "processrunner.h"
#include "uilocker.h"
-#include
#include
#include
#include
diff --git a/src/pch.h b/src/pch.h
index 030ee634..c66550be 100644
--- a/src/pch.h
+++ b/src/pch.h
@@ -5,14 +5,17 @@
#include
#include
#include
+#include
#include
#include
+#include
#include
#include
#include
#include
#include