diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 49f58e1c8f..beee702d1d 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -10,7 +10,9 @@ #include "Settings.h" #include "ThemeData.h" #include "views/UIModeController.h" +#include #include +#include #include #include "utils/StringUtil.h" #include "utils/ThreadPool.h" @@ -321,16 +323,31 @@ bool SystemData::loadConfig(Window* window) pThreadPool->queueWorkItem([] { CollectionSystemManager::get()->loadCollectionSystems(true); }); } - int processedSystem = 0; + std::atomic processedSystem(0); + std::vector activeSystems; + std::mutex activeSystemsMutex; + if (pThreadPool != NULL) + activeSystems.assign(systemCount, false); for (pugi::xml_node system = systemList.child("system"); system; system = system.next_sibling("system")) { if (pThreadPool != NULL) { - pThreadPool->queueWorkItem([system, currentSystem, systems, &processedSystem] + pThreadPool->queueWorkItem([system, currentSystem, systems, &processedSystem, &activeSystems, &activeSystemsMutex] { + { + std::lock_guard lock(activeSystemsMutex); + activeSystems[currentSystem] = true; + } + systems[currentSystem] = loadSystem(system); - processedSystem++; + + { + std::lock_guard lock(activeSystemsMutex); + activeSystems[currentSystem] = false; + } + + processedSystem.fetch_add(1); }); } else @@ -354,11 +371,27 @@ bool SystemData::loadConfig(Window* window) { if (window != NULL) { - pThreadPool->wait([window, &processedSystem, systemCount, &systemsNames] + pThreadPool->wait([window, &processedSystem, systemCount, &systemsNames, &activeSystems, &activeSystemsMutex] { - int px = processedSystem - 1; - if (px >= 0 && px < systemsNames.size()) - window->renderLoadingScreen(systemsNames.at(px), (float)px / (float)(systemCount + 1)); + std::string activeText; + { + std::lock_guard lock(activeSystemsMutex); + for (size_t i = 0; i < activeSystems.size(); i++) + { + if (!activeSystems[i]) + continue; + + if (!activeText.empty()) + activeText += ", "; + activeText += systemsNames.at(i); + } + } + + if (activeText.empty()) + activeText = "Loading systems..."; + + const int completed = processedSystem.load(); + window->renderLoadingScreen(activeText, systemCount == 0 ? 0 : (float)completed / (float)systemCount); }, 10); } else @@ -375,14 +408,14 @@ bool SystemData::loadConfig(Window* window) delete pThreadPool; if (window != NULL) - window->renderLoadingScreen("Favorites", systemCount == 0 ? 0 : currentSystem / systemCount); + window->renderLoadingScreen("Favorites", 1.0f); CollectionSystemManager::get()->updateSystemsList(); } else { if (window != NULL) - window->renderLoadingScreen("Favorites", systemCount == 0 ? 0 : currentSystem / systemCount); + window->renderLoadingScreen("Favorites", 1.0f); CollectionSystemManager::get()->loadCollectionSystems(); } diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index b3150db4a5..71eb6b38db 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -451,6 +451,11 @@ void GuiMenu::openOtherSettings() s->addWithLabel("PARSE GAMESLISTS ONLY", parse_gamelists); s->addSaveFunc([parse_gamelists] { Settings::getInstance()->setBool("ParseGamelistOnly", parse_gamelists->getState()); }); + auto threaded_loading = std::make_shared(mWindow); + threaded_loading->setState(Settings::getInstance()->getBool("ThreadedLoading")); + s->addWithLabel("GAMESLISTS THREADED LOADING", threaded_loading); + s->addSaveFunc([threaded_loading] { Settings::getInstance()->setBool("ThreadedLoading", threaded_loading->getState()); }); + auto local_art = std::make_shared(mWindow); local_art->setState(Settings::getInstance()->getBool("LocalArt")); s->addWithLabel("SEARCH FOR LOCAL ART", local_art); diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 42c9bfa746..5717deb046 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -8,6 +8,8 @@ #include "Scripting.h" #include #include +#include +#include #ifdef WIN32 #include @@ -297,15 +299,91 @@ void Window::renderLoadingScreen(std::string text, float percent, unsigned char splash.setPosition((Renderer::getScreenWidth() - splash.getSize().x()) / 2, (Renderer::getScreenHeight() - splash.getSize().y()) / 2 * 0.6f); splash.render(trans); - auto& font = mDefaultFonts.at(1); - TextCache* cache = font->buildTextCache(text, 0, 0, 0x656565FF); + std::vector lines; + if(text.find('\n') != std::string::npos) + { + std::stringstream ss(text); + std::string line; + while(std::getline(ss, line, '\n')) + { + if(!line.empty()) + lines.push_back(line); + } + } + else if(text.find(", ") != std::string::npos) + { + size_t start = 0; + while(start < text.size()) + { + size_t end = text.find(", ", start); + if(end == std::string::npos) + end = text.size(); - float x = Math::round((Renderer::getScreenWidth() - cache->metrics.size.x()) / 2.0f); - float y = Math::round(Renderer::getScreenHeight() * 0.78f); - trans = trans.translate(Vector3f(x, y, 0.0f)); - Renderer::setMatrix(trans); - font->renderTextCache(cache); - delete cache; + std::string line = text.substr(start, end - start); + if(!line.empty()) + lines.push_back(line); + + if(end == text.size()) + break; + start = end + 2; + } + } + else + { + lines.push_back(text); + } + + if(lines.empty()) + lines.push_back("Loading..."); + + auto font = mDefaultFonts.at(1); + if(lines.size() > 4) + font = mDefaultFonts.at(0); + + float maxTextWidth = 0.0f; + for(const auto& line : lines) + { + TextCache* cache = font->buildTextCache(line, 0, 0, 0x656565FF); + maxTextWidth = std::max(maxTextWidth, cache->metrics.size.x()); + delete cache; + } + + if(maxTextWidth > Renderer::getScreenWidth() * 0.9f) + font = mDefaultFonts.at(0); + + const float barTop = Renderer::getScreenHeight() - (Renderer::getScreenHeight() * 3 * 0.04f); + const float textTopLimit = Renderer::getScreenHeight() * 0.58f; + const float textBottomLimit = barTop - 8.0f; + const float lineHeight = font->getHeight() * 1.15f; + const float availableHeight = std::max(0.0f, textBottomLimit - textTopLimit); + + int maxLines = lineHeight <= 0.0f ? 1 : (int)(availableHeight / lineHeight); + if(maxLines < 1) + maxLines = 1; + + if((int)lines.size() > maxLines) + { + const int hidden = (int)lines.size() - maxLines + 1; + lines.resize(maxLines); + lines[maxLines - 1] = "+" + std::to_string(hidden) + " more"; + } + + const float totalHeight = lineHeight * (float)lines.size(); + float startY = textBottomLimit - totalHeight; + if(startY < textTopLimit) + startY = textTopLimit; + + for(size_t i = 0; i < lines.size(); i++) + { + TextCache* cache = font->buildTextCache(lines[i], 0, 0, 0x656565FF); + float x = Math::round((Renderer::getScreenWidth() - cache->metrics.size.x()) / 2.0f); + float y = Math::round(startY + (lineHeight * (float)i)); + Transform4x4f lineTrans = Transform4x4f::Identity(); + lineTrans.translate(Vector3f(x, y, 0.0f)); + Renderer::setMatrix(lineTrans); + font->renderTextCache(cache); + delete cache; + } Renderer::swapBuffers();