mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Started to refactor plugin sorting code.
This commit is contained in:
+2
-1
@@ -49,7 +49,8 @@ set (LOOT_SRC "${CMAKE_SOURCE_DIR}/src/backend/metadata.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/game.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/helpers.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/globals.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/generators.cpp")
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/generators.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/backend/sort.cpp")
|
||||
|
||||
set (LOOT_GUI_SRC ${LOOT_SRC}
|
||||
# Code the API doesn't need.
|
||||
|
||||
@@ -119,6 +119,8 @@ namespace loot {
|
||||
void RedatePlugins(); //Change timestamps to match load order (Skyrim only).
|
||||
void LoadPlugins(bool headersOnly); //Loads all installed plugins.
|
||||
|
||||
void SortPlugins(const unsigned int language, std::list<Message>& messages, std::function<void(const std::string&)> callback);
|
||||
|
||||
//Caches for condition results, active plugins and CRCs.
|
||||
std::unordered_map<std::string, bool> conditionCache; //Holds lowercased strings.
|
||||
std::unordered_map<std::string, uint32_t> crcCache; //Holds lowercased strings.
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/* LOOT
|
||||
|
||||
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
|
||||
Fallout: New Vegas.
|
||||
|
||||
Copyright (C) 2014 WrinklyNinja
|
||||
|
||||
This file is part of LOOT.
|
||||
|
||||
LOOT is free software: you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
LOOT is distributed in the hope that it will
|
||||
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with LOOT. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "game.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/locale.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
using boost::format;
|
||||
|
||||
namespace loc = boost::locale;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace loot {
|
||||
|
||||
void Game::SortPlugins(const unsigned int language, std::list<Message>& messages, std::function<void(const std::string&)> callback) {
|
||||
boost::thread_group group;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name();
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Load Plugins & Lists
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
callback("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
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
callback("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<loot::Message>::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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-58
@@ -605,14 +605,9 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Beginning sorting process.";
|
||||
|
||||
list<loot::Message> messages;
|
||||
boost::thread_group group;
|
||||
unsigned int lang;
|
||||
|
||||
wxProgressDialog *progDia = new wxProgressDialog(translate("LOOT: Working..."),translate("LOOT working..."), 1000, this, wxPD_APP_MODAL|wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME);
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Load Plugins & Lists
|
||||
///////////////////////////////////////////////////////
|
||||
wxProgressDialog *progDia = new wxProgressDialog(translate("LOOT: Working..."), translate("LOOT working..."), 1000, this, wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_ELAPSED_TIME);
|
||||
|
||||
//Set language.
|
||||
if (_settings["Language"])
|
||||
@@ -622,61 +617,13 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(lang).Name();
|
||||
|
||||
group.create_thread([this, lang, &messages]() {
|
||||
try {
|
||||
this->_games[_currentGame].masterlist.Load(this->_games[_currentGame], lang);
|
||||
}
|
||||
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->_games[_currentGame].LoadPlugins(false);
|
||||
});
|
||||
group.join_all();
|
||||
|
||||
//Now load userlist.
|
||||
if (fs::exists(_games[_currentGame].UserlistPath())) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Parsing userlist at: " << _games[_currentGame].UserlistPath();
|
||||
|
||||
try {
|
||||
_games[_currentGame].userlist.Load(_games[_currentGame].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()));
|
||||
}
|
||||
}
|
||||
|
||||
progDia->Pulse();
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Merge & Check Metadata
|
||||
// Load Plugins & Lists
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
//Merge all global message lists.
|
||||
BOOST_LOG_TRIVIAL(debug) << "Merging all global message lists.";
|
||||
if (!_games[_currentGame].masterlist.messages.empty())
|
||||
messages.insert(messages.end(), _games[_currentGame].masterlist.messages.begin(), _games[_currentGame].masterlist.messages.end());
|
||||
if (!_games[_currentGame].userlist.messages.empty())
|
||||
messages.insert(messages.end(), _games[_currentGame].userlist.messages.begin(), _games[_currentGame].userlist.messages.end());
|
||||
|
||||
//Evaluate any conditions in the global messages.
|
||||
BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions.";
|
||||
try {
|
||||
list<loot::Message>::iterator it=messages.begin();
|
||||
while (it != messages.end()) {
|
||||
if (!it->EvalCondition(_games[_currentGame], lang))
|
||||
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()));
|
||||
}
|
||||
|
||||
progDia->Update(800, translate("Building plugin graph..."));
|
||||
_games[_currentGame].SortPlugins(lang, messages, [progDia](const std::string& message) {
|
||||
progDia->Pulse(FromUTF8(message));
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Build Graph Edges & Sort
|
||||
@@ -692,6 +639,8 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
|
||||
*/
|
||||
|
||||
progDia->Update(800, translate("Building plugin graph..."));
|
||||
|
||||
//Check for back-edges, then perform a topological sort.
|
||||
list<loot::Plugin> plugins;
|
||||
for (auto &plugin : _games[_currentGame].plugins) {
|
||||
|
||||
Reference in New Issue
Block a user