From a296ef7a14c7f997ef961c168c23b8318cf520fb Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Fri, 15 Aug 2014 18:51:03 +0100 Subject: [PATCH] Finished implementing plugin sorting. --- src/backend/game.h | 3 +- src/backend/sort.cpp | 93 ++------------------------------------------ src/gui/handler.cpp | 20 +++++++++- 3 files changed, 23 insertions(+), 93 deletions(-) diff --git a/src/backend/game.h b/src/backend/game.h index 8ea1bc37..5a69c713 100644 --- a/src/backend/game.h +++ b/src/backend/game.h @@ -124,8 +124,7 @@ namespace loot { void RedatePlugins(); //Change timestamps to match load order (Skyrim only). void LoadPlugins(bool headersOnly); //Loads all installed plugins. - void SortPrep(const unsigned int language, std::list& messages, std::function progressCallback); - std::list Sort(const unsigned int language, std::list& messages, std::function progressCallback); + std::list Sort(const unsigned int language, std::function progressCallback); //Caches for condition results, active plugins and CRCs. std::unordered_map conditionCache; //Holds lowercased strings. diff --git a/src/backend/sort.cpp b/src/backend/sort.cpp index 178528e7..168db6e1 100644 --- a/src/backend/sort.cpp +++ b/src/backend/sort.cpp @@ -40,96 +40,7 @@ namespace fs = boost::filesystem; namespace loot { - void Game::SortPrep(const unsigned int language, std::list& messages, std::function progressCallback) { - boost::thread_group group; - - BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name(); - - /////////////////////////////////////////////////////// - // Load Plugins & Lists - /////////////////////////////////////////////////////// - - progressCallback("Reading installed plugins..."); - - group.create_thread([this, language, &messages]() { - try { - this->masterlist.Load(*this, language); - } - catch (exception &e) { - messages.push_back(loot::Message(loot::Message::error, (format(loc::translate("Masterlist parsing failed. Details: %1%")) % e.what()).str())); - } - }); - group.create_thread([this]() { - this->LoadPlugins(false); - }); - group.join_all(); - - //Now load userlist. - if (fs::exists(this->UserlistPath())) { - BOOST_LOG_TRIVIAL(debug) << "Parsing userlist at: " << this->UserlistPath(); - - try { - this->userlist.Load(this->UserlistPath()); - } - catch (exception& e) { - BOOST_LOG_TRIVIAL(error) << "Userlist parsing failed. Details: " << e.what(); - messages.push_back(loot::Message(loot::Message::error, (format(loc::translate("Userlist parsing failed. Details: %1%")) % e.what()).str())); - } - } - - /////////////////////////////////////////////////////// - // Evaluate Global Messages - /////////////////////////////////////////////////////// - - progressCallback("Evaluating global messages..."); - - //Merge all global message lists. - BOOST_LOG_TRIVIAL(debug) << "Merging all global message lists."; - if (!this->masterlist.messages.empty()) - messages.insert(messages.end(), this->masterlist.messages.begin(), this->masterlist.messages.end()); - if (!this->userlist.messages.empty()) - messages.insert(messages.end(), this->userlist.messages.begin(), this->userlist.messages.end()); - - //Evaluate any conditions in the global messages. - BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions."; - try { - list::iterator it = messages.begin(); - while (it != messages.end()) { - if (!it->EvalCondition(*this, language)) - it = messages.erase(it); - else - ++it; - } - } - catch (std::exception& e) { - BOOST_LOG_TRIVIAL(error) << "A global message contains a condition that could not be evaluated. Details: " << e.what(); - messages.push_back(loot::Message(loot::Message::error, (format(loc::translate("A global message contains a condition that could not be evaluated. Details: %1%")) % e.what()).str())); - } - - //////////////////////////////////////////////////////// - // Slim down masterlist - //////////////////////////////////////////////////////// - // - // Userlist data gets replaced every time sorting is looped, so there's no point evaluating it - // outside the loop, but the masterlist can be slimmed down now. - - progressCallback("Filtering masterlist..."); - - std::list tempMasterlistPlugins; - for (const auto &plugin : this->plugins) { - list::iterator pos = std::find(this->masterlist.plugins.begin(), this->masterlist.plugins.end(), plugin.second); - - if (pos != this->masterlist.plugins.end()) { - // The plugin exists in the masterlist, store a copy of its metadata. - tempMasterlistPlugins.push_back(*pos); - } - } - // Now replace the current full masterlist plugin metadata list with the install-specific one. - this->masterlist.plugins = tempMasterlistPlugins; - } - - - std::list Game::Sort(const unsigned int language, std::list& messages, std::function progressCallback) { + std::list Game::Sort(const unsigned int language, std::function progressCallback) { //Create a plugin graph containing the plugin and masterlist data. loot::PluginGraph graph; @@ -163,7 +74,9 @@ namespace loot { } catch (std::exception& e) { BOOST_LOG_TRIVIAL(error) << "\"" << graph[v].Name() << "\" contains a condition that could not be evaluated. Details: " << e.what(); + list messages(graph[v].Messages()); messages.push_back(loot::Message(loot::Message::error, (format(loc::translate("\"%1%\" contains a condition that could not be evaluated. Details: %2%")) % graph[v].Name() % e.what()).str())); + graph[v].Messages(messages); } //Also check install validity. diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index 360d9894..aed743cd 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -172,9 +172,27 @@ namespace loot { return true; } else if (request == "sortPlugins") { + + //Set language. + unsigned int language; + if (g_app_state.GetSettings()["language"]) + language = Language(g_app_state.GetSettings()["language"].as()).Code(); + else + language = Language::any; + BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name(); + + // Check if the first plugin has any FormIDs in memory, and if not load all plugins. + if (g_app_state.CurrentGame().plugins.begin()->second.FormIDs().size() == 0) + g_app_state.CurrentGame().LoadPlugins(false); + //Sort plugins into their load order. + list plugins = g_app_state.CurrentGame().Sort(language, [](const string& message){}); + list loadOrder; - g_app_state.CurrentGame().GetLoadOrder(loadOrder); + for (const auto &plugin : plugins) { + loadOrder.push_back(plugin.Name()); + } + callback->Success(JSON::stringify(YAML::Node(loadOrder))); return true; }