From 77e9f2d1501fe7a17a406006bb3fa91677be0c5e Mon Sep 17 00:00:00 2001 From: Aloshi Date: Tue, 9 Jul 2013 05:37:37 -0500 Subject: [PATCH] Refactor some of the startup code. --- src/SystemData.cpp | 25 +++++--- src/SystemData.h | 4 +- src/Window.cpp | 36 +++++++----- src/Window.h | 2 +- src/components/GuiMenu.cpp | 2 +- src/main.cpp | 116 +++++++++++++++++++++---------------- 6 files changed, 110 insertions(+), 75 deletions(-) diff --git a/src/SystemData.cpp b/src/SystemData.cpp index 899cfe5e9..e856112f5 100644 --- a/src/SystemData.cpp +++ b/src/SystemData.cpp @@ -182,14 +182,21 @@ std::string SystemData::getDescName() } //creates systems from information located in a config file -void SystemData::loadConfig() +bool SystemData::loadConfig(const std::string& path, bool writeExample) { deleteSystems(); - std::string path = getConfigPath(); - LOG(LogInfo) << "Loading system config file..."; + if(!fs::exists(path)) + { + LOG(LogInfo) << "System config file \"" << path << "\" doesn't exist!"; + if(writeExample) + writeExampleConfig(path); + + return false; + } + std::ifstream file(path.c_str()); if(file.is_open()) { @@ -262,21 +269,21 @@ void SystemData::loadConfig() } }else{ LOG(LogError) << "Error reading config file \"" << path << "\" - no equals sign found on line " << lineNr << ": \"" << line << "\"!"; - return; + return false; } } }else{ LOG(LogError) << "Error - could not load config file \"" << path << "\"!"; - return; + return false; } LOG(LogInfo) << "Finished loading config file - created " << sSystemVector.size() << " systems."; - return; + return true; } -void SystemData::writeExampleConfig() +void SystemData::writeExampleConfig(const std::string& path) { - std::string path = getConfigPath(); + std::cerr << "Writing example config to \"" << path << "\"..."; std::ofstream file(path.c_str()); @@ -303,6 +310,8 @@ void SystemData::writeExampleConfig() file << "COMMAND=" << std::endl; file.close(); + + std::cerr << "done. Go read it!\n"; } void SystemData::deleteSystems() diff --git a/src/SystemData.h b/src/SystemData.h index e3c6755d2..eaa31e4d0 100644 --- a/src/SystemData.h +++ b/src/SystemData.h @@ -25,8 +25,8 @@ public: void launchGame(Window* window, GameData* game); static void deleteSystems(); - static void loadConfig(); - static void writeExampleConfig(); + static bool loadConfig(const std::string& path, bool writeExampleIfNonexistant = true); //Load the system config file at getConfigPath(). Returns true if no errors were encountered. An example can be written if the file doesn't exist. + static void writeExampleConfig(const std::string& path); static std::string getConfigPath(); static std::vector sSystemVector; diff --git a/src/Window.cpp b/src/Window.cpp index d1a789939..e1b69444b 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -3,18 +3,20 @@ #include "Renderer.h" #include "AudioManager.h" #include "VolumeControl.h" +#include "Log.h" +#include "Settings.h" Window::Window() { mInputManager = new InputManager(this); - - mDefaultFonts.push_back(Font::get(mResourceManager, Font::getDefaultPath(), FONT_SIZE_SMALL)); - mDefaultFonts.push_back(Font::get(mResourceManager, Font::getDefaultPath(), FONT_SIZE_MEDIUM)); - mDefaultFonts.push_back(Font::get(mResourceManager, Font::getDefaultPath(), FONT_SIZE_LARGE)); } Window::~Window() { + //delete all our GUIs + while(peekGui()) + delete peekGui(); + delete mInputManager; } @@ -55,25 +57,31 @@ void Window::render() } } -void Window::init() +bool Window::init(unsigned int width, unsigned int height) { - mInputManager->init(); //shouldn't this go AFTER renderer initialization? - Renderer::init(0, 0); + if(!Renderer::init(width, height)) + { + LOG(LogError) << "Renderer failed to initialize!"; + return false; + } + + mInputManager->init(); + mResourceManager.reloadAll(); - for(unsigned int i = 0; i < mGuiStack.size(); i++) + //keep a reference to the default fonts, so they don't keep getting destroyed/recreated + if(mDefaultFonts.empty()) { - mGuiStack.at(i)->init(); + mDefaultFonts.push_back(Font::get(mResourceManager, Font::getDefaultPath(), FONT_SIZE_SMALL)); + mDefaultFonts.push_back(Font::get(mResourceManager, Font::getDefaultPath(), FONT_SIZE_MEDIUM)); + mDefaultFonts.push_back(Font::get(mResourceManager, Font::getDefaultPath(), FONT_SIZE_LARGE)); } + + return true; } void Window::deinit() { - for(unsigned int i = 0; i < mGuiStack.size(); i++) - { - mGuiStack.at(i)->deinit(); - } - mInputManager->deinit(); mResourceManager.unloadAll(); Renderer::deinit(); diff --git a/src/Window.h b/src/Window.h index 400f868ae..52cefcb21 100644 --- a/src/Window.h +++ b/src/Window.h @@ -21,7 +21,7 @@ public: void update(int deltaTime); void render(); - void init(); + bool init(unsigned int width = 0, unsigned int height = 0); void deinit(); InputManager* getInputManager(); diff --git a/src/components/GuiMenu.cpp b/src/components/GuiMenu.cpp index ad02bdd01..0dd21ab39 100644 --- a/src/components/GuiMenu.cpp +++ b/src/components/GuiMenu.cpp @@ -52,7 +52,7 @@ void GuiMenu::executeCommand(std::string command) }else if(command == "es_reload") { //reload the game list - SystemData::loadConfig(); + SystemData::loadConfig(SystemData::getConfigPath(), false); mParent->setSystemId(0); }else if(command == "es_settings") { diff --git a/src/main.cpp b/src/main.cpp index d4ff84d7d..94e01608f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,26 +20,23 @@ #include #endif - #include namespace fs = boost::filesystem; -int main(int argc, char* argv[]) +bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height) { - unsigned int width = 0; - unsigned int height = 0; if(argc > 1) { for(int i = 1; i < argc; i++) { if(strcmp(argv[i], "-w") == 0) { - width = atoi(argv[i + 1]); + *width = atoi(argv[i + 1]); i++; //skip the argument value }else if(strcmp(argv[i], "-h") == 0) { - height = atoi(argv[i + 1]); + *height = atoi(argv[i + 1]); i++; //skip the argument value }else if(strcmp(argv[i], "--gamelist-only") == 0) { @@ -83,17 +80,16 @@ int main(int argc, char* argv[]) std::cout << "--help summon a sentient, angry tuba\n\n"; std::cout << "More information available in README.md.\n"; - return 0; + return false; //exit after printing help } } } - #ifdef _RPI_ - bcm_host_init(); - #endif - - bool running = true; + return true; +} +bool verifyHomeFolderExists() +{ //make sure the config directory exists std::string home = getHomePath(); std::string configDir = home + "/.emulationstation"; @@ -101,55 +97,83 @@ int main(int argc, char* argv[]) { std::cout << "Creating config directory \"" << configDir << "\"\n"; fs::create_directory(configDir); + if(!fs::exists(configDir)) + { + std::cerr << "Config directory could not be created!\n"; + return false; + } } + return true; +} + +//called on exit, assuming we get far enough to have the log initialized +void onExit() +{ + Log::close(); + + #ifdef _RPI_ + bcm_host_deinit(); + #endif +} + +int main(int argc, char* argv[]) +{ + unsigned int width = 0; + unsigned int height = 0; + + if(!parseArgs(argc, argv, &width, &height)) + return 0; + + //if ~/.emulationstation doesn't exist and cannot be created, bail + if(!verifyHomeFolderExists()) + return 1; + + #ifdef _RPI_ + bcm_host_init(); + #endif + //start the logger Log::open(); LOG(LogInfo) << "EmulationStation - " << PROGRAM_VERSION_STRING; - //the renderer also takes care of setting up SDL for input and sound - bool renderInit = Renderer::init(width, height); - if(!renderInit) + //always close the log and deinit the BCM library on exit + atexit(&onExit); + + Window window; + if(!window.init(width, height)) { - std::cerr << "Error initializing renderer!\n"; - Log::close(); + LOG(LogError) << "Window failed to initialize!"; return 1; } - Window window; //don't call Window.init() because we manually pass the resolution to Renderer::init - window.getInputManager()->init(); - //try loading the system config file - if(!fs::exists(SystemData::getConfigPath())) //if it doesn't exist, create the example and quit + if(!SystemData::loadConfig(SystemData::getConfigPath(), true)) { - std::cerr << "A system config file in " << SystemData::getConfigPath() << " was not found. An example will be created.\n"; - SystemData::writeExampleConfig(); - std::cerr << "Set it up, then re-run EmulationStation.\n"; - running = false; - }else{ - SystemData::loadConfig(); + LOG(LogError) << "Error parsing system config file!"; + return 1; + } - if(SystemData::sSystemVector.size() == 0) //if it exists but was empty, notify the user and quit - { - std::cerr << "A system config file in " << SystemData::getConfigPath() << " was found, but contained no systems.\n"; - std::cerr << "Does at least one system have a game present?\n"; - running = false; - }else{ - //choose which GUI to open depending on Input configuration - if(fs::exists(InputManager::getConfigPath())) - { - //an input config already exists - we have input, proceed to the gamelist as usual. - GuiGameList::create(&window); - }else{ - window.pushGui(new GuiDetectDevice(&window)); - } - } + //make sure it wasn't empty + if(SystemData::sSystemVector.size() == 0) + { + LOG(LogError) << "No systems found! Does at least one system have a game present? (check that extensions match!)"; + return 1; + } + + //choose which GUI to open depending on if an input configuration already exists + if(fs::exists(InputManager::getConfigPath())) + { + GuiGameList::create(&window); + }else{ + window.pushGui(new GuiDetectDevice(&window)); } bool sleeping = false; unsigned int timeSinceLastEvent = 0; - int lastTime = 0; + bool running = true; + while(running) { SDL_Event event; @@ -234,11 +258,5 @@ int main(int argc, char* argv[]) std::cout << "EmulationStation cleanly shutting down...\n"; - Log::close(); - - #ifdef _RPI_ - bcm_host_deinit(); - #endif - return 0; }