summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2020-02-15 17:22:12 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2020-02-18 17:25:05 -0500
commit5e569d0107aefe292b76ac0458f9420077f350a0 (patch)
treedca1410b91361a937f58ed3a3aa0bcb39b80eef2 /src
parentdbb3f5117a3f977bbef34ebdab217f379429d1f2 (diff)
re-enabled archive parsing
Diffstat (limited to 'src')
-rw-r--r--src/directoryrefresher.cpp126
-rw-r--r--src/mainwindow.cpp1
-rw-r--r--src/shared/directoryentry.cpp161
-rw-r--r--src/shared/directoryentry.h79
-rw-r--r--src/shared/util.h10
5 files changed, 223 insertions, 154 deletions
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index 8a64d4a9..5e1c05a8 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -210,38 +210,41 @@ void DirectoryRefresher::cleanStructure(DirectoryEntry *structure)
}
}
-void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure, const QString &modName,
- int priority, const QString &directory, const QStringList &archives)
+void DirectoryRefresher::addModBSAToStructure(
+ DirectoryEntry* root, const QString& modName,
+ int priority, const QString& directory, const QStringList& archives)
{
- std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+ const IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
GamePlugins *gamePlugins = game->feature<GamePlugins>();
QStringList loadOrder = QStringList();
gamePlugins->getLoadOrder(loadOrder);
- for (const QString &archive : archives) {
- QFileInfo fileInfo(archive);
- if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
-
- int order = -1;
+ std::vector<std::wstring> lo;
+ for (auto&& s : loadOrder) {
+ lo.push_back(s.toStdWString());
+ }
- for (auto plugin : loadOrder)
- {
- QString name = plugin.left(plugin.size() - 4);
- if (fileInfo.fileName().startsWith(name + " - ", Qt::CaseInsensitive) || fileInfo.fileName().startsWith(name + ".", Qt::CaseInsensitive)) {
- order = loadOrder.indexOf(plugin);
- }
- }
+ std::vector<std::wstring> archivesW;
+ for (auto&& a : archives) {
+ archivesW.push_back(a.toStdWString());
+ }
- try {
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
- directoryStructure->addFromBSA(ToWString(modName), directoryW, ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority, order);
- } catch (const std::exception &e) {
- throw MyException(tr("failed to parse bsa %1: %2").arg(archive, e.what()));
- }
- }
+ std::set<std::wstring> enabledArchives;
+ for (auto&& a : m_EnabledArchives) {
+ enabledArchives.insert(a.toStdWString());
}
+
+ DirectoryStats dummy;
+
+ root->addFromAllBSAs(
+ modName.toStdWString(),
+ QDir::toNativeSeparators(directory).toStdWString(),
+ priority,
+ archivesW,
+ enabledArchives,
+ lo,
+ dummy);
}
void DirectoryRefresher::stealModFilesIntoStructure(
@@ -329,6 +332,8 @@ struct ModThread
std::wstring modName;
std::wstring path;
int prio = -1;
+ std::vector<std::wstring> archives;
+ std::set<std::wstring> enabledArchives;
DirectoryStats* stats = nullptr;
env::DirectoryWalker walker;
@@ -354,14 +359,21 @@ struct ModThread
SetThisThreadName(QString::fromStdWString(modName + L" refresher"));
ds->addFromOrigin(walker, modName, path, prio, *stats);
- /*if (Settings::instance().archiveParsing()) {
- addModBSAToStructure(
- directoryStructure,
- entries[i].modName,
- prio,
- entries[i].absolutePath,
- entries[i].archives);
- }*/
+ if (Settings::instance().archiveParsing()) {
+ const IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+
+ GamePlugins *gamePlugins = game->feature<GamePlugins>();
+ QStringList loadOrder = QStringList();
+ gamePlugins->getLoadOrder(loadOrder);
+
+ std::vector<std::wstring> lo;
+ for (auto&& s : loadOrder) {
+ lo.push_back(s.toStdWString());
+ }
+
+ ds->addFromAllBSAs(
+ modName, path, prio, archives, enabledArchives, lo, *stats);
+ }
ready = false;
}
@@ -377,6 +389,7 @@ void DirectoryRefresher::addMultipleModsFilesToStructure(
{
std::vector<DirectoryStats> stats(entries.size());
+ log::debug("refresher: using {} threads", m_threadCount);
g_threads.setMax(m_threadCount);
for (std::size_t i=0; i<entries.size(); ++i) {
@@ -396,9 +409,20 @@ void DirectoryRefresher::addMultipleModsFilesToStructure(
auto& mt = g_threads.request();
mt.ds = directoryStructure;
- mt.modName = entries[i].modName.toStdWString();
+ mt.modName = e.modName.toStdWString();
mt.path = QDir::toNativeSeparators(e.absolutePath).toStdWString();
mt.prio = prio;
+
+ mt.archives.clear();
+ for (auto&& a : e.archives) {
+ mt.archives.push_back(a.toStdWString());
+ }
+
+ mt.enabledArchives.clear();
+ for (auto&& a : m_EnabledArchives) {
+ mt.enabledArchives.insert(a.toStdWString());
+ }
+
mt.stats = &stats[i];
mt.wakeup();
@@ -424,33 +448,35 @@ void DirectoryRefresher::refresh()
SetThisThreadName("DirectoryRefresher");
TimeThis tt("refresh");
- QMutexLocker locker(&m_RefreshLock);
+ {
+ QMutexLocker locker(&m_RefreshLock);
- m_Root.reset(new DirectoryEntry(L"data", nullptr, 0));
- m_Root->getFileRegister()->reserve(m_lastFileCount);
+ m_Root.reset(new DirectoryEntry(L"data", nullptr, 0));
+ m_Root->getFileRegister()->reserve(m_lastFileCount);
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+ IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
- std::wstring dataDirectory =
- QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
+ std::wstring dataDirectory =
+ QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
- {
- DirectoryStats dummy;
- m_Root->addFromOrigin(L"data", dataDirectory, 0, dummy);
- }
+ {
+ DirectoryStats dummy;
+ m_Root->addFromOrigin(L"data", dataDirectory, 0, dummy);
+ }
- std::sort(m_Mods.begin(), m_Mods.end(), [](auto lhs, auto rhs) {
- return lhs.priority < rhs.priority;
- });
+ std::sort(m_Mods.begin(), m_Mods.end(), [](auto lhs, auto rhs) {
+ return lhs.priority < rhs.priority;
+ });
- addMultipleModsFilesToStructure(m_Root.get(), m_Mods, true);
+ addMultipleModsFilesToStructure(m_Root.get(), m_Mods, true);
- m_Root->getFileRegister()->sortOrigins();
+ m_Root->getFileRegister()->sortOrigins();
- cleanStructure(m_Root.get());
+ cleanStructure(m_Root.get());
- m_lastFileCount = m_Root->getFileRegister()->highestCount();
- log::debug("refresher saw {} files", m_lastFileCount);
+ m_lastFileCount = m_Root->getFileRegister()->highestCount();
+ log::debug("refresher saw {} files", m_lastFileCount);
+ }
emit progress(100);
emit refreshed();
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index adbac94e..f5749392 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -87,6 +87,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "envshortcut.h"
#include "browserdialog.h"
+#include "directoryrefresher.h"
#include "shared/directoryentry.h"
#include "shared/fileentry.h"
#include "shared/filesorigin.h"
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index 7f140750..84d68675 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -67,14 +67,14 @@ static bool SupportOptimizedFind()
return (::VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, mask) == TRUE);
}
-static bool DirCompareByName(const DirectoryEntry *lhs, const DirectoryEntry *rhs)
+static bool DirCompareByName(const DirectoryEntry* lhs, const DirectoryEntry* rhs)
{
return _wcsicmp(lhs->getName().c_str(), rhs->getName().c_str()) < 0;
}
DirectoryEntry::DirectoryEntry(
- std::wstring name, DirectoryEntry *parent, int originID) :
+ std::wstring name, DirectoryEntry* parent, int originID) :
m_OriginConnection(new OriginConnection),
m_Name(std::move(name)), m_Parent(parent), m_Populated(false), m_TopLevel(true)
{
@@ -83,7 +83,7 @@ DirectoryEntry::DirectoryEntry(
}
DirectoryEntry::DirectoryEntry(
- std::wstring name, DirectoryEntry *parent, int originID,
+ std::wstring name, DirectoryEntry* parent, int originID,
boost::shared_ptr<FileRegister> fileRegister,
boost::shared_ptr<OriginConnection> originConnection) :
m_FileRegister(fileRegister), m_OriginConnection(originConnection),
@@ -166,51 +166,69 @@ void DirectoryEntry::addDir(
m_Populated = true;
}
-void DirectoryEntry::addFromBSA(
- const std::wstring &originName, std::wstring &directory,
- const std::wstring &fileName, int priority, int order)
+void DirectoryEntry::addFromAllBSAs(
+ const std::wstring& originName, const std::wstring& directory,
+ int priority, const std::vector<std::wstring>& archives,
+ const std::set<std::wstring>& enabledArchives,
+ const std::vector<std::wstring>& loadOrder,
+ DirectoryStats& stats)
{
- DirectoryStats dummy;
- FilesOrigin &origin = createOrigin(originName, directory, priority, dummy);
+ for (const auto& archive : archives) {
+ const std::filesystem::path archivePath(archive);
+ const auto filename = archivePath.filename().native();
- WIN32_FILE_ATTRIBUTE_DATA fileData;
- if (::GetFileAttributesExW(fileName.c_str(), GetFileExInfoStandard, &fileData) == 0) {
- throw windows_error(QObject::tr("failed to determine file time").toStdString());
- }
+ if (!enabledArchives.contains(filename)) {
+ continue;
+ }
- FILETIME now;
- ::GetSystemTimeAsFileTime(&now);
+ const auto filenameLc = ToLowerCopy(filename);
- const double clfSecondsPer100ns = 100. * 1.E-9;
+ int order = -1;
- ((ULARGE_INTEGER *)&now)->QuadPart -= ((double)5) / clfSecondsPer100ns;
+ for (auto plugin : loadOrder)
+ {
+ const auto pluginNameLc =
+ ToLowerCopy(std::filesystem::path(plugin).stem().native());
- size_t namePos = fileName.find_last_of(L"\\/");
- if (namePos == std::wstring::npos) {
- namePos = 0;
+ if (filenameLc.starts_with(pluginNameLc + L" - ") ||
+ filenameLc.starts_with(pluginNameLc + L".")) {
+ auto itor = std::find(loadOrder.begin(), loadOrder.end(), plugin);
+ if (itor != loadOrder.end()) {
+ order = std::distance(loadOrder.begin(), itor);
+ }
+ }
+ }
+
+ addFromBSA(
+ originName, directory, archivePath.native(),
+ priority, order, stats);
}
- else {
- ++namePos;
+}
+
+void DirectoryEntry::addFromBSA(
+ const std::wstring& originName, const std::wstring& directory,
+ const std::wstring& archivePath, int priority, int order, DirectoryStats& stats)
+{
+ FilesOrigin& origin = createOrigin(originName, directory, priority, stats);
+ const auto archiveName = std::filesystem::path(archivePath).filename().native();
+
+ if (containsArchive(archiveName)) {
+ return;
}
- if (!containsArchive(fileName.substr(namePos)) || ::CompareFileTime(&fileData.ftLastWriteTime, &now) > 0) {
- BSA::Archive archive;
- BSA::EErrorCode res = archive.read(ToString(fileName, false).c_str(), false);
+ BSA::Archive archive;
+ BSA::EErrorCode res = archive.read(ToString(archivePath, false).c_str(), false);
- if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) {
- std::ostringstream stream;
+ if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) {
+ log::error("invalid bsa '{}', error {}", archivePath, res);
+ return;
+ }
- stream
- << QObject::tr("invalid bsa file: ").toStdString()
- << ToString(fileName, false)
- << " error code " << res << " - " << ::GetLastError();
+ const auto ft = ToFILETIME(std::filesystem::last_write_time(archivePath));
- throw std::runtime_error(stream.str());
- }
+ addFiles(origin, archive.getRoot(), ft, archiveName, order, stats);
- addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos), order);
- m_Populated = true;
- }
+ m_Populated = true;
}
void DirectoryEntry::propagateOrigin(int origin)
@@ -258,7 +276,7 @@ int DirectoryEntry::anyOrigin() const
// if we got here, no file directly within this directory is a valid indicator for a mod, thus
// we continue looking in subdirectories
- for (DirectoryEntry *entry : m_SubDirectories) {
+ for (DirectoryEntry* entry : m_SubDirectories) {
int res = entry->anyOrigin();
if (res != InvalidOriginID){
return res;
@@ -279,7 +297,7 @@ std::vector<FileEntryPtr> DirectoryEntry::getFiles() const
return result;
}
-DirectoryEntry *DirectoryEntry::findSubDirectory(
+DirectoryEntry* DirectoryEntry::findSubDirectory(
const std::wstring &name, bool alreadyLowerCase) const
{
SubDirectoriesLookup::const_iterator itor;
@@ -297,9 +315,10 @@ DirectoryEntry *DirectoryEntry::findSubDirectory(
return itor->second;
}
-DirectoryEntry *DirectoryEntry::findSubDirectoryRecursive(const std::wstring &path)
+DirectoryEntry* DirectoryEntry::findSubDirectoryRecursive(const std::wstring &path)
{
- return getSubDirectoryRecursive(path, false, InvalidOriginID);
+ DirectoryStats dummy;
+ return getSubDirectoryRecursive(path, false, dummy, InvalidOriginID);
}
const FileEntryPtr DirectoryEntry::findFile(
@@ -349,7 +368,7 @@ bool DirectoryEntry::containsArchive(std::wstring archiveName)
}
const FileEntryPtr DirectoryEntry::searchFile(
- const std::wstring &path, const DirectoryEntry **directory) const
+ const std::wstring &path, const DirectoryEntry** directory) const
{
if (directory != nullptr) {
*directory = nullptr;
@@ -373,7 +392,7 @@ const FileEntryPtr DirectoryEntry::searchFile(
if (iter != m_Files.end()) {
return m_FileRegister->getFile(iter->second);
} else if (directory != nullptr) {
- DirectoryEntry *temp = findSubDirectory(path);
+ DirectoryEntry* temp = findSubDirectory(path);
if (temp != nullptr) {
*directory = temp;
}
@@ -381,7 +400,7 @@ const FileEntryPtr DirectoryEntry::searchFile(
} else {
// file is in a subdirectory, recurse into the matching subdirectory
std::wstring pathComponent = path.substr(0, len);
- DirectoryEntry *temp = findSubDirectory(pathComponent);
+ DirectoryEntry* temp = findSubDirectory(pathComponent);
if (temp != nullptr) {
if (len >= path.size()) {
@@ -401,7 +420,7 @@ void DirectoryEntry::removeFile(FileIndex index)
removeFileFromList(index);
}
-bool DirectoryEntry::removeFile(const std::wstring &filePath, int *origin)
+bool DirectoryEntry::removeFile(const std::wstring &filePath, int* origin)
{
size_t pos = filePath.find_first_of(L"\\/");
@@ -411,7 +430,9 @@ bool DirectoryEntry::removeFile(const std::wstring &filePath, int *origin)
std::wstring dirName = filePath.substr(0, pos);
std::wstring rest = filePath.substr(pos + 1);
- DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false);
+
+ DirectoryStats dummy;
+ DirectoryEntry* entry = getSubDirectoryRecursive(dirName, false, dummy);
if (entry != nullptr) {
return entry->removeFile(rest, origin);
@@ -426,7 +447,7 @@ void DirectoryEntry::removeDir(const std::wstring &path)
if (pos == std::string::npos) {
for (auto iter = m_SubDirectories.begin(); iter != m_SubDirectories.end(); ++iter) {
- DirectoryEntry *entry = *iter;
+ DirectoryEntry* entry = *iter;
if (CaseInsensitiveEqual(entry->getName(), path)) {
entry->removeDirRecursive();
@@ -438,7 +459,9 @@ void DirectoryEntry::removeDir(const std::wstring &path)
} else {
std::wstring dirName = path.substr(0, pos);
std::wstring rest = path.substr(pos + 1);
- DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false);
+
+ DirectoryStats dummy;
+ DirectoryEntry* entry = getSubDirectoryRecursive(dirName, false, dummy);
if (entry != nullptr) {
entry->removeDir(rest);
@@ -446,7 +469,7 @@ void DirectoryEntry::removeDir(const std::wstring &path)
}
}
-bool DirectoryEntry::remove(const std::wstring &fileName, int *origin)
+bool DirectoryEntry::remove(const std::wstring &fileName, int* origin)
{
const auto lcFileName = ToLowerCopy(fileName);
@@ -661,18 +684,17 @@ void DirectoryEntry::onFile(Context* cx, std::wstring_view path, FILETIME ft)
}
void DirectoryEntry::addFiles(
- FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime,
- const std::wstring &archiveName, int order)
+ FilesOrigin& origin, const BSA::Folder::Ptr archiveFolder, FILETIME fileTime,
+ const std::wstring& archiveName, int order, DirectoryStats& stats)
{
- DirectoryStats dummy;
-
// add files
- for (unsigned int fileIdx = 0; fileIdx < archiveFolder->getNumFiles(); ++fileIdx) {
- BSA::File::Ptr file = archiveFolder->getFile(fileIdx);
+ const auto fileCount = archiveFolder->getNumFiles();
+ for (unsigned int i=0; i<fileCount; ++i) {
+ const BSA::File::Ptr file = archiveFolder->getFile(i);
auto f = insert(
ToWString(file->getName(), true), origin, fileTime,
- archiveName, order, dummy);
+ archiveName, order, stats);
if (f) {
if (file->getUncompressedFileSize() > 0) {
@@ -684,16 +706,18 @@ void DirectoryEntry::addFiles(
}
// recurse into subdirectories
- for (unsigned int folderIdx = 0; folderIdx < archiveFolder->getNumSubFolders(); ++folderIdx) {
- BSA::Folder::Ptr folder = archiveFolder->getSubFolder(folderIdx);
- DirectoryEntry *folderEntry = getSubDirectoryRecursive(
- ToWString(folder->getName(), true), true, origin.getID());
+ const auto dirCount = archiveFolder->getNumSubFolders();
+ for (unsigned int i=0; i<dirCount; ++i) {
+ const BSA::Folder::Ptr folder = archiveFolder->getSubFolder(i);
+
+ DirectoryEntry* folderEntry = getSubDirectoryRecursive(
+ ToWString(folder->getName(), true), true, stats, origin.getID());
- folderEntry->addFiles(origin, folder, fileTime, archiveName, order);
+ folderEntry->addFiles(origin, folder, fileTime, archiveName, order, stats);
}
}
-DirectoryEntry *DirectoryEntry::getSubDirectory(
+DirectoryEntry* DirectoryEntry::getSubDirectory(
std::wstring_view name, bool create, DirectoryStats& stats, int originID)
{
std::wstring nameLc = ToLowerCopy(name);
@@ -728,7 +752,7 @@ DirectoryEntry *DirectoryEntry::getSubDirectory(
}
}
-DirectoryEntry *DirectoryEntry::getSubDirectory(
+DirectoryEntry* DirectoryEntry::getSubDirectory(
env::Directory& dir, bool create, DirectoryStats& stats, int originID)
{
SubDirectoriesLookup::iterator itor;
@@ -764,8 +788,8 @@ DirectoryEntry *DirectoryEntry::getSubDirectory(
}
}
-DirectoryEntry *DirectoryEntry::getSubDirectoryRecursive(
- const std::wstring &path, bool create, int originID)
+DirectoryEntry* DirectoryEntry::getSubDirectoryRecursive(
+ const std::wstring& path, bool create, DirectoryStats& stats, int originID)
{
if (path.length() == 0) {
// path ended with a backslash?
@@ -773,19 +797,18 @@ DirectoryEntry *DirectoryEntry::getSubDirectoryRecursive(
}
const size_t pos = path.find_first_of(L"\\/");
- DirectoryStats dummy;
if (pos == std::wstring::npos) {
- return getSubDirectory(path, create, dummy);
+ return getSubDirectory(path, create, stats);
} else {
- DirectoryEntry *nextChild = getSubDirectory(
- path.substr(0, pos), create, dummy, originID);
+ DirectoryEntry* nextChild = getSubDirectory(
+ path.substr(0, pos), create, stats, originID);
if (nextChild == nullptr) {
return nullptr;
} else {
return nextChild->getSubDirectoryRecursive(
- path.substr(pos + 1), create, originID);
+ path.substr(pos + 1), create, stats, originID);
}
}
}
@@ -798,7 +821,7 @@ void DirectoryEntry::removeDirRecursive()
m_FilesLookup.clear();
- for (DirectoryEntry *entry : m_SubDirectories) {
+ for (DirectoryEntry* entry : m_SubDirectories) {
entry->removeDirRecursive();
delete entry;
}
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index 5ca7389d..a28ceeae 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -50,10 +50,10 @@ class DirectoryEntry
{
public:
DirectoryEntry(
- std::wstring name, DirectoryEntry *parent, OriginID originID);
+ std::wstring name, DirectoryEntry* parent, OriginID originID);
DirectoryEntry(
- std::wstring name, DirectoryEntry *parent, OriginID originID,
+ std::wstring name, DirectoryEntry* parent, OriginID originID,
boost::shared_ptr<FileRegister> fileRegister,
boost::shared_ptr<OriginConnection> originConnection);
@@ -85,7 +85,7 @@ public:
return !m_Files.empty();
}
- const DirectoryEntry *getParent() const
+ const DirectoryEntry* getParent() const
{
return m_Parent;
}
@@ -93,24 +93,32 @@ public:
// add files to this directory (and subdirectories) from the specified origin.
// That origin may exist or not
void addFromOrigin(
- const std::wstring &originName,
- const std::wstring &directory, int priority, DirectoryStats& stats);
+ const std::wstring& originName,
+ const std::wstring& directory, int priority, DirectoryStats& stats);
void addFromOrigin(
- env::DirectoryWalker& walker, const std::wstring &originName,
- const std::wstring &directory, int priority, DirectoryStats& stats);
+ env::DirectoryWalker& walker, const std::wstring& originName,
+ const std::wstring& directory, int priority, DirectoryStats& stats);
+
+ void addFromAllBSAs(
+ const std::wstring& originName, const std::wstring& directory,
+ int priority, const std::vector<std::wstring>& archives,
+ const std::set<std::wstring>& enabledArchives,
+ const std::vector<std::wstring>& loadOrder,
+ DirectoryStats& stats);
void addFromBSA(
- const std::wstring &originName, std::wstring &directory,
- const std::wstring &fileName, int priority, int order);
+ const std::wstring& originName, const std::wstring& directory,
+ const std::wstring& archivePath, int priority, int order,
+ DirectoryStats& stats);
void addFromList(
- const std::wstring &originName, const std::wstring &directory,
+ const std::wstring& originName, const std::wstring& directory,
env::Directory& root, int priority, DirectoryStats& stats);
void propagateOrigin(OriginID origin);
- const std::wstring &getName() const
+ const std::wstring& getName() const
{
return m_Name;
}
@@ -120,9 +128,9 @@ public:
return m_FileRegister;
}
- bool originExists(const std::wstring &name) const;
- FilesOrigin &getOriginByID(OriginID ID) const;
- FilesOrigin &getOriginByName(const std::wstring &name) const;
+ bool originExists(const std::wstring& name) const;
+ FilesOrigin& getOriginByID(OriginID ID) const;
+ FilesOrigin& getOriginByName(const std::wstring& name) const;
const FilesOrigin* findOriginByID(OriginID ID) const;
OriginID anyOrigin() const;
@@ -130,8 +138,8 @@ public:
std::vector<FileEntryPtr> getFiles() const;
void getSubDirectories(
- std::vector<DirectoryEntry*>::const_iterator &begin,
- std::vector<DirectoryEntry*>::const_iterator &end) const
+ std::vector<DirectoryEntry*>::const_iterator& begin,
+ std::vector<DirectoryEntry*>::const_iterator& end) const
{
begin = m_SubDirectories.begin();
end = m_SubDirectories.end();
@@ -179,16 +187,16 @@ public:
return m_FileRegister->getFile(index);
}
- DirectoryEntry *findSubDirectory(
- const std::wstring &name, bool alreadyLowerCase=false) const;
+ DirectoryEntry* findSubDirectory(
+ const std::wstring& name, bool alreadyLowerCase=false) const;
- DirectoryEntry *findSubDirectoryRecursive(const std::wstring &path);
+ DirectoryEntry* findSubDirectoryRecursive(const std::wstring& path);
/** retrieve a file in this directory by name.
* @param name name of the file
* @return fileentry object for the file or nullptr if no file matches
*/
- const FileEntryPtr findFile(const std::wstring &name, bool alreadyLowerCase=false) const;
+ const FileEntryPtr findFile(const std::wstring& name, bool alreadyLowerCase=false) const;
const FileEntryPtr findFile(const DirectoryEntryFileKey& key) const;
bool hasFile(const std::wstring& name) const;
@@ -201,29 +209,29 @@ public:
// path containing the file
//
const FileEntryPtr searchFile(
- const std::wstring &path, const DirectoryEntry **directory=nullptr) const;
+ const std::wstring& path, const DirectoryEntry** directory=nullptr) const;
void removeFile(FileIndex index);
// remove the specified file from the tree. This can be a path leading to a
// file in a subdirectory
- bool removeFile(const std::wstring &filePath, OriginID *origin = nullptr);
+ bool removeFile(const std::wstring& filePath, OriginID* origin = nullptr);
/**
* @brief remove the specified directory
* @param path directory to remove
*/
- void removeDir(const std::wstring &path);
+ void removeDir(const std::wstring& path);
- bool remove(const std::wstring &fileName, OriginID *origin);
+ bool remove(const std::wstring& fileName, OriginID* origin);
bool hasContentsFromOrigin(OriginID originID) const;
- FilesOrigin &createOrigin(
- const std::wstring &originName,
- const std::wstring &directory, int priority, DirectoryStats& stats);
+ FilesOrigin& createOrigin(
+ const std::wstring& originName,
+ const std::wstring& directory, int priority, DirectoryStats& stats);
- void removeFiles(const std::set<FileIndex> &indices);
+ void removeFiles(const std::set<FileIndex>& indices);
void dump(const std::wstring& file) const;
@@ -242,7 +250,7 @@ private:
SubDirectories m_SubDirectories;
SubDirectoriesLookup m_SubDirectoriesLookup;
- DirectoryEntry *m_Parent;
+ DirectoryEntry* m_Parent;
std::set<OriginID> m_Origins;
bool m_Populated;
bool m_TopLevel;
@@ -252,20 +260,20 @@ private:
FileEntryPtr insert(
- std::wstring_view fileName, FilesOrigin &origin, FILETIME fileTime,
+ std::wstring_view fileName, FilesOrigin& origin, FILETIME fileTime,
std::wstring_view archive, int order, DirectoryStats& stats);
FileEntryPtr insert(
- env::File& file, FilesOrigin &origin,
+ env::File& file, FilesOrigin& origin,
std::wstring_view archive, int order, DirectoryStats& stats);
void addFiles(
- env::DirectoryWalker& walker, FilesOrigin &origin,
+ env::DirectoryWalker& walker, FilesOrigin& origin,
const std::wstring& path, DirectoryStats& stats);
void addFiles(
- FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime,
- const std::wstring &archiveName, int order);
+ FilesOrigin& origin, BSA::Folder::Ptr archiveFolder, FILETIME fileTime,
+ const std::wstring& archiveName, int order, DirectoryStats& stats);
void addDir(FilesOrigin& origin, env::Directory& d, DirectoryStats& stats);
@@ -278,7 +286,8 @@ private:
OriginID originID = InvalidOriginID);
DirectoryEntry* getSubDirectoryRecursive(
- const std::wstring &path, bool create, OriginID originID = InvalidOriginID);
+ const std::wstring& path, bool create, DirectoryStats& stats,
+ OriginID originID = InvalidOriginID);
void removeDirRecursive();
diff --git a/src/shared/util.h b/src/shared/util.h
index dc6e72ad..1d3cce82 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -21,6 +21,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define UTIL_H
#include <string>
+#include <filesystem>
#include <versioninfo.h>
class Executable;
@@ -51,6 +52,15 @@ QString getUsvfsVersionString();
void SetThisThreadName(const QString& s);
void checkDuplicateShortcuts(const QMenu& m);
+inline FILETIME ToFILETIME(std::filesystem::file_time_type t)
+{
+ FILETIME ft;
+ static_assert(sizeof(t) == sizeof(ft));
+
+ std::memcpy(&ft, &t, sizeof(FILETIME));
+ return ft;
+}
+
} // namespace MOShared