summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTannin <devnull@localhost>2014-05-05 18:24:15 +0200
committerTannin <devnull@localhost>2014-05-05 18:24:15 +0200
commit0eb1662a0eaf8eee680cab5b913fff3fcc9b8b2f (patch)
tree4cccf64266f73d9acabc15e517abd510da79b582 /src
parent164ec25a75a9d5b5fcbafbe321935ba37fe0885c (diff)
- very effective optimization to findfirstfile-calls
- several configuration files are now only saved to disk if the content actually changed. This should also get rid of a problem where plugins.txt was re-written immediately after starting the game (causing a conflict with the game) - reduced "noise" from hook.dll - removed some debugging messages
Diffstat (limited to 'src')
-rw-r--r--src/directoryrefresher.cpp4
-rw-r--r--src/mainwindow.cpp34
-rw-r--r--src/mainwindow.h2
-rw-r--r--src/pluginlist.cpp9
-rw-r--r--src/pluginlist.h2
-rw-r--r--src/profile.cpp7
-rw-r--r--src/profile.h1
-rw-r--r--src/safewritefile.cpp20
-rw-r--r--src/safewritefile.h4
-rw-r--r--src/shared/directoryentry.cpp29
-rw-r--r--src/shared/directoryentry.h6
11 files changed, 68 insertions, 50 deletions
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index 43e13a37..70bcf5b6 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -93,7 +93,6 @@ void DirectoryRefresher::refresh()
//TODO i is the priority here, where higher = more important. the input vector is also sorted by priority but inverted!
for (int i = 1; iter != m_Mods.end(); ++iter, ++i) {
QString modName = std::get<0>(*iter);
-qDebug("load files for mod %s", qPrintable(modName));
try {
addModToStructure(m_DirectoryStructure, modName, i, std::get<1>(*iter));
} catch (const std::exception &e) {
@@ -103,14 +102,11 @@ qDebug("load files for mod %s", qPrintable(modName));
}
std::wstring dataDirectory = GameInfo::instance().getGameDirectory() + L"\\data";
-qDebug("load files for data folder");
m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0);
emit progress(100);
-qDebug("cleanup structure");
cleanStructure(m_DirectoryStructure);
-qDebug("all done");
emit refreshed();
}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index b8c357f8..5dc2eb2a 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -664,8 +664,9 @@ void MainWindow::saveArchiveList()
}
}
}
- archiveFile.commit();
- qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_CurrentProfile->getArchivesFileName())));
+ if (archiveFile.commitIfDifferent(m_ArchiveListHash)) {
+ qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_CurrentProfile->getArchivesFileName())));
+ }
} else {
qWarning("archive list not initialised");
}
@@ -1423,7 +1424,7 @@ HANDLE MainWindow::spawnBinaryDirect(const QFileInfo &binary, const QString &arg
}
}
- while (m_RefreshProgress->isVisible()) {
+ while (m_DirectoryUpdate) {
::Sleep(100);
QCoreApplication::processEvents();
}
@@ -1432,7 +1433,6 @@ HANDLE MainWindow::spawnBinaryDirect(const QFileInfo &binary, const QString &arg
if (m_CurrentProfile != nullptr) {
m_CurrentProfile->writeModlistNow(true);
}
- savePluginList();
// TODO: should also pass arguments
if (m_AboutToRun(binary.absoluteFilePath())) {
@@ -1443,28 +1443,6 @@ HANDLE MainWindow::spawnBinaryDirect(const QFileInfo &binary, const QString &arg
}
}
-/*
-void MainWindow::spawnProgram(const QString &fileName, const QString &argumentsArg,
- const QString &profileName, const QDir &currentDirectory)
-{
- QFileInfo binary;
- QString arguments = argumentsArg;
- QString steamAppID;
- try {
- const Executable &exe = m_ExecutablesList.find(fileName);
- steamAppID = exe.m_SteamAppID;
- if (arguments == "") {
- arguments = exe.m_Arguments;
- }
- binary = exe.m_BinaryInfo;
- } catch (const std::runtime_error&) {
- qWarning("\"%s\" not set up as executable", fileName.toUtf8().constData());
- binary = QFileInfo(fileName);
- }
- spawnBinaryDirect(binary, arguments, profileName, currentDirectory, steamAppID);
-}
-*/
-
void MainWindow::spawnBinary(const QFileInfo &binary, const QString &arguments, const QDir &currentDirectory, bool closeAfterStart, const QString &steamAppID)
{
@@ -2774,8 +2752,6 @@ void MainWindow::refresher_progress(int percent)
void MainWindow::directory_refreshed()
{
- statusBar()->hide();
-
DirectoryEntry *newStructure = m_DirectoryRefresher.getDirectoryStructure();
if (newStructure != NULL) {
DirectoryEntry *oldStructure = m_DirectoryStructure;
@@ -2800,6 +2776,7 @@ void MainWindow::directory_refreshed()
ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
modInfo->clearCaches();
}
+ statusBar()->hide();
}
@@ -5375,7 +5352,6 @@ void MainWindow::on_bossButton_clicked()
HANDLE stdOutWrite = INVALID_HANDLE_VALUE;
HANDLE stdOutRead = INVALID_HANDLE_VALUE;
createStdoutPipe(&stdOutRead, &stdOutWrite);
-
HANDLE loot = startBinary(QFileInfo(qApp->applicationDirPath() + "/loot/lootcli.exe"),
parameters.join(" "),
m_CurrentProfile->getName(),
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 3caa08ef..3aaf62a5 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -391,6 +391,8 @@ private:
std::vector<QTreeWidgetItem*> m_RemoveWidget;
+ uint m_ArchiveListHash;
+
private slots:
void showMessage(const QString &message);
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index 534017cd..929e0476 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -391,6 +391,8 @@ void PluginList::writePlugins(const QString &fileName, bool writeUnchecked) cons
file->write(textCodec->fromUnicode("# This file was automatically generated by Mod Organizer.\r\n"));
+ QStringList saveList;
+
bool invalidFileNames = false;
int writtenCount = 0;
for (size_t i = 0; i < m_ESPs.size(); ++i) {
@@ -401,6 +403,7 @@ void PluginList::writePlugins(const QString &fileName, bool writeUnchecked) cons
invalidFileNames = true;
qCritical("invalid plugin name %s", m_ESPs[priority].m_Name.toUtf8().constData());
} else {
+ saveList << m_ESPs[priority].m_Name;
file->write(textCodec->fromUnicode(m_ESPs[priority].m_Name));
}
file->write("\r\n");
@@ -413,9 +416,9 @@ void PluginList::writePlugins(const QString &fileName, bool writeUnchecked) cons
"Please see mo_interface.log for a list of affected plugins and rename them."));
}
- file.commit();
-
- qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
+ if (file.commitIfDifferent(m_LastSaveHash[fileName])) {
+ qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
+ }
}
diff --git a/src/pluginlist.h b/src/pluginlist.h
index 606d6c68..b7e7e2b4 100644
--- a/src/pluginlist.h
+++ b/src/pluginlist.h
@@ -29,6 +29,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <boost/signals2.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <vector>
+#include <map>
#include "pdll.h"
#include <BOSS-API.h>
@@ -278,6 +279,7 @@ private:
private:
std::vector<ESPInfo> m_ESPs;
+ mutable std::map<QString, uint> m_LastSaveHash;
std::map<QString, int> m_ESPsByName;
std::vector<int> m_ESPsByPriority;
diff --git a/src/profile.cpp b/src/profile.cpp
index 42358b7d..8d02c047 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -147,7 +147,6 @@ void Profile::writeModlistNow(bool onlyOnTimer) const
m_SaveTimer->stop();
if (!m_Directory.exists()) return;
-#pragma message("right now, this is doing unnecessary saves. Need a flag that says that mod priority, enabled-state or name of a mod has changed")
try {
QString fileName = getModlistFileName();
@@ -175,9 +174,9 @@ void Profile::writeModlistNow(bool onlyOnTimer) const
}
}
- file.commit();
-
- qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
+ if (file.commitIfDifferent(m_LastModlistHash)) {
+ qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
+ }
} catch (const std::exception &e) {
reportError(tr("failed to write mod list: %1").arg(e.what()));
return;
diff --git a/src/profile.h b/src/profile.h
index 5aa77357..df27bb37 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -316,6 +316,7 @@ private:
QDir m_Directory;
+ mutable uint m_LastModlistHash;
std::vector<ModStatus> m_ModStatus;
std::vector<unsigned int> m_ModIndexByPriority;
unsigned int m_NumRegularMods;
diff --git a/src/safewritefile.cpp b/src/safewritefile.cpp
index 6df8c2b8..626413dd 100644
--- a/src/safewritefile.cpp
+++ b/src/safewritefile.cpp
@@ -46,3 +46,23 @@ void SafeWriteFile::commit() {
m_TempFile.setAutoRemove(false);
m_TempFile.close();
}
+
+bool SafeWriteFile::commitIfDifferent(uint &inHash) {
+ uint newHash = hash();
+ if (newHash != inHash) {
+ commit();
+ inHash = newHash;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+uint SafeWriteFile::hash()
+{
+ qint64 pos = m_TempFile.pos();
+ m_TempFile.seek(0);
+ QByteArray data = m_TempFile.readAll();
+ m_TempFile.seek(pos);
+ return qHash(data);
+}
diff --git a/src/safewritefile.h b/src/safewritefile.h
index 56bd7744..06c22acc 100644
--- a/src/safewritefile.h
+++ b/src/safewritefile.h
@@ -37,6 +37,10 @@ public:
void commit();
+ bool commitIfDifferent(uint &hash);
+
+ uint hash();
+
private:
QString m_FileName;
QTemporaryFile m_TempFile;
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index a232ea19..6311ba25 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -235,6 +235,9 @@ std::vector<FileEntry::Ptr> FilesOrigin::getFiles() const
void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive)
{
+ if (m_Parent != NULL) {
+ m_Parent->propagateOrigin(origin);
+ }
if (m_Origin == -1) {
m_Origin = origin;
m_FileTime = fileTime;
@@ -385,29 +388,25 @@ std::wstring FileEntry::getRelativePath() const
//
DirectoryEntry::DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID)
: m_OriginConnection(new OriginConnection),
- m_Name(name), m_Parent(parent), m_Populated(false), m_Origin(originID), m_TopLevel(true)
+ m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(true)
{
m_FileRegister.reset(new FileRegister(m_OriginConnection));
+ m_Origins.insert(originID);
LEAK_TRACE;
}
DirectoryEntry::DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID,
boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection)
: m_FileRegister(fileRegister), m_OriginConnection(originConnection),
- m_Name(name), m_Parent(parent), m_Populated(false), m_Origin(originID), m_TopLevel(false)
+ m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(false)
{
LEAK_TRACE;
+ m_Origins.insert(originID);
}
DirectoryEntry::~DirectoryEntry()
{
-/* if (m_TopLevel) {
- if (m_FileRegister.use_count() > 1) {
-log("this should not happen");
- delete m_FileRegister.get();
- }
- }*/
LEAK_UNTRACE;
clear();
}
@@ -479,6 +478,14 @@ void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &di
m_Populated = true;
}
+void DirectoryEntry::propagateOrigin(int origin)
+{
+ m_Origins.insert(origin);
+ if (m_Parent != NULL) {
+ m_Parent->propagateOrigin(origin);
+ }
+}
+
static bool SupportOptimizedFind()
{
@@ -603,6 +610,10 @@ void DirectoryEntry::removeDir(const std::wstring &path)
}
}
+bool DirectoryEntry::hasContentsFromOrigin(int originID) const
+{
+ return m_Origins.find(originID) != m_Origins.end();
+}
void DirectoryEntry::insertFile(const std::wstring &filePath, FilesOrigin &origin, FILETIME fileTime)
{
@@ -656,7 +667,7 @@ int DirectoryEntry::anyOrigin() const
return res;
}
}
- return m_Origin;
+ return *(m_Origins.begin());
}
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index b298cdd9..f691603f 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -213,6 +213,8 @@ public:
void addFromOrigin(const std::wstring &originName, const std::wstring &directory, int priority);
void addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority);
+ void propagateOrigin(int origin);
+
const std::wstring &getName() const;
boost::shared_ptr<FileRegister> getFileRegister() { return m_FileRegister; }
@@ -269,6 +271,8 @@ public:
}
}
+ bool hasContentsFromOrigin(int originID) const;
+
private:
DirectoryEntry(const DirectoryEntry &reference);
@@ -319,7 +323,7 @@ private:
std::vector<DirectoryEntry*> m_SubDirectories;
DirectoryEntry *m_Parent;
- int m_Origin;
+ std::set<int> m_Origins;
bool m_Populated;