The application startup can now be aborted via an OS signal or using the configured keyboard quit shortcut.

This commit is contained in:
Leon Styhre 2023-02-07 18:14:16 +01:00
parent 1e31423f3f
commit cf8ce151dd
4 changed files with 75 additions and 56 deletions

View file

@ -15,6 +15,7 @@
#include "FileFilterIndex.h" #include "FileFilterIndex.h"
#include "FileSorts.h" #include "FileSorts.h"
#include "GamelistFileParser.h" #include "GamelistFileParser.h"
#include "InputManager.h"
#include "Log.h" #include "Log.h"
#include "Settings.h" #include "Settings.h"
#include "ThemeData.h" #include "ThemeData.h"
@ -32,9 +33,6 @@
#include <pugixml.hpp> #include <pugixml.hpp>
#include <random> #include <random>
std::vector<SystemData*> SystemData::sSystemVector;
std::unique_ptr<FindRules> SystemData::sFindRules;
FindRules::FindRules() FindRules::FindRules()
{ {
LOG(LogInfo) << "Loading emulator find rules..."; LOG(LogInfo) << "Loading emulator find rules...";
@ -544,7 +542,13 @@ bool SystemData::loadConfig()
system = system.next_sibling("system")) { system = system.next_sibling("system")) {
// Poll events so that the OS doesn't think the application is hanging on startup, // Poll events so that the OS doesn't think the application is hanging on startup,
// this is required as the main application loop hasn't started yet. // this is required as the main application loop hasn't started yet.
while (SDL_PollEvent(&event)) {}; while (SDL_PollEvent(&event)) {
InputManager::getInstance().parseEvent(event);
if (event.type == SDL_QUIT) {
sStartupExitSignal = true;
return true;
}
};
std::string name; std::string name;
std::string fullname; std::string fullname;

View file

@ -114,8 +114,9 @@ public:
// Generates the game system directories and information files based on es_systems.xml. // Generates the game system directories and information files based on es_systems.xml.
static bool createSystemDirectories(); static bool createSystemDirectories();
static std::vector<SystemData*> sSystemVector; static inline std::vector<SystemData*> sSystemVector;
static std::unique_ptr<FindRules> sFindRules; static inline std::unique_ptr<FindRules> sFindRules;
static inline bool sStartupExitSignal {false};
const bool isCollection() const { return mIsCollectionSystem; } const bool isCollection() const { return mIsCollectionSystem; }
const bool isCustomCollection() const { return mIsCustomCollectionSystem; } const bool isCustomCollection() const { return mIsCustomCollectionSystem; }

View file

@ -704,70 +704,78 @@ int main(int argc, char* argv[])
ThemeData::populateThemeSets(); ThemeData::populateThemeSets();
loadSystemsReturnCode loadSystemsStatus {loadSystemConfigFile()}; loadSystemsReturnCode loadSystemsStatus {loadSystemConfigFile()};
if (loadSystemsStatus) { if (!SystemData::sStartupExitSignal) {
// If there was an issue parsing the es_systems.xml file, display an error message. if (loadSystemsStatus) {
// If there were no game files found, give the option to the user to quit or to // If there was an issue parsing the es_systems.xml file, display an error message.
// configure a different ROM directory as well as to generate the game systems // If there were no game files found, give the option to the user to quit or to
// directory structure. // configure a different ROM directory as well as to generate the game systems
if (loadSystemsStatus == INVALID_FILE) { // directory structure.
ViewController::getInstance()->invalidSystemsFileDialog(); if (loadSystemsStatus == INVALID_FILE) {
ViewController::getInstance()->invalidSystemsFileDialog();
}
else if (loadSystemsStatus == NO_ROMS) {
ViewController::getInstance()->noGamesDialog();
}
} }
else if (loadSystemsStatus == NO_ROMS) {
ViewController::getInstance()->noGamesDialog(); // Check if any of the enabled systems have an invalid alternative emulator entry,
// which means that a label is present in the gamelist.xml file which is not matching
// any command tag in es_systems.xml.
for (auto system : SystemData::sSystemVector) {
if (system->getAlternativeEmulator().substr(0, 9) == "<INVALID>") {
ViewController::getInstance()->invalidAlternativeEmulatorDialog();
break;
}
} }
// Don't generate controller events while we're loading.
SDL_GameControllerEventState(SDL_DISABLE);
// Preload system view and all gamelist views.
ViewController::getInstance()->preload();
} }
// Check if any of the enabled systems has an invalid alternative emulator entry, if (!SystemData::sStartupExitSignal) {
// which means that a label is present in the gamelist.xml file which is not matching if (loadSystemsStatus == loadSystemsReturnCode::LOADING_OK) {
// any command tag in es_systems.xml. LOG(LogInfo) << "Finished loading theme set \"" << ThemeData::getCurrentThemeSetName()
for (auto system : SystemData::sSystemVector) { << "\"";
if (system->getAlternativeEmulator().substr(0, 9) == "<INVALID>") {
ViewController::getInstance()->invalidAlternativeEmulatorDialog();
break;
} }
}
// Don't generate controller events while we're loading. // Open the input configuration GUI if the force flag was passed from the command line.
SDL_GameControllerEventState(SDL_DISABLE); if (!loadSystemsStatus) {
if (forceInputConfig) {
// Preload what we can right away instead of waiting for the user to select it. window->pushGui(new GuiDetectDevice(
// This makes for no delays when accessing content, but a longer startup time. false, true, [] { ViewController::getInstance()->goToStart(true); }));
ViewController::getInstance()->preload(); }
else {
if (loadSystemsStatus == loadSystemsReturnCode::LOADING_OK) { ViewController::getInstance()->goToStart(true);
LOG(LogInfo) << "Finished loading theme set \"" << ThemeData::getCurrentThemeSetName() }
<< "\"";
}
// Open the input configuration GUI if the flag to force this was passed from the command line.
if (!loadSystemsStatus) {
if (forceInputConfig) {
window->pushGui(new GuiDetectDevice(
false, true, [] { ViewController::getInstance()->goToStart(true); }));
} }
else {
ViewController::getInstance()->goToStart(true);
}
}
// Generate controller events since we're done loading. // Generate controller events since we're done loading.
SDL_GameControllerEventState(SDL_ENABLE); SDL_GameControllerEventState(SDL_ENABLE);
lastTime = SDL_GetTicks(); lastTime = SDL_GetTicks();
LOG(LogInfo) << "Application startup time: " LOG(LogInfo) << "Application startup time: "
<< std::chrono::duration_cast<std::chrono::milliseconds>( << std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now() - applicationStartTime) std::chrono::system_clock::now() - applicationStartTime)
.count() .count()
<< " ms"; << " ms";
// Main application loop. // Main application loop.
if (!SystemData::sStartupExitSignal) {
#if defined(__EMSCRIPTEN__) #if defined(__EMSCRIPTEN__)
emscripten_set_main_loop(&applicationLoop, 0, 1); emscripten_set_main_loop(&applicationLoop, 0, 1);
#else #else
applicationLoop(); applicationLoop();
#endif #endif
}
}
else {
LOG(LogInfo) << "Exit signal received, aborting application startup";
}
while (window->peekGui() != ViewController::getInstance()) while (window->peekGui() != ViewController::getInstance())
delete window->peekGui(); delete window->peekGui();

View file

@ -1101,7 +1101,13 @@ void ViewController::preload()
it != SystemData::sSystemVector.cend(); ++it) { it != SystemData::sSystemVector.cend(); ++it) {
// Poll events so that the OS doesn't think the application is hanging on startup, // Poll events so that the OS doesn't think the application is hanging on startup,
// this is required as the main application loop hasn't started yet. // this is required as the main application loop hasn't started yet.
while (SDL_PollEvent(&event)) {}; while (SDL_PollEvent(&event)) {
InputManager::getInstance().parseEvent(event);
if (event.type == SDL_QUIT) {
SystemData::sStartupExitSignal = true;
return;
}
};
const std::string entryType {(*it)->isCustomCollection() ? "custom collection" : "system"}; const std::string entryType {(*it)->isCustomCollection() ? "custom collection" : "system"};
LOG(LogDebug) << "ViewController::preload(): Populating gamelist for " << entryType << " \"" LOG(LogDebug) << "ViewController::preload(): Populating gamelist for " << entryType << " \""