From bca6283311cf1dea4c96f8ee5bf192bdb1640cb3 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Wed, 17 Jul 2019 08:56:16 -0400
Subject: use log::Levels instead of ints create log level combobox in code,
set selected index based on value instead added log level to context menu in
log list
---
src/usvfsconnector.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
(limited to 'src/usvfsconnector.h')
diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h
index 8a88bde5..b0bd320c 100644
--- a/src/usvfsconnector.h
+++ b/src/usvfsconnector.h
@@ -29,6 +29,7 @@ along with Mod Organizer. If not, see .
#include
#include
#include
+#include
#include "executableinfo.h"
@@ -84,7 +85,11 @@ public:
~UsvfsConnector();
void updateMapping(const MappingType &mapping);
- void updateParams(int logLevel, int crashDumpsType, QString executableBlacklist);
+
+ void updateParams(
+ MOBase::log::Levels logLevel, int crashDumpsType,
+ QString executableBlacklist);
+
void updateForcedLibraries(const QList &forcedLibraries);
private:
--
cgit v1.3.1
From 4f1b15f0a1b2e6cbca4b420608d81570af489067 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Sat, 24 Aug 2019 16:07:07 -0400
Subject: changed crash dump type to use enum instead of int added
ColorSettings settings dialog general and diag tabs don't use qsettings
anymore removed logging of setting changes, will be added back to Settings
class
---
src/modinfo.cpp | 1 -
src/modlist.cpp | 10 +--
src/organizercore.cpp | 6 +-
src/organizercore.h | 4 +-
src/pluginlist.cpp | 2 +-
src/settings.cpp | 160 ++++++++++++++++++++++++++++++--------
src/settings.h | 70 ++++++++++-------
src/settingsdialog.cpp | 26 +------
src/settingsdialog.ui | 20 -----
src/settingsdialogdiagnostics.cpp | 38 ++++++++-
src/settingsdialogdiagnostics.h | 1 +
src/settingsdialoggeneral.cpp | 66 ++++++++--------
src/usvfsconnector.cpp | 7 +-
src/usvfsconnector.h | 2 +-
14 files changed, 259 insertions(+), 154 deletions(-)
(limited to 'src/usvfsconnector.h')
diff --git a/src/modinfo.cpp b/src/modinfo.cpp
index 5a05e7ca..e3daa4fd 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -42,7 +42,6 @@ along with Mod Organizer. If not, see .
#include
#include
#include
-#include
using namespace MOBase;
using namespace MOShared;
diff --git a/src/modlist.cpp b/src/modlist.cpp
index c591c49b..94b4a387 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -416,15 +416,15 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
bool archiveOverwritten = m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end();
bool archiveLooseOverwritten = m_ArchiveLooseOverwritten.find(modIndex) != m_ArchiveLooseOverwritten.end();
if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) {
- return Settings::instance().modlistContainsPluginColor();
+ return Settings::instance().colors().modlistContainsPlugin();
} else if (overwritten || archiveLooseOverwritten) {
- return Settings::instance().modlistOverwritingLooseColor();
+ return Settings::instance().colors().modlistOverwritingLoose();
} else if (overwrite || archiveLooseOverwrite) {
- return Settings::instance().modlistOverwrittenLooseColor();
+ return Settings::instance().colors().modlistOverwrittenLoose();
} else if (archiveOverwritten) {
- return Settings::instance().modlistOverwritingArchiveColor();
+ return Settings::instance().colors().modlistOverwritingArchive();
} else if (archiveOverwrite) {
- return Settings::instance().modlistOverwrittenArchiveColor();
+ return Settings::instance().colors().modlistOverwrittenArchive();
} else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR)
&& modInfo->getColor().isValid()
&& ((role != ViewMarkingScrollBar::DEFAULT_ROLE)
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 73d0abac..5a8ee4c2 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -667,7 +667,7 @@ void OrganizerCore::prepareVFS()
}
void OrganizerCore::updateVFSParams(
- log::Levels logLevel, int crashDumpsType, QString executableBlacklist)
+ log::Levels logLevel, CrashDumpsType crashDumpsType, QString executableBlacklist)
{
setGlobalCrashDumpsType(crashDumpsType);
m_USVFS.updateParams(logLevel, crashDumpsType, executableBlacklist);
@@ -692,8 +692,8 @@ bool OrganizerCore::cycleDiagnostics() {
}
//static
-void OrganizerCore::setGlobalCrashDumpsType(int crashDumpsType) {
- m_globalCrashDumpsType = ::crashDumpsType(crashDumpsType);
+void OrganizerCore::setGlobalCrashDumpsType(CrashDumpsType type) {
+ m_globalCrashDumpsType = type;
}
//static
diff --git a/src/organizercore.h b/src/organizercore.h
index 4bcfe745..a14d79a9 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -193,7 +193,7 @@ public:
void prepareVFS();
void updateVFSParams(
- MOBase::log::Levels logLevel, int crashDumpsType,
+ MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
QString executableBlacklist);
void setLogLevel(MOBase::log::Levels level);
@@ -201,7 +201,7 @@ public:
bool cycleDiagnostics();
static CrashDumpsType getGlobalCrashDumpsType() { return m_globalCrashDumpsType; }
- static void setGlobalCrashDumpsType(int crashDumpsType);
+ static void setGlobalCrashDumpsType(CrashDumpsType crashDumpsType);
static std::wstring crashDumpsPath();
public:
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index 8637f546..ddfe492e 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -931,7 +931,7 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const
} else if (role == Qt::BackgroundRole
|| (role == ViewMarkingScrollBar::DEFAULT_ROLE)) {
if (m_ESPs[index].m_ModSelected) {
- return Settings::instance().pluginListContainedColor();
+ return Settings::instance().colors().pluginListContained();
} else {
return QVariant();
}
diff --git a/src/settings.cpp b/src/settings.cpp
index 844ee81e..2236fc9d 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -24,7 +24,6 @@ along with Mod Organizer. If not, see .
#include "expanderwidget.h"
#include
#include
-#include
using namespace MOBase;
@@ -33,7 +32,13 @@ std::optional getOptional(
const QSettings& s, const QString& name, std::optional def={})
{
if (s.contains(name)) {
- return s.value(name).value();
+ const auto v = s.value(name);
+
+ if constexpr (std::is_enum_v) {
+ return static_cast(v.value>());
+ } else {
+ return v.value();
+ }
}
return def;
@@ -160,10 +165,12 @@ void warnIfNotCheckable(const QAbstractButton* b)
}
}
+
Settings *Settings::s_Instance = nullptr;
-Settings::Settings(const QString& path)
- : m_Settings(path, QSettings::IniFormat), m_Geometry(m_Settings)
+Settings::Settings(const QString& path) :
+ m_Settings(path, QSettings::IniFormat),
+ m_Geometry(m_Settings), m_Colors(m_Settings)
{
if (s_Instance != nullptr) {
throw std::runtime_error("second instance of \"Settings\" created");
@@ -280,6 +287,11 @@ bool Settings::colorSeparatorScrollbar() const
return m_Settings.value("Settings/colorSeparatorScrollbars", true).toBool();
}
+void Settings::setColorSeparatorScrollbar(bool b)
+{
+ m_Settings.setValue("Settings/colorSeparatorScrollbars", b);
+}
+
void Settings::managedGameChanged(IPluginGame const *gamePlugin)
{
m_GamePlugin = gamePlugin;
@@ -397,6 +409,11 @@ bool Settings::usePrereleases() const
return m_Settings.value("Settings/use_prereleases", false).toBool();
}
+void Settings::setUsePrereleases(bool b)
+{
+ m_Settings.setValue("Settings/use_prereleases", b);
+}
+
void Settings::setDownloadSpeed(const QString &serverName, int bytesPerSecond)
{
m_Settings.beginGroup("Servers");
@@ -615,16 +632,27 @@ bool Settings::getSteamLogin(QString &username, QString &password) const
return !username.isEmpty() && !password.isEmpty();
}
+
bool Settings::compactDownloads() const
{
return m_Settings.value("Settings/compact_downloads", false).toBool();
}
+void Settings::setCompactDownloads(bool b)
+{
+ m_Settings.setValue("Settings/compact_downloads", b);
+}
+
bool Settings::metaDownloads() const
{
return m_Settings.value("Settings/meta_downloads", false).toBool();
}
+void Settings::setMetaDownloads(bool b)
+{
+ m_Settings.setValue("Settings/meta_downloads", b);
+}
+
bool Settings::offlineMode() const
{
return m_Settings.value("Settings/offline_mode", false).toBool();
@@ -640,44 +668,25 @@ void Settings::setLogLevel(log::Levels level)
m_Settings.setValue("Settings/log_level", static_cast(level));
}
-int Settings::crashDumpsType() const
+CrashDumpsType Settings::crashDumpsType() const
{
- return m_Settings.value("Settings/crash_dumps_type", static_cast(CrashDumpsType::Mini)).toInt();
+ const auto v = getOptional(m_Settings, "Settings/crash_dumps_type");
+ return v.value_or(CrashDumpsType::Mini);
}
-int Settings::crashDumpsMax() const
+void Settings::setCrashDumpsType(CrashDumpsType type)
{
- return m_Settings.value("Settings/crash_dumps_max", 5).toInt();
+ m_Settings.setValue("Settings/crash_dumps_type", static_cast(type));
}
-QColor Settings::modlistOverwrittenLooseColor() const
-{
- return m_Settings.value("Settings/overwrittenLooseFilesColor", QColor(0, 255, 0, 64)).value();
-}
-
-QColor Settings::modlistOverwritingLooseColor() const
-{
- return m_Settings.value("Settings/overwritingLooseFilesColor", QColor(255, 0, 0, 64)).value();
-}
-
-QColor Settings::modlistOverwrittenArchiveColor() const
-{
- return m_Settings.value("Settings/overwrittenArchiveFilesColor", QColor(0, 255, 255, 64)).value();
-}
-
-QColor Settings::modlistOverwritingArchiveColor() const
-{
- return m_Settings.value("Settings/overwritingArchiveFilesColor", QColor(255, 0, 255, 64)).value();
-}
-
-QColor Settings::modlistContainsPluginColor() const
+int Settings::crashDumpsMax() const
{
- return m_Settings.value("Settings/containsPluginColor", QColor(0, 0, 255, 64)).value();
+ return m_Settings.value("Settings/crash_dumps_max", 5).toInt();
}
-QColor Settings::pluginListContainedColor() const
+void Settings::setCrashDumpsMax(int n)
{
- return m_Settings.value("Settings/containedColor", QColor(0, 0, 255, 64)).value();
+ return m_Settings.setValue("Settings/crash_dumps_max", n);
}
QString Settings::executablesBlacklist() const
@@ -850,6 +859,11 @@ QString Settings::language()
return result;
}
+void Settings::setLanguage(const QString& name)
+{
+ m_Settings.setValue("Settings/language", name);
+}
+
void Settings::updateServers(const QList &servers)
{
m_Settings.beginGroup("Servers");
@@ -1132,6 +1146,16 @@ const GeometrySettings& Settings::geometry() const
return m_Geometry;
}
+ColorSettings& Settings::colors()
+{
+ return m_Colors;
+}
+
+const ColorSettings& Settings::colors() const
+{
+ return m_Colors;
+}
+
QSettings::Status Settings::sync() const
{
m_Settings.sync();
@@ -1451,6 +1475,78 @@ void GeometrySettings::restoreDocks(QMainWindow* mw) const
}
+ColorSettings::ColorSettings(QSettings& s)
+ : m_Settings(s)
+{
+}
+
+QColor ColorSettings::modlistOverwrittenLoose() const
+{
+ return getOptional(m_Settings, "Settings/overwrittenLooseFilesColor")
+ .value_or(QColor(0, 255, 0, 64));
+}
+
+void ColorSettings::setModlistOverwrittenLoose(const QColor& c)
+{
+ m_Settings.setValue("Settings/overwrittenLooseFilesColor", c);
+}
+
+QColor ColorSettings::modlistOverwritingLoose() const
+{
+ return getOptional(m_Settings, "Settings/overwritingLooseFilesColor")
+ .value_or(QColor(255, 0, 0, 64));
+}
+
+void ColorSettings::setModlistOverwritingLoose(const QColor& c)
+{
+ m_Settings.setValue("Settings/overwritingLooseFilesColor", c);
+}
+
+QColor ColorSettings::modlistOverwrittenArchive() const
+{
+ return getOptional(m_Settings, "Settings/overwrittenArchiveFilesColor")
+ .value_or(QColor(0, 255, 255, 64));
+}
+
+void ColorSettings::setModlistOverwrittenArchive(const QColor& c)
+{
+ m_Settings.setValue("Settings/overwrittenArchiveFilesColor", c);
+}
+
+QColor ColorSettings::modlistOverwritingArchive() const
+{
+ return getOptional(m_Settings, "Settings/overwritingArchiveFilesColor")
+ .value_or(QColor(255, 0, 255, 64));
+}
+
+void ColorSettings::setModlistOverwritingArchive(const QColor& c)
+{
+ m_Settings.setValue("Settings/overwritingArchiveFilesColor", c);
+}
+
+QColor ColorSettings::modlistContainsPlugin() const
+{
+ return getOptional(m_Settings, "Settings/containsPluginColor")
+ .value_or(QColor(0, 0, 255, 64));
+}
+
+void ColorSettings::setModlistContainsPlugin(const QColor& c)
+{
+ m_Settings.setValue("Settings/containsPluginColor", c);
+}
+
+QColor ColorSettings::pluginListContained() const
+{
+ return getOptional(m_Settings, "Settings/containedColor")
+ .value_or(QColor(0, 0, 255, 64));
+}
+
+void ColorSettings::setPluginListContained(const QColor& c)
+{
+ m_Settings.setValue("Settings/containedColor", c);
+}
+
+
GeometrySaver::GeometrySaver(Settings& s, QDialog* dialog)
: m_settings(s), m_dialog(dialog)
{
diff --git a/src/settings.h b/src/settings.h
index b25af15f..5b1d7bfc 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -23,6 +23,7 @@ along with Mod Organizer. If not, see .
#include "loadmechanism.h"
#include
#include
+#include
namespace MOBase {
class IPlugin;
@@ -96,6 +97,36 @@ private:
};
+class ColorSettings
+{
+public:
+ ColorSettings(QSettings& s);
+
+ void setCrashDumpsMax(int i) const;
+
+ QColor modlistOverwrittenLoose() const;
+ void setModlistOverwrittenLoose(const QColor& c);
+
+ QColor modlistOverwritingLoose() const;
+ void setModlistOverwritingLoose(const QColor& c);
+
+ QColor modlistOverwrittenArchive() const;
+ void setModlistOverwrittenArchive(const QColor& c);
+
+ QColor modlistOverwritingArchive() const;
+ void setModlistOverwritingArchive(const QColor& c);
+
+ QColor modlistContainsPlugin() const;
+ void setModlistContainsPlugin(const QColor& c);
+
+ QColor pluginListContained() const;
+ void setPluginListContained(const QColor& c) ;
+
+private:
+ QSettings& m_Settings;
+};
+
+
enum class EndorsementState
{
Accepted = 1,
@@ -268,6 +299,10 @@ public:
GeometrySettings& geometry();
const GeometrySettings& geometry() const;
+ ColorSettings& colors();
+ const ColorSettings& colors() const;
+
+
/**
* retrieve the directory where profiles stored (with native separators)
**/
@@ -329,43 +364,22 @@ public:
* @return true if the user chose compact downloads
*/
bool compactDownloads() const;
+ void setCompactDownloads(bool b);
/**
* @return true if the user chose meta downloads
*/
bool metaDownloads() const;
+ void setMetaDownloads(bool b);
- /**
- * @return the configured log level
- */
MOBase::log::Levels logLevel() const;
-
- /**
- * sets the log level setting
- */
void setLogLevel(MOBase::log::Levels level);
- /**
- * @return the configured crash dumps type
- */
- int crashDumpsType() const;
+ CrashDumpsType crashDumpsType() const;
+ void setCrashDumpsType(CrashDumpsType type);
- /**
- * @return the configured crash dumps max
- */
int crashDumpsMax() const;
-
- QColor modlistOverwrittenLooseColor() const;
-
- QColor modlistOverwritingLooseColor() const;
-
- QColor modlistOverwrittenArchiveColor() const;
-
- QColor modlistOverwritingArchiveColor() const;
-
- QColor modlistContainsPluginColor() const;
-
- QColor pluginListContainedColor() const;
+ void setCrashDumpsMax(int n);
QString executablesBlacklist() const;
@@ -473,6 +487,7 @@ public:
* @return short code of the configured language (corresponding to the translation files)
*/
QString language();
+ void setLanguage(const QString& name);
/**
* @brief updates the list of known servers
@@ -499,6 +514,7 @@ public:
std::vector plugins() const { return m_Plugins; }
bool usePrereleases() const;
+ void setUsePrereleases(bool b);
/**
* @brief register MO as the handler for nxm links
@@ -512,6 +528,7 @@ public:
* @return the state of the setting
*/
bool colorSeparatorScrollbar() const;
+ void setColorSeparatorScrollbar(bool b);
static QColor getIdealTextColor(const QColor& rBackgroundColor);
@@ -540,6 +557,7 @@ private:
MOBase::IPluginGame const *m_GamePlugin;
mutable QSettings m_Settings;
GeometrySettings m_Geometry;
+ ColorSettings m_Colors;
LoadMechanism m_LoadMechanism;
std::vector m_Plugins;
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 097dafc8..9d031785 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -51,43 +51,19 @@ int SettingsDialog::exec()
{
GeometrySaver gs(m_settings, this);
- auto& qsettings = m_settings.directInterface();
auto ret = TutorableDialog::exec();
if (ret == QDialog::Accepted) {
-
for (auto&& tab : m_tabs) {
tab->closing();
}
- // remember settings before change
- QMap before;
- qsettings.beginGroup("Settings");
- for (auto k : qsettings.allKeys())
- before[k] = qsettings.value(k).toString();
- qsettings.endGroup();
-
- // transfer modified settings to configuration file
+ // update settings for each tab
for (std::unique_ptr const &tab: m_tabs) {
tab->update();
}
-
- // print "changed" settings
- qsettings.beginGroup("Settings");
- bool first_update = true;
- for (auto k : qsettings.allKeys())
- if (qsettings.value(k).toString() != before[k] && !k.contains("username") && !k.contains("password"))
- {
- if (first_update) {
- log::debug("Changed settings:");
- first_update = false;
- }
- log::debug(" {}={}", k, qsettings.value(k).toString());
- }
- qsettings.endGroup();
}
- // These changes happen regardless of accepted or rejected
bool restartNeeded = false;
if (getApiKeyChanged()) {
restartNeeded = true;
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui
index e7676387..af230bc0 100644
--- a/src/settingsdialog.ui
+++ b/src/settingsdialog.ui
@@ -1346,26 +1346,6 @@ programs you are intentionally running.
"Full" Even larger dumps with a full memory dump of the process.
- -
-
- None
-
-
- -
-
- Mini (recommended)
-
-
- -
-
- Data
-
-
- -
-
- Full
-
-
diff --git a/src/settingsdialogdiagnostics.cpp b/src/settingsdialogdiagnostics.cpp
index 227d1dfa..278da0bf 100644
--- a/src/settingsdialogdiagnostics.cpp
+++ b/src/settingsdialogdiagnostics.cpp
@@ -10,10 +10,13 @@ DiagnosticsSettingsTab::DiagnosticsSettingsTab(Settings& s, SettingsDialog& d)
: SettingsTab(s, d)
{
setLevelsBox();
- ui->dumpsTypeBox->setCurrentIndex(settings().crashDumpsType());
+ setCrashDumpTypesBox();
+
ui->dumpsMaxEdit->setValue(settings().crashDumpsMax());
+
QString logsPath = qApp->property("dataPath").toString()
+ "/" + QString::fromStdWString(AppConfig::logPath());
+
ui->diagnosticsExplainedLabel->setText(
ui->diagnosticsExplainedLabel->text()
.replace("LOGS_FULL_PATH", logsPath)
@@ -40,9 +43,36 @@ void DiagnosticsSettingsTab::setLevelsBox()
}
}
+void DiagnosticsSettingsTab::setCrashDumpTypesBox()
+{
+ ui->dumpsTypeBox->clear();
+
+ auto add = [&](auto&& text, auto&& type) {
+ ui->dumpsTypeBox->addItem(text, static_cast(type));
+ };
+
+ add(QObject::tr("None"), CrashDumpsType::None);
+ add(QObject::tr("Mini (recommended)"), CrashDumpsType::Mini);
+ add(QObject::tr("Data"), CrashDumpsType::Data);
+ add(QObject::tr("Full"), CrashDumpsType::Full);
+
+ const auto current = static_cast(settings().crashDumpsType());
+
+ for (int i=0; idumpsTypeBox->count(); ++i) {
+ if (ui->dumpsTypeBox->itemData(i) == current) {
+ ui->dumpsTypeBox->setCurrentIndex(i);
+ break;
+ }
+ }
+}
+
void DiagnosticsSettingsTab::update()
{
- qsettings().setValue("Settings/log_level", ui->logLevelBox->currentData().toInt());
- qsettings().setValue("Settings/crash_dumps_type", ui->dumpsTypeBox->currentIndex());
- qsettings().setValue("Settings/crash_dumps_max", ui->dumpsMaxEdit->value());
+ settings().setLogLevel(
+ static_cast(ui->logLevelBox->currentData().toInt()));
+
+ settings().setCrashDumpsType(
+ static_cast(ui->dumpsTypeBox->currentData().toInt()));
+
+ settings().setCrashDumpsMax(ui->dumpsMaxEdit->value());
}
diff --git a/src/settingsdialogdiagnostics.h b/src/settingsdialogdiagnostics.h
index f20413f8..f0fbf770 100644
--- a/src/settingsdialogdiagnostics.h
+++ b/src/settingsdialogdiagnostics.h
@@ -13,6 +13,7 @@ public:
private:
void setLevelsBox();
+ void setCrashDumpTypesBox();
};
#endif // SETTINGSDIALOGDIAGNOSTICS_H
diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp
index 35012db7..e3d73037 100644
--- a/src/settingsdialoggeneral.cpp
+++ b/src/settingsdialoggeneral.cpp
@@ -26,28 +26,30 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d)
}
addStyles();
+
{
- int currentID = ui->styleBox->findData(
- qsettings().value("Settings/style", "").toString());
+ const int currentID = ui->styleBox->findData(
+ settings().getStyleName().value_or(""));
+
if (currentID != -1) {
ui->styleBox->setCurrentIndex(currentID);
}
}
//version with stylesheet
- setButtonColor(ui->overwritingBtn, settings().modlistOverwritingLooseColor());
- setButtonColor(ui->overwrittenBtn, settings().modlistOverwrittenLooseColor());
- setButtonColor(ui->overwritingArchiveBtn, settings().modlistOverwritingArchiveColor());
- setButtonColor(ui->overwrittenArchiveBtn, settings().modlistOverwrittenArchiveColor());
- setButtonColor(ui->containsBtn, settings().modlistContainsPluginColor());
- setButtonColor(ui->containedBtn, settings().pluginListContainedColor());
-
- setOverwritingColor(settings().modlistOverwritingLooseColor());
- setOverwrittenColor(settings().modlistOverwrittenLooseColor());
- setOverwritingArchiveColor(settings().modlistOverwritingArchiveColor());
- setOverwrittenArchiveColor(settings().modlistOverwrittenArchiveColor());
- setContainsColor(settings().modlistContainsPluginColor());
- setContainedColor(settings().pluginListContainedColor());
+ setButtonColor(ui->overwritingBtn, settings().colors().modlistOverwritingLoose());
+ setButtonColor(ui->overwrittenBtn, settings().colors().modlistOverwrittenLoose());
+ setButtonColor(ui->overwritingArchiveBtn, settings().colors().modlistOverwritingArchive());
+ setButtonColor(ui->overwrittenArchiveBtn, settings().colors().modlistOverwrittenArchive());
+ setButtonColor(ui->containsBtn, settings().colors().modlistContainsPlugin());
+ setButtonColor(ui->containedBtn, settings().colors().pluginListContained());
+
+ setOverwritingColor(settings().colors().modlistOverwritingLoose());
+ setOverwrittenColor(settings().colors().modlistOverwrittenLoose());
+ setOverwritingArchiveColor(settings().colors().modlistOverwritingArchive());
+ setOverwrittenArchiveColor(settings().colors().modlistOverwrittenArchive());
+ setContainsColor(settings().colors().modlistContainsPlugin());
+ setContainedColor(settings().colors().pluginListContained());
ui->compactBox->setChecked(settings().compactDownloads());
ui->showMetaBox->setChecked(settings().metaDownloads());
@@ -67,30 +69,32 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d)
void GeneralSettingsTab::update()
{
- QString oldLanguage = settings().language();
- QString newLanguage = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString();
+ const QString oldLanguage = settings().language();
+ const QString newLanguage = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString();
+
if (newLanguage != oldLanguage) {
- qsettings().setValue("Settings/language", newLanguage);
+ settings().setLanguage(newLanguage);
emit settings().languageChanged(newLanguage);
}
- QString oldStyle = qsettings().value("Settings/style", "").toString();
- QString newStyle = ui->styleBox->itemData(ui->styleBox->currentIndex()).toString();
+ const QString oldStyle = settings().getStyleName().value_or("");
+ const QString newStyle = ui->styleBox->itemData(ui->styleBox->currentIndex()).toString();
if (oldStyle != newStyle) {
- qsettings().setValue("Settings/style", newStyle);
+ settings().setStyleName(newStyle);
emit settings().styleChanged(newStyle);
}
- qsettings().setValue("Settings/overwritingLooseFilesColor", getOverwritingColor());
- qsettings().setValue("Settings/overwrittenLooseFilesColor", getOverwrittenColor());
- qsettings().setValue("Settings/overwritingArchiveFilesColor", getOverwritingArchiveColor());
- qsettings().setValue("Settings/overwrittenArchiveFilesColor", getOverwrittenArchiveColor());
- qsettings().setValue("Settings/containsPluginColor", getContainsColor());
- qsettings().setValue("Settings/containedColor", getContainedColor());
- qsettings().setValue("Settings/compact_downloads", ui->compactBox->isChecked());
- qsettings().setValue("Settings/meta_downloads", ui->showMetaBox->isChecked());
- qsettings().setValue("Settings/use_prereleases", ui->usePrereleaseBox->isChecked());
- qsettings().setValue("Settings/colorSeparatorScrollbars", ui->colorSeparatorsBox->isChecked());
+ settings().colors().setModlistOverwritingLoose(getOverwritingColor());
+ settings().colors().setModlistOverwrittenLoose(getOverwrittenColor());
+ settings().colors().setModlistOverwritingArchive(getOverwritingArchiveColor());
+ settings().colors().setModlistOverwrittenArchive(getOverwrittenArchiveColor());
+ settings().colors().setModlistContainsPlugin(getContainsColor());
+ settings().colors().setPluginListContained(getContainedColor());
+
+ settings().setCompactDownloads(ui->compactBox->isChecked());
+ settings().setMetaDownloads(ui->showMetaBox->isChecked());
+ settings().setUsePrereleases(ui->usePrereleaseBox->isChecked());
+ settings().setColorSeparatorScrollbar(ui->colorSeparatorsBox->isChecked());
}
void GeneralSettingsTab::addLanguages()
diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp
index b5e6edb1..41f58308 100644
--- a/src/usvfsconnector.cpp
+++ b/src/usvfsconnector.cpp
@@ -164,7 +164,7 @@ UsvfsConnector::UsvfsConnector()
{
USVFSParameters params;
LogLevel level = toUsvfsLogLevel(Settings::instance().logLevel());
- CrashDumpsType dumpType = crashDumpsType(Settings::instance().crashDumpsType());
+ CrashDumpsType dumpType = Settings::instance().crashDumpsType();
std::string dumpPath = MOShared::ToString(OrganizerCore::crashDumpsPath(), true);
USVFSInitParameters(¶ms, SHMID, false, level, dumpType, dumpPath.c_str());
@@ -249,9 +249,10 @@ void UsvfsConnector::updateMapping(const MappingType &mapping)
}
void UsvfsConnector::updateParams(
- MOBase::log::Levels logLevel, int crashDumpsType, QString executableBlacklist)
+ MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
+ QString executableBlacklist)
{
- USVFSUpdateParams(toUsvfsLogLevel(logLevel), ::crashDumpsType(crashDumpsType));
+ USVFSUpdateParams(toUsvfsLogLevel(logLevel), crashDumpsType);
ClearExecutableBlacklist();
for (auto exec : executableBlacklist.split(";")) {
std::wstring buf = exec.toStdWString();
diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h
index b0bd320c..cd5d56b2 100644
--- a/src/usvfsconnector.h
+++ b/src/usvfsconnector.h
@@ -87,7 +87,7 @@ public:
void updateMapping(const MappingType &mapping);
void updateParams(
- MOBase::log::Levels logLevel, int crashDumpsType,
+ MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
QString executableBlacklist);
void updateForcedLibraries(const QList &forcedLibraries);
--
cgit v1.3.1
From 324fa12a2d491be039c1cf720ee2786864d010bc Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Thu, 10 Oct 2019 10:25:46 -0400
Subject: uses new usvfsParameters, also updates spawn delay
---
src/organizercore.cpp | 6 ++++--
src/organizercore.h | 2 +-
src/usvfsconnector.cpp | 44 ++++++++++++++++++++++++++++++++------------
src/usvfsconnector.h | 2 +-
4 files changed, 38 insertions(+), 16 deletions(-)
(limited to 'src/usvfsconnector.h')
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 335910da..df824c2b 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -484,10 +484,11 @@ void OrganizerCore::prepareVFS()
}
void OrganizerCore::updateVFSParams(
- log::Levels logLevel, CrashDumpsType crashDumpsType, QString executableBlacklist)
+ log::Levels logLevel, CrashDumpsType crashDumpsType,
+ std::chrono::seconds spawnDelay, QString executableBlacklist)
{
setGlobalCrashDumpsType(crashDumpsType);
- m_USVFS.updateParams(logLevel, crashDumpsType, executableBlacklist);
+ m_USVFS.updateParams(logLevel, crashDumpsType, spawnDelay, executableBlacklist);
}
void OrganizerCore::setLogLevel(log::Levels level)
@@ -497,6 +498,7 @@ void OrganizerCore::setLogLevel(log::Levels level)
updateVFSParams(
m_Settings.diagnostics().logLevel(),
m_Settings.diagnostics().crashDumpsType(),
+ m_Settings.diagnostics().spawnDelay(),
m_Settings.executablesBlacklist());
log::getDefault().setLevel(m_Settings.diagnostics().logLevel());
diff --git a/src/organizercore.h b/src/organizercore.h
index 5de550df..5b7dd87b 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -195,7 +195,7 @@ public:
void updateVFSParams(
MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
- QString executableBlacklist);
+ std::chrono::seconds spawnDelay, QString executableBlacklist);
void setLogLevel(MOBase::log::Levels level);
diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp
index 3ea811be..9a4fa742 100644
--- a/src/usvfsconnector.cpp
+++ b/src/usvfsconnector.cpp
@@ -162,15 +162,24 @@ QString toString(CrashDumpsType t)
UsvfsConnector::UsvfsConnector()
{
+ using namespace std::chrono;
+
const auto& s = Settings::instance();
- USVFSParameters params;
- const LogLevel level = toUsvfsLogLevel(s.diagnostics().logLevel());
+ const LogLevel logLevel = toUsvfsLogLevel(s.diagnostics().logLevel());
const CrashDumpsType dumpType = s.diagnostics().crashDumpsType();
- const auto delay = s.diagnostics().spawnDelay();
-
+ const auto delay = duration_cast(s.diagnostics().spawnDelay());
std::string dumpPath = MOShared::ToString(OrganizerCore::crashDumpsPath(), true);
- USVFSInitParameters(¶ms, SHMID, false, level, dumpType, dumpPath.c_str(), delay);
+
+ usvfsParameters* params = usvfsCreateParameters();
+
+ usvfsSetInstanceName(params, SHMID);
+ usvfsSetDebugMode(params, false);
+ usvfsSetLogLevel(params, logLevel);
+ usvfsSetCrashDumpType(params, dumpType);
+ usvfsSetCrashDumpPath(params, dumpPath.c_str());
+ usvfsSetProcessDelay(params, delay.count());
+
InitLogging(false);
log::debug(
@@ -178,12 +187,13 @@ UsvfsConnector::UsvfsConnector()
" . instance: {}\n"
" . log: {}\n"
" . dump: {} ({})",
- params.instanceName,
- toString(params.logLevel),
- params.crashDumpsPath,
- toString(params.crashDumpsType));
+ SHMID,
+ toString(logLevel),
+ dumpPath.c_str(),
+ toString(dumpType));
- CreateVFS(¶ms);
+ usvfsCreateVFS(params);
+ usvfsFreeParameters(params);
ClearExecutableBlacklist();
for (auto exec : s.executablesBlacklist().split(";")) {
@@ -253,9 +263,19 @@ void UsvfsConnector::updateMapping(const MappingType &mapping)
void UsvfsConnector::updateParams(
MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
- QString executableBlacklist)
+ std::chrono::seconds spawnDelay, QString executableBlacklist)
{
- USVFSUpdateParams(toUsvfsLogLevel(logLevel), crashDumpsType);
+ using namespace std::chrono;
+
+ usvfsParameters* p = usvfsCreateParameters();
+
+ usvfsSetLogLevel(p, toUsvfsLogLevel(logLevel));
+ usvfsSetCrashDumpType(p, crashDumpsType);
+ usvfsSetProcessDelay(p, duration_cast(spawnDelay).count());
+
+ usvfsUpdateParameters(p);
+ usvfsFreeParameters(p);
+
ClearExecutableBlacklist();
for (auto exec : executableBlacklist.split(";")) {
std::wstring buf = exec.toStdWString();
diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h
index cd5d56b2..a4647eaf 100644
--- a/src/usvfsconnector.h
+++ b/src/usvfsconnector.h
@@ -88,7 +88,7 @@ public:
void updateParams(
MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
- QString executableBlacklist);
+ std::chrono::seconds spawnDelay, QString executableBlacklist);
void updateForcedLibraries(const QList &forcedLibraries);
--
cgit v1.3.1
From 33f5b59bee9fe5a1b3515737819ddfec4f596423 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 1 Nov 2019 10:14:17 -0400
Subject: added crash dump path to parameters, if a mechanism to customize it
is ever created moved toString() for log level and dump type to usvfs, which
needs them for logging
---
src/organizercore.cpp | 5 ++++-
src/organizercore.h | 3 ++-
src/usvfsconnector.cpp | 51 ++++++--------------------------------------------
src/usvfsconnector.h | 6 ++++--
4 files changed, 16 insertions(+), 49 deletions(-)
(limited to 'src/usvfsconnector.h')
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index df824c2b..5613e8ce 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -485,10 +485,12 @@ void OrganizerCore::prepareVFS()
void OrganizerCore::updateVFSParams(
log::Levels logLevel, CrashDumpsType crashDumpsType,
+ const QString& crashDumpsPath,
std::chrono::seconds spawnDelay, QString executableBlacklist)
{
setGlobalCrashDumpsType(crashDumpsType);
- m_USVFS.updateParams(logLevel, crashDumpsType, spawnDelay, executableBlacklist);
+ m_USVFS.updateParams(
+ logLevel, crashDumpsType, crashDumpsPath, spawnDelay, executableBlacklist);
}
void OrganizerCore::setLogLevel(log::Levels level)
@@ -498,6 +500,7 @@ void OrganizerCore::setLogLevel(log::Levels level)
updateVFSParams(
m_Settings.diagnostics().logLevel(),
m_Settings.diagnostics().crashDumpsType(),
+ QString::fromStdWString(crashDumpsPath()),
m_Settings.diagnostics().spawnDelay(),
m_Settings.executablesBlacklist());
diff --git a/src/organizercore.h b/src/organizercore.h
index 5b7dd87b..0d0a092c 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -195,7 +195,8 @@ public:
void updateVFSParams(
MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
- std::chrono::seconds spawnDelay, QString executableBlacklist);
+ const QString& crashDumpsPath, std::chrono::seconds spawnDelay,
+ QString executableBlacklist);
void setLogLevel(MOBase::log::Levels level);
diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp
index 9a4fa742..311c6dd3 100644
--- a/src/usvfsconnector.cpp
+++ b/src/usvfsconnector.cpp
@@ -118,48 +118,6 @@ CrashDumpsType crashDumpsType(int type)
}
}
-QString toString(LogLevel lv)
-{
- switch (lv)
- {
- case LogLevel::Debug:
- return "debug";
-
- case LogLevel::Info:
- return "info";
-
- case LogLevel::Warning:
- return "warning";
-
- case LogLevel::Error:
- return "error";
-
- default:
- return QString("%1").arg(static_cast(lv));
- }
-}
-
-QString toString(CrashDumpsType t)
-{
- switch (t)
- {
- case CrashDumpsType::None:
- return "none";
-
- case CrashDumpsType::Mini:
- return "mini";
-
- case CrashDumpsType::Data:
- return "data";
-
- case CrashDumpsType::Full:
- return "full";
-
- default:
- return QString("%1").arg(static_cast(t));
- }
-}
-
UsvfsConnector::UsvfsConnector()
{
using namespace std::chrono;
@@ -188,9 +146,9 @@ UsvfsConnector::UsvfsConnector()
" . log: {}\n"
" . dump: {} ({})",
SHMID,
- toString(logLevel),
+ usvfsLogLevelToString(logLevel),
dumpPath.c_str(),
- toString(dumpType));
+ usvfsCrashDumpTypeToString(dumpType));
usvfsCreateVFS(params);
usvfsFreeParameters(params);
@@ -263,14 +221,17 @@ void UsvfsConnector::updateMapping(const MappingType &mapping)
void UsvfsConnector::updateParams(
MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
- std::chrono::seconds spawnDelay, QString executableBlacklist)
+ const QString& crashDumpsPath, std::chrono::seconds spawnDelay,
+ QString executableBlacklist)
{
using namespace std::chrono;
usvfsParameters* p = usvfsCreateParameters();
+ usvfsSetDebugMode(p, FALSE);
usvfsSetLogLevel(p, toUsvfsLogLevel(logLevel));
usvfsSetCrashDumpType(p, crashDumpsType);
+ usvfsSetCrashDumpPath(p, crashDumpsPath.toStdString().c_str());
usvfsSetProcessDelay(p, duration_cast(spawnDelay).count());
usvfsUpdateParameters(p);
diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h
index a4647eaf..d0071678 100644
--- a/src/usvfsconnector.h
+++ b/src/usvfsconnector.h
@@ -88,9 +88,11 @@ public:
void updateParams(
MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType,
- std::chrono::seconds spawnDelay, QString executableBlacklist);
+ const QString& crashDumpsPath, std::chrono::seconds spawnDelay,
+ QString executableBlacklist);
- void updateForcedLibraries(const QList &forcedLibraries);
+ void updateForcedLibraries(
+ const QList &forcedLibraries);
private:
--
cgit v1.3.1
From 18b438cf27a552e69e984bfee63187b6471682ab Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Tue, 29 Oct 2019 07:28:12 -0400
Subject: split to getRunningUSVFSProcesses() simplified
waitForAllUSVFSProcesses() to always get the list of running processes after
one process completes
---
src/envmodule.cpp | 6 ++
src/envmodule.h | 2 +
src/organizercore.cpp | 224 ++++++++++++++-----------------------------------
src/spawn.cpp | 53 ++++++++----
src/spawn.h | 4 +
src/usvfsconnector.cpp | 47 +++++++++++
src/usvfsconnector.h | 2 +
7 files changed, 163 insertions(+), 175 deletions(-)
(limited to 'src/usvfsconnector.h')
diff --git a/src/envmodule.cpp b/src/envmodule.cpp
index abbe02e5..160a54fa 100644
--- a/src/envmodule.cpp
+++ b/src/envmodule.cpp
@@ -511,4 +511,10 @@ DWORD getProcessParentID(DWORD pid)
return ppid;
}
+
+DWORD getProcessParentID(HANDLE handle)
+{
+ return getProcessParentID(GetProcessId(handle));
+}
+
} // namespace
diff --git a/src/envmodule.h b/src/envmodule.h
index 212f6f7b..6c0a028d 100644
--- a/src/envmodule.h
+++ b/src/envmodule.h
@@ -121,7 +121,9 @@ std::vector getRunningProcesses();
std::vector getLoadedModules();
QString getProcessName(HANDLE process);
+
DWORD getProcessParentID(DWORD pid);
+DWORD getProcessParentID(HANDLE handle);
} // namespace env
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 2a228fda..2a97b998 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -1355,17 +1355,13 @@ bool OrganizerCore::waitForApplication(HANDLE handle, LPDWORD exitCode)
if (!Settings::instance().interface().lockGUI())
return true;
- ILockedWaitingForProcess* uilock = nullptr;
- if (m_MainWindow != nullptr) {
- uilock = m_MainWindow->lock();
- }
+ bool r = false;
- ON_BLOCK_EXIT([&] () {
- if (m_MainWindow != nullptr) {
- m_MainWindow->unlock();
- } });
+ withLock([&](auto* uilock) {
+ r = waitForProcessCompletion(handle, exitCode, uilock);
+ });
- return waitForProcessCompletion(handle, exitCode, uilock);
+ return r;
}
bool OrganizerCore::waitForProcessCompletion(
@@ -1387,6 +1383,9 @@ bool OrganizerCore::waitForProcessCompletion(
bool OrganizerCore::waitForAllUSVFSProcessesWithLock()
{
+ if (!Settings::instance().interface().lockGUI())
+ return true;
+
bool r = false;
withLock([&](auto* uilock) {
@@ -1396,178 +1395,81 @@ bool OrganizerCore::waitForAllUSVFSProcessesWithLock()
return r;
}
-bool OrganizerCore::waitForAllUSVFSProcesses(ILockedWaitingForProcess* uilock)
+HANDLE getInterestingProcess(
+ const std::vector& handles,
+ const std::vector& hidden, DWORD preferedParentPid)
{
- // Certain process names we wish to "hide" for aesthetic reason:
- std::vector hiddenList;
- hiddenList.push_back(QFileInfo(QCoreApplication::applicationFilePath()).fileName());
-
- bool originalHandle = true;
- bool newHandle = true;
- bool uiunlocked = false;
-
- HANDLE handle = findAndOpenAUSVFSProcess(hiddenList, GetCurrentProcessId());
- DWORD* exitCode = nullptr;
- DWORD currentPID = 0;
- QString processName;
-
- auto waitForChildUntil = GetTickCount64();
- if (handle != INVALID_HANDLE_VALUE) {
- currentPID = GetProcessId(handle);
- processName = env::getProcessName(handle);
- }
-
- bool waitingOnHidden = false;
- for (QString hide : hiddenList)
- if (processName.contains(hide, Qt::CaseInsensitive))
- waitingOnHidden = true;
-
- // The main reason for adding the hidden list is to hide the MO proxy we use to spawn virtualized processes.
- // On the one hand we want to display the real executable without it feeling laggy, on the other we don't want
- // to requery processes all the time if for some reason we are waiting on hidden processes and find no "unhidden"
- // process. For this reason we use exponential backoff and also start with a delibrately low value to improve
- // the responsiveness of the initial update
- DWORD64 nextHiddenCheck = GetTickCount64();
- DWORD64 nextHiddenCheckDelay = 50;
-
- constexpr DWORD INPUT_EVENT = WAIT_OBJECT_0 + 1;
- DWORD res = WAIT_TIMEOUT;
- while (handle != INVALID_HANDLE_VALUE && (newHandle || res == WAIT_TIMEOUT || res == INPUT_EVENT))
- {
- if (newHandle) {
- processName += QString(" (%1)").arg(currentPID);
- if (uilock)
- uilock->setProcessName(processName);
-
- log::debug(
- "Waiting for {} process completion: {}",
- (originalHandle ? "spawned" : "usvfs"), processName);
-
- newHandle = false;
- }
+ HANDLE best_match = INVALID_HANDLE_VALUE;
+ bool best_match_hidden = true;
- // Wait for a an event on the handle, a key press, mouse click or timeout
- res = MsgWaitForMultipleObjects(1, &handle, FALSE, 200, QS_KEY | QS_MOUSEBUTTON);
- if (res == WAIT_FAILED) {
- log::warn("Failed waiting for process completion : MsgWaitForMultipleObjects WAIT_FAILED {}", GetLastError());
- break;
- }
+ for (auto handle : handles) {
+ const QString pname = env::getProcessName(handle);
- // keep processing events so the app doesn't appear dead
- QCoreApplication::sendPostedEvents();
- QCoreApplication::processEvents();
+ bool phidden = false;
+ for (auto h : hidden)
+ if (pname.contains(h, Qt::CaseInsensitive))
+ phidden = true;
- if (uilock && uilock->unlockForced()) {
- uiunlocked = true;
- break;
- }
+ bool pprefered = preferedParentPid && env::getProcessParentID(handle) == preferedParentPid;
- if (res == WAIT_OBJECT_0) {
- // process we were waiting on has completed
- if (originalHandle && exitCode && !::GetExitCodeProcess(handle, exitCode))
- log::warn("Failed getting exit code of complete process: {}", GetLastError());
- CloseHandle(handle);
- handle = INVALID_HANDLE_VALUE;
- originalHandle = false;
- // if the previous process spawned a child process and immediately exits we may miss it if we check immediately
- waitForChildUntil = GetTickCount64() + 800;
+ if (best_match == INVALID_HANDLE_VALUE || best_match_hidden || (!phidden && pprefered)) {
+ best_match = handle;
+ best_match_hidden = phidden;
}
- // search for another process to wait on if either:
- // 1. we just completed waiting for a process and need to find/wait for an inject child
- // 2. we are currently waiting on a hidden process so periodically check if there is a non-hidden process to wait on
- bool firstIteration = true;
- while ((handle == INVALID_HANDLE_VALUE && GetTickCount64() <= waitForChildUntil)
- || (waitingOnHidden && GetTickCount64() >= nextHiddenCheck))
- {
- if (firstIteration)
- firstIteration = false;
- else {
- QThread::msleep(200);
- QCoreApplication::sendPostedEvents();
- QCoreApplication::processEvents();
- }
-
- // search if there is another usvfs process active
- handle = findAndOpenAUSVFSProcess(hiddenList, currentPID);
- waitingOnHidden = false;
- newHandle = handle != INVALID_HANDLE_VALUE;
- if (newHandle) {
- currentPID = GetProcessId(handle);
- processName = env::getProcessName(handle);
- for (QString hide : hiddenList)
- if (processName.contains(hide, Qt::CaseInsensitive))
- waitingOnHidden = true;
- }
- if (waitingOnHidden) {
- nextHiddenCheck = GetTickCount64() + nextHiddenCheckDelay;
- nextHiddenCheckDelay = std::min(nextHiddenCheckDelay * 2, (DWORD64) 2000);
- }
- else {
- nextHiddenCheck = GetTickCount64();
- nextHiddenCheckDelay = 200;
- }
- }
+ if (!phidden && pprefered)
+ return best_match;
}
- if (res == WAIT_OBJECT_0)
- log::debug("Waiting for process completion successfull");
- else if (uiunlocked)
- log::debug("Waiting for process completion aborted by UI");
- else
- log::debug("Waiting for process completion not successfull: {}", res);
-
- if (handle != INVALID_HANDLE_VALUE)
- ::CloseHandle(handle);
-
- return res == WAIT_OBJECT_0;
+ return best_match;
}
-HANDLE OrganizerCore::findAndOpenAUSVFSProcess(const std::vector& hiddenList, DWORD preferedParentPid) {
- // for practical reasons a querySize of 1 is probably enough, we use a larger query as a heuristics
- // to find a more "aesthetic injected processes (attempting to comply to hiddenList and preferedParentPid)
- constexpr size_t querySize = 100;
- DWORD pids[querySize];
- size_t found = querySize;
- if (!::GetVFSProcessList(&found, pids)) {
- log::warn("Failed seeking USVFS processes : GetVFSProcessList failed?!");
- return INVALID_HANDLE_VALUE;
- }
-
- HANDLE best_match = INVALID_HANDLE_VALUE;
- bool best_match_hidden = true;
- for (size_t i = 0; i < found; ++i) {
- if (pids[i] == GetCurrentProcessId())
- continue; // obviously don't wait for MO process
+bool OrganizerCore::waitForAllUSVFSProcesses(ILockedWaitingForProcess* uilock)
+{
+ // Certain process names we wish to "hide" for aesthetic reason:
+ std::vector hiddenList;
+ hiddenList.push_back(QFileInfo(QCoreApplication::applicationFilePath()).fileName());
- HANDLE handle = ::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE, FALSE, pids[i]);
- if (handle == INVALID_HANDLE_VALUE) {
- log::warn("Failed opening USVFS process {}: OpenProcess failed {}", pids[i], GetLastError());
- continue;
+ for (;;) {
+ const auto handles = getRunningUSVFSProcesses();
+ if (handles.empty()) {
+ break;
}
- QString pname = env::getProcessName(handle);
- bool phidden = false;
- for (auto hide : hiddenList)
- if (pname.contains(hide, Qt::CaseInsensitive))
- phidden = true;
+ const auto interesting = getInterestingProcess(
+ handles, hiddenList, GetCurrentProcessId());
- bool pprefered = preferedParentPid && env::getProcessParentID(pids[i]) == preferedParentPid;
+ if (uilock) {
+ const DWORD pid = ::GetProcessId(interesting);
+ const QString processName = QString("%1 (%2)")
+ .arg(env::getProcessName(interesting))
+ .arg(pid);
- if (best_match == INVALID_HANDLE_VALUE || best_match_hidden || (!phidden && pprefered)) {
- if (best_match != INVALID_HANDLE_VALUE)
- CloseHandle(best_match);
- best_match = handle;
- best_match_hidden = phidden;
+ uilock->setProcessName(processName);
}
- else
- CloseHandle(handle);
- if (!phidden && pprefered)
- return best_match;
+ const auto r = spawn::waitForProcess(interesting, nullptr, uilock);
+
+ switch (r)
+ {
+ case spawn::WaitResults::Completed:
+ // this process is completed, check for others
+ break;
+
+ case spawn::WaitResults::Unlocked:
+ // force unlocked
+ log::debug("waiting for process completion aborted by UI");
+ return true;
+
+ case spawn::WaitResults::Error: // fall-through
+ default:
+ log::debug("waiting for process completion not successful");
+ return false;
+ }
}
- return best_match;
+ log::debug("Waiting for process completion successful");
+ return true;
}
bool OrganizerCore::onAboutToRun(
diff --git a/src/spawn.cpp b/src/spawn.cpp
index f0b3b2c7..1003024f 100644
--- a/src/spawn.cpp
+++ b/src/spawn.cpp
@@ -1094,7 +1094,8 @@ FileExecutionContext getFileExecutionContext(
return {{}, {}, FileExecutionTypes::Other};
}
-WaitResults waitForProcess(HANDLE handle, DWORD* exitCode, ILockedWaitingForProcess* uilock)
+WaitResults waitForProcess(
+ HANDLE handle, DWORD* exitCode, ILockedWaitingForProcess* uilock)
{
if (handle == INVALID_HANDLE_VALUE) {
return WaitResults::Error;
@@ -1108,37 +1109,62 @@ WaitResults waitForProcess(HANDLE handle, DWORD* exitCode, ILockedWaitingForProc
if (uilock)
uilock->setProcessName(processName);
- constexpr DWORD INPUT_EVENT = WAIT_OBJECT_0 + 1;
- DWORD res = WAIT_TIMEOUT;
-
log::debug(
"waiting for process completion '{}' ({})",
processName, pid);
+ std::vector handles;
+ handles.push_back(handle);
+
+ std::vector exitCodes;
+
+ const auto r = waitForProcesses(handles, exitCodes, uilock);
+ if (exitCode && !exitCodes.empty()) {
+ *exitCode = exitCodes[0];
+ }
+
+ return r;
+}
+
+WaitResults waitForProcesses(
+ const std::vector& handles, std::vector& exitCodes,
+ ILockedWaitingForProcess* uilock)
+{
+ if (handles.empty()) {
+ return WaitResults::Completed;
+ }
+
+ const auto WAIT_OBJECT_N = static_cast(WAIT_OBJECT_0 + handles.size());
+
for (;;) {
// Wait for a an event on the handle, a key press, mouse click or timeout
const auto res = MsgWaitForMultipleObjects(
- 1, &handle, FALSE, 50, QS_KEY | QS_MOUSEBUTTON);
+ static_cast(handles.size()), &handles[0],
+ TRUE, 50, QS_KEY | QS_MOUSEBUTTON);
if (res == WAIT_FAILED) {
// error
const auto e = ::GetLastError();
log::error(
- "failed waiting for process completion '{}' ({}), {}",
- processName, pid, formatSystemMessage(e));
+ "failed waiting for process completion, {}", formatSystemMessage(e));
return WaitResults::Error;
- } else if (res == WAIT_OBJECT_0) {
+ } else if (res >= WAIT_OBJECT_0 && res < WAIT_OBJECT_N) {
// completed
- log::debug("process '{}' ({}) completed", processName, pid);
+ exitCodes.resize(handles.size());
+ std::fill(exitCodes.begin(), exitCodes.end(), 0);
+
+ for (std::size_t i=0; iunlockForced()) {
- log::debug("waiting for process '{}' ({}) aborted by UI", processName, pid);
return WaitResults::Unlocked;
}
}
diff --git a/src/spawn.h b/src/spawn.h
index 441cad2c..6b947f2f 100644
--- a/src/spawn.h
+++ b/src/spawn.h
@@ -136,6 +136,10 @@ enum class WaitResults
WaitResults waitForProcess(
HANDLE handle, DWORD* exitCode, ILockedWaitingForProcess* uilock);
+WaitResults waitForProcesses(
+ const std::vector& handles, std::vector& exitCodes,
+ ILockedWaitingForProcess* uilock);
+
} // namespace
diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp
index 311c6dd3..3dba3efc 100644
--- a/src/usvfsconnector.cpp
+++ b/src/usvfsconnector.cpp
@@ -20,6 +20,7 @@ along with Mod Organizer. If not, see .
#include "usvfsconnector.h"
#include "settings.h"
#include "organizercore.h"
+#include "envmodule.h"
#include "shared/util.h"
#include
#include
@@ -256,3 +257,49 @@ void UsvfsConnector::updateForcedLibraries(const QList getRunningUSVFSProcesses()
+{
+ std::vector pids;
+
+ {
+ size_t count = 0;
+ DWORD* buffer = nullptr;
+ if (!::GetVFSProcessList2(&count, &buffer)) {
+ log::error("failed to get usvfs process list");
+ return {};
+ }
+
+ if (buffer) {
+ pids.assign(buffer, buffer + count);
+ std::free(buffer);
+ }
+ }
+
+ const auto thisPid = GetCurrentProcessId();
+ std::vector v;
+
+ for (auto&& pid : pids) {
+ if (pid == thisPid) {
+ continue; // obviously don't wait for MO process
+ }
+
+ HANDLE handle = ::OpenProcess(
+ PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE, FALSE, pid);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ const auto e = GetLastError();
+
+ log::warn(
+ "failed to open usvfs process {}: {}",
+ pid, formatSystemMessage(e));
+
+ continue;
+ }
+
+ v.push_back(handle);
+ }
+
+ return v;
+}
diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h
index d0071678..5982778b 100644
--- a/src/usvfsconnector.h
+++ b/src/usvfsconnector.h
@@ -103,4 +103,6 @@ private:
CrashDumpsType crashDumpsType(int type);
+std::vector getRunningUSVFSProcesses();
+
#endif // USVFSCONNECTOR_H
--
cgit v1.3.1