summaryrefslogtreecommitdiff
path: root/src/moapplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/moapplication.cpp')
-rw-r--r--src/moapplication.cpp333
1 files changed, 171 insertions, 162 deletions
diff --git a/src/moapplication.cpp b/src/moapplication.cpp
index bb7b4922..885abc37 100644
--- a/src/moapplication.cpp
+++ b/src/moapplication.cpp
@@ -164,27 +164,36 @@ int MOApplication::run(SingleInstance& singleInstance)
// when switching instances or changing some settings
for (;;)
{
- // resets things when MO is "restarted"
- resetForRestart();
+ try
+ {
+ // resets things when MO is "restarted"
+ resetForRestart();
- const auto r = doOneRun(singleInstance);
- if (r == RestartExitCode) {
- continue;
- }
+ const auto r = doOneRun(singleInstance);
+ if (r == RestartExitCode) {
+ continue;
+ }
- return r;
+ return r;
+ }
+ catch (const std::exception &e)
+ {
+ reportError(e.what());
+ return 1;
+ }
}
}
int MOApplication::doOneRun(SingleInstance& singleInstance)
{
- TimeThis tt("doOneRun() to runApplication()");
-
+ // figuring out the current instance
auto currentInstance = getCurrentInstance();
if (!currentInstance) {
return 1;
}
+ // first time the data path is available, set the global property and log
+ // directory, then log a bunch of debug stuff
const QString dataPath = currentInstance->directory();
setProperty("dataPath", dataPath);
@@ -196,57 +205,20 @@ int MOApplication::doOneRun(SingleInstance& singleInstance)
log::debug("command line: '{}'", QString::fromWCharArray(GetCommandLineW()));
- tt.stop();
-
- return runApplication(singleInstance, dataPath, *currentInstance);
-}
-
-std::optional<Instance> MOApplication::getCurrentInstance()
-{
- auto& m = InstanceManager::singleton();
- auto currentInstance = m.currentInstance();
-
- if (!currentInstance)
- {
- currentInstance = selectInstance();
- }
- else
- {
- if (!QDir(currentInstance->directory()).exists()) {
- // the previously used instance doesn't exist anymore
-
- if (m.hasAnyInstances()) {
- MOShared::criticalOnTop(QObject::tr(
- "Instance at '%1' not found. Select another instance.")
- .arg(currentInstance->directory()));
- } else {
- MOShared::criticalOnTop(QObject::tr(
- "Instance at '%1' not found. You must create a new instance")
- .arg(currentInstance->directory()));
- }
-
- currentInstance = selectInstance();
- }
- }
-
- return currentInstance;
-}
-
-int MOApplication::runApplication(
- SingleInstance& singleInstance,
- const QString &dataPath, Instance& currentInstance)
-{
- TimeThis tt("runApplication() to exec()");
-
log::info(
"starting Mod Organizer version {} revision {} in {}, usvfs: {}",
createVersionInfo().displayString(3), GITID,
QCoreApplication::applicationDirPath(), MOShared::getUsvfsVersionString());
- log::info("data path: {}", dataPath);
+ if (singleInstance.secondary()) {
+ log::debug("another instance of MO is running but --multiple was given");
+ }
+ log::info("data path: {}", currentInstance->directory());
log::info("working directory: {}", QDir::currentPath());
+
+ // deleting old files, only for the main instance
if (!singleInstance.secondary()) {
purgeOldFiles();
}
@@ -254,155 +226,192 @@ int MOApplication::runApplication(
QWindowsWindowFunctions::setWindowActivationBehavior(
QWindowsWindowFunctions::AlwaysActivateWindow);
- try
- {
- Settings settings(
- dataPath + "/" + QString::fromStdWString(AppConfig::iniFileName()),
- true);
- log::getDefault().setLevel(settings.diagnostics().logLevel());
+ // loading settings
+ Settings settings(currentInstance->iniPath(), true);
+ log::getDefault().setLevel(settings.diagnostics().logLevel());
+ log::debug("using ini at '{}'", settings.filename());
- log::debug("using ini at '{}'", settings.filename());
+ OrganizerCore::setGlobalCoreDumpType(settings.diagnostics().coreDumpType());
- if (singleInstance.secondary()) {
- log::debug("another instance of MO is running but --multiple was given");
- }
- // global crashDumpType sits in OrganizerCore to make a bit less ugly to
- // update it when the settings are changed during runtime
- OrganizerCore::setGlobalCoreDumpType(settings.diagnostics().coreDumpType());
+ // logging and checking
+ env::Environment env;
+ env.dump(settings);
+ settings.dump();
+ sanity::checkEnvironment(env);
- env::Environment env;
- env.dump(settings);
- settings.dump();
- sanity::checkEnvironment(env);
+ const auto moduleNotification = env.onModuleLoaded(qApp, [](auto&& m) {
+ log::debug("loaded module {}", m.toString());
+ sanity::checkIncompatibleModule(m);
+ });
- const auto moduleNotification = env.onModuleLoaded(qApp, [](auto&& m) {
- log::debug("loaded module {}", m.toString());
- sanity::checkIncompatibleModule(m);
- });
- // this must outlive `organizer`
- std::unique_ptr<PluginContainer> pluginContainer;
+ // this must outlive `organizer`
+ std::unique_ptr<PluginContainer> pluginContainer;
- log::debug("initializing nexus interface");
- NexusInterface ni(&settings);
+ // nexus interface
+ log::debug("initializing nexus interface");
+ NexusInterface ni(&settings);
- log::debug("initializing core");
- OrganizerCore organizer(settings);
- if (!organizer.bootstrap()) {
- reportError("failed to set up data paths");
- InstanceManager::singleton().clearCurrentInstance();
- return 1;
- }
+ // organizer core
+ log::debug("initializing core");
+ OrganizerCore organizer(settings);
+ if (!organizer.bootstrap()) {
+ reportError("failed to set up data paths");
+ InstanceManager::singleton().clearCurrentInstance();
+ return 1;
+ }
- log::debug("initializing plugins");
- pluginContainer = std::make_unique<PluginContainer>(&organizer);
- pluginContainer->loadPlugins();
+ // plugins
+ log::debug("initializing plugins");
+ pluginContainer = std::make_unique<PluginContainer>(&organizer);
+ pluginContainer->loadPlugins();
- for (;;)
- {
- const auto setupResult = setupInstance(currentInstance, *pluginContainer);
+ // instance
+ if (auto r=setupInstanceLoop(*currentInstance, *pluginContainer)) {
+ return *r;
+ }
- if (setupResult == SetupInstanceResults::Okay) {
- break;
- } else if (setupResult == SetupInstanceResults::TryAgain) {
- continue;
- } else if (setupResult == SetupInstanceResults::SelectAnother) {
- InstanceManager::singleton().clearCurrentInstance();
- return RestartExitCode;
- } else {
- return 1;
- }
- }
+ if (currentInstance->isPortable()) {
+ log::debug("this is a portable instance");
+ }
- if (currentInstance.isPortable()) {
- log::debug("this is a portable instance");
- }
+ sanity::checkPaths(*currentInstance->gamePlugin(), settings);
- sanity::checkPaths(*currentInstance.gamePlugin(), settings);
+ // setting up organizer core
+ organizer.setManagedGame(currentInstance->gamePlugin());
+ organizer.createDefaultProfile();
- organizer.setManagedGame(currentInstance.gamePlugin());
- organizer.createDefaultProfile();
+ log::info(
+ "using game plugin '{}' ('{}', variant {}, steam id '{}') at {}",
+ currentInstance->gamePlugin()->gameName(),
+ currentInstance->gamePlugin()->gameShortName(),
+ (settings.game().edition().value_or("").isEmpty() ?
+ "(none)" : *settings.game().edition()),
+ currentInstance->gamePlugin()->steamAPPId(),
+ currentInstance->gamePlugin()->gameDirectory().absolutePath());
- log::info(
- "using game plugin '{}' ('{}', variant {}, steam id '{}') at {}",
- currentInstance.gamePlugin()->gameName(),
- currentInstance.gamePlugin()->gameShortName(),
- (settings.game().edition().value_or("").isEmpty() ?
- "(none)" : *settings.game().edition()),
- currentInstance.gamePlugin()->steamAPPId(),
- currentInstance.gamePlugin()->gameDirectory().absolutePath());
+ CategoryFactory::instance().loadCategories();
+ organizer.updateExecutablesList();
+ organizer.updateModInfoFromDisc();
+ organizer.setCurrentProfile(currentInstance->profileName());
+ // checking command line
+ if (auto r=m_cl.setupCore(organizer)) {
+ return *r;
+ }
- CategoryFactory::instance().loadCategories();
- organizer.updateExecutablesList();
- organizer.updateModInfoFromDisc();
+ // show splash
+ MOSplash splash(
+ settings, currentInstance->directory(), currentInstance->gamePlugin());
- organizer.setCurrentProfile(currentInstance.profileName());
+ // start an api check
+ QString apiKey;
+ if (GlobalSettings::nexusApiKey(apiKey)) {
+ ni.getAccessManager()->apiCheck(apiKey);
+ }
- if (auto r=m_cl.setupCore(organizer)) {
- return *r;
- }
+ // tutorials
+ log::debug("initializing tutorials");
+ TutorialManager::init(
+ qApp->applicationDirPath() + "/"
+ + QString::fromStdWString(AppConfig::tutorialsPath()) + "/",
+ &organizer);
- MOSplash splash(settings, dataPath, currentInstance.gamePlugin());
+ // styling
+ if (!setStyleFile(settings.interface().styleName().value_or(""))) {
+ // disable invalid stylesheet
+ settings.interface().setStyleName("");
+ }
- QString apiKey;
- if (GlobalSettings::nexusApiKey(apiKey)) {
- ni.getAccessManager()->apiCheck(apiKey);
- }
- log::debug("initializing tutorials");
- TutorialManager::init(
- qApp->applicationDirPath() + "/"
- + QString::fromStdWString(AppConfig::tutorialsPath()) + "/",
- &organizer);
+ int res = 1;
- if (!setStyleFile(settings.interface().styleName().value_or(""))) {
- // disable invalid stylesheet
- settings.interface().setStyleName("");
- }
+ {
+ MainWindow mainWindow(settings, organizer, *pluginContainer);
- int res = 1;
+ // qt resets the thread name somewhere when creating the main window
+ MOShared::SetThisThreadName("main");
- {
- // scope to control lifetime of mainwindow
- // set up main window and its data structures
- MainWindow mainWindow(settings, organizer, *pluginContainer);
+ // the nexus interface can show dialogs, make sure they're parented to the
+ // main window
+ ni.getAccessManager()->setTopLevelWidget(&mainWindow);
- // qt resets the thread name somewhere when creating the main window
- MOShared::SetThisThreadName("main");
+ QObject::connect(&mainWindow, SIGNAL(styleChanged(QString)), this,
+ SLOT(setStyleFile(QString)));
- ni.getAccessManager()->setTopLevelWidget(&mainWindow);
+ QObject::connect(&singleInstance, SIGNAL(messageSent(QString)), &organizer,
+ SLOT(externalMessage(QString)));
- QObject::connect(&mainWindow, SIGNAL(styleChanged(QString)), this,
- SLOT(setStyleFile(QString)));
- QObject::connect(&singleInstance, SIGNAL(messageSent(QString)), &organizer,
- SLOT(externalMessage(QString)));
- log::debug("displaying main window");
- mainWindow.show();
- mainWindow.activateWindow();
+ log::debug("displaying main window");
+ mainWindow.show();
+ mainWindow.activateWindow();
+ splash.close();
- splash.close();
+ res = exec();
+ mainWindow.close();
- tt.stop();
+ // main window is about to be destroyed
+ ni.getAccessManager()->setTopLevelWidget(nullptr);
+ }
- res = exec();
- mainWindow.close();
+ // reset geometry if the flag was set from the settings dialog
+ settings.geometry().resetIfNeeded();
- ni.getAccessManager()->setTopLevelWidget(nullptr);
- }
+ return res;
+}
+
+std::optional<Instance> MOApplication::getCurrentInstance()
+{
+ auto& m = InstanceManager::singleton();
+ auto currentInstance = m.currentInstance();
- settings.geometry().resetIfNeeded();
- return res;
+ if (!currentInstance)
+ {
+ currentInstance = selectInstance();
}
- catch (const std::exception &e)
+ else
{
- reportError(e.what());
+ if (!QDir(currentInstance->directory()).exists()) {
+ // the previously used instance doesn't exist anymore
+
+ if (m.hasAnyInstances()) {
+ MOShared::criticalOnTop(QObject::tr(
+ "Instance at '%1' not found. Select another instance.")
+ .arg(currentInstance->directory()));
+ } else {
+ MOShared::criticalOnTop(QObject::tr(
+ "Instance at '%1' not found. You must create a new instance")
+ .arg(currentInstance->directory()));
+ }
+
+ currentInstance = selectInstance();
+ }
}
- return 1;
+ return currentInstance;
+}
+
+std::optional<int> MOApplication::setupInstanceLoop(
+ Instance& currentInstance, PluginContainer& pc)
+{
+ for (;;)
+ {
+ const auto setupResult = setupInstance(currentInstance, pc);
+
+ if (setupResult == SetupInstanceResults::Okay) {
+ return {};
+ } else if (setupResult == SetupInstanceResults::TryAgain) {
+ continue;
+ } else if (setupResult == SetupInstanceResults::SelectAnother) {
+ InstanceManager::singleton().clearCurrentInstance();
+ return RestartExitCode;
+ } else {
+ return 1;
+ }
+ }
}
void MOApplication::purgeOldFiles()