Move Game data members into GameCache

Also make them private.
This commit is contained in:
Oliver Hamlet
2015-12-08 21:27:22 +00:00
parent 9224e30153
commit 14a5076b65
13 changed files with 202 additions and 193 deletions
+15 -15
View File
@@ -363,9 +363,9 @@ LOOT_API unsigned int loot_load_lists(loot_db db, const char * const masterlistP
db->extTagMap = nullptr;
db->extMessageArray = nullptr;
db->masterlist = temp;
db->GetMasterlist() = temp;
db->rawMetadata = temp;
db->userlist = userTemp;
db->GetUserlist() = userTemp;
db->rawUserMetadata = userTemp;
return loot_ok;
@@ -406,8 +406,8 @@ LOOT_API unsigned int loot_eval_lists(loot_db db, const unsigned int language) {
catch (loot::error& e) {
return c_error(e);
}
db->masterlist = temp;
db->userlist = userTemp;
db->GetMasterlist() = temp;
db->GetUserlist() = userTemp;
return loot_ok;
}
@@ -575,12 +575,12 @@ LOOT_API unsigned int loot_get_tag_map(loot_db db, char *** const tagMap, size_t
std::set<std::string> allTags;
for (const auto &plugin : db->masterlist.Plugins()) {
for (const auto &plugin : db->GetMasterlist().Plugins()) {
for (const auto &tag : plugin.Tags()) {
allTags.insert(tag.Name());
}
}
for (const auto &plugin : db->userlist.Plugins()) {
for (const auto &plugin : db->GetUserlist().Plugins()) {
for (const auto &tag : plugin.Tags()) {
allTags.insert(tag.Name());
}
@@ -649,7 +649,7 @@ LOOT_API unsigned int loot_get_plugin_tags(loot_db db, const char * const plugin
*numTags_removed = 0;
std::set<std::string> tagsAdded, tagsRemoved;
loot::PluginMetadata p = db->masterlist.FindPlugin(loot::PluginMetadata(plugin));
loot::PluginMetadata p = db->GetMasterlist().FindPlugin(loot::PluginMetadata(plugin));
for (const auto &tag : p.Tags()) {
if (tag.IsAddition())
tagsAdded.insert(tag.Name());
@@ -657,7 +657,7 @@ LOOT_API unsigned int loot_get_plugin_tags(loot_db db, const char * const plugin
tagsRemoved.insert(tag.Name());
}
p = db->userlist.FindPlugin(loot::PluginMetadata(plugin));
p = db->GetUserlist().FindPlugin(loot::PluginMetadata(plugin));
*userlistModified = !p.Tags().empty();
for (const auto &tag : p.Tags()) {
*userlistModified = true;
@@ -730,10 +730,10 @@ LOOT_API unsigned int loot_get_plugin_messages(loot_db db, const char * const pl
*messages = nullptr;
*numMessages = 0;
loot::PluginMetadata p = db->masterlist.FindPlugin(loot::PluginMetadata(plugin));
loot::PluginMetadata p = db->GetMasterlist().FindPlugin(loot::PluginMetadata(plugin));
std::list<loot::Message> pluginMessages(p.Messages());
p = db->userlist.FindPlugin(loot::PluginMetadata(plugin));
p = db->GetUserlist().FindPlugin(loot::PluginMetadata(plugin));
std::list<loot::Message> temp(p.Messages());
pluginMessages.insert(pluginMessages.end(), temp.begin(), temp.end());
@@ -766,8 +766,8 @@ LOOT_API unsigned int loot_get_dirty_info(loot_db db, const char * const plugin,
*needsCleaning = loot_needs_cleaning_unknown;
// Is there any dirty info? Testing for applicability happens in loot_eval_lists().
if (!db->masterlist.FindPlugin(loot::PluginMetadata(plugin)).DirtyInfo().empty()
|| !db->userlist.FindPlugin(loot::PluginMetadata(plugin)).DirtyInfo().empty()) {
if (!db->GetMasterlist().FindPlugin(loot::PluginMetadata(plugin)).DirtyInfo().empty()
|| !db->GetUserlist().FindPlugin(loot::PluginMetadata(plugin)).DirtyInfo().empty()) {
*needsCleaning = loot_needs_cleaning_yes;
}
@@ -775,9 +775,9 @@ LOOT_API unsigned int loot_get_dirty_info(loot_db db, const char * const plugin,
// This isn't a very reliable system, because if the lists have been evaluated in some language
// other than English, the strings will be in different languages (and the API can't tell what they'd be)
// and the strings may be non-standard and begin with something other than "Do not clean." anyway.
std::list<loot::Message> messages(db->masterlist.FindPlugin(loot::PluginMetadata(plugin)).Messages());
std::list<loot::Message> messages(db->GetMasterlist().FindPlugin(loot::PluginMetadata(plugin)).Messages());
std::list<loot::Message> temp(db->userlist.FindPlugin(loot::PluginMetadata(plugin)).Messages());
std::list<loot::Message> temp(db->GetUserlist().FindPlugin(loot::PluginMetadata(plugin)).Messages());
messages.insert(messages.end(), temp.begin(), temp.end());
for (const auto& message : messages) {
@@ -804,7 +804,7 @@ LOOT_API unsigned int loot_write_minimal_list(loot_db db, const char * const out
if (boost::filesystem::exists(outputFile) && !overwrite)
return c_error(loot_error_file_write_fail, "Output file exists but overwrite is not set to true.");
loot::Masterlist temp = db->masterlist;
loot::Masterlist temp = db->GetMasterlist();
std::unordered_set<loot::PluginMetadata> minimalPlugins;
for (const auto &plugin : temp.Plugins()) {
loot::PluginMetadata p(plugin.Name());
+6 -38
View File
@@ -50,31 +50,8 @@ namespace loot {
.SetRegistryKey(gameSettings.RegistryKey());
}
Game::Game(const Game& game) :
GameSettings(game),
LoadOrderHandler(game),
GameCache(game),
masterlist(game.masterlist),
userlist(game.userlist),
plugins(game.plugins),
_pluginsFullyLoaded(game.ArePluginsFullyLoaded()) {}
Game::Game(const unsigned int gameCode, const std::string& folder) : GameSettings(gameCode, folder), _pluginsFullyLoaded(false) {}
Game& Game::operator= (const Game& game) {
if (&game != this) {
GameSettings::operator=(game);
LoadOrderHandler::operator=(game);
GameCache::operator=(game);
masterlist = game.masterlist;
userlist = game.userlist;
plugins = game.plugins;
_pluginsFullyLoaded = game.ArePluginsFullyLoaded();
}
return *this;
}
void Game::Init(bool createFolder, const boost::filesystem::path& gameLocalAppData) {
if (Id() != Game::tes4 && Id() != Game::tes5 && Id() != Game::fo3 && Id() != Game::fonv && Id() != Game::fo4) {
throw error(error::invalid_args, lc::translate("Invalid game ID supplied.").str());
@@ -156,11 +133,6 @@ namespace loot {
}
meanFileSize /= sizeMap.size(); //Rounding error, but not important.
// Reserve space in the plugins unordered_map to speed up inserting
// later and more importantly avoid any inserts invalidating
// iterators.
plugins.reserve(sizeMap.size());
// Get the number of threads to use.
// hardware_concurrency() may be zero, if so then use only one thread.
size_t threadsToUse = std::min((size_t)thread::hardware_concurrency(), sizeMap.size());
@@ -190,7 +162,7 @@ namespace loot {
threads.push_back(thread([&]() {
for (auto pluginName : pluginGroup) {
BOOST_LOG_TRIVIAL(trace) << "Loading " << pluginName;
addPlugin(Plugin(*this, pluginName, headersOnly));
AddPlugin(Plugin(*this, pluginName, headersOnly));
}
}));
}
@@ -209,16 +181,12 @@ namespace loot {
}
bool Game::IsPluginActive(const std::string& pluginName) const {
auto it = plugins.find(boost::locale::to_lower(pluginName));
if (it != end(plugins))
return it->second.IsActive();
else
try {
return GetPlugin(pluginName).IsActive();
}
catch (...) {
return LoadOrderHandler::IsPluginActive(pluginName);
}
void Game::addPlugin(const Plugin&& plugin) {
std::lock_guard<std::mutex> lock(mutex);
plugins.emplace(boost::locale::to_lower(plugin.Name()), plugin);
}
}
std::list<Game> ToGames(const std::list<GameSettings>& settings) {
-15
View File
@@ -28,12 +28,8 @@
#include "game_cache.h"
#include "game_settings.h"
#include "load_order_handler.h"
#include "../plugin/plugin.h"
#include "../metadata_list.h"
#include "../masterlist.h"
#include <string>
#include <unordered_map>
#include <boost/filesystem.hpp>
@@ -43,11 +39,8 @@ namespace loot {
//Game functions.
Game(); //Sets game to LOOT_Game::autodetect, with all other vars being empty.
Game(const GameSettings& gameSettings);
Game(const Game& game);
Game(const unsigned int baseGameCode, const std::string& lootFolder = "");
Game& operator= (const Game& game);
void Init(bool createFolder, const boost::filesystem::path& gameLocalAppData = "");
void RedatePlugins(); //Change timestamps to match load order (Skyrim only).
@@ -58,16 +51,8 @@ namespace loot {
// Check if the plugin is active by using the cached value if
// available, and otherwise asking the load order handler.
bool IsPluginActive(const std::string& pluginName) const;
//Plugin data and metadata lists.
Masterlist masterlist;
MetadataList userlist;
std::unordered_map<std::string, Plugin> plugins; //Map so that plugin data can be edited.
private:
bool _pluginsFullyLoaded;
std::mutex mutex;
void addPlugin(const Plugin&& plugin);
};
std::list<Game> ToGames(const std::list<GameSettings>& settings);
+43 -3
View File
@@ -40,15 +40,31 @@ namespace lc = boost::locale;
namespace loot {
GameCache::GameCache() {}
GameCache::GameCache(const GameCache& cache)
: conditionCache(cache.conditionCache) {}
GameCache::GameCache(const GameCache& cache) :
masterlist(cache.masterlist),
userlist(cache.userlist),
conditionCache(cache.conditionCache),
plugins(cache.plugins) {}
GameCache& GameCache::operator=(const GameCache& cache) {
conditionCache = cache.conditionCache;
if (&cache != this) {
masterlist = cache.masterlist;
userlist = cache.userlist;
conditionCache = cache.conditionCache;
plugins = cache.plugins;
}
return *this;
}
Masterlist & GameCache::GetMasterlist() {
return masterlist;
}
MetadataList & GameCache::GetUserlist() {
return userlist;
}
void GameCache::CacheCondition(const std::string& condition, bool result) {
std::lock_guard<std::mutex> guard(mutex);
conditionCache.insert(pair<string, bool>(boost::locale::to_lower(condition), result));
@@ -65,6 +81,30 @@ namespace loot {
return std::pair<bool, bool>(false, false);
}
std::set<Plugin> GameCache::GetPlugins() const {
std::set<Plugin> output;
std::transform(begin(plugins),
end(plugins),
inserter<set<Plugin>>(output, begin(output)),
[](const pair<std::string, Plugin>& pluginPair) {
return pluginPair.second;
});
return output;
}
const Plugin& GameCache::GetPlugin(const std::string & pluginName) const {
auto it = plugins.find(boost::locale::to_lower(pluginName));
if (it != end(plugins))
return it->second;
throw error(error::invalid_args, "No plugin \"" + pluginName + "\" exists.");
}
void GameCache::AddPlugin(const Plugin&& plugin) {
std::lock_guard<std::mutex> lock(mutex);
plugins.emplace(boost::locale::to_lower(plugin.Name()), plugin);
}
void GameCache::ClearCache() {
std::lock_guard<std::mutex> guard(mutex);
+15 -4
View File
@@ -25,11 +25,14 @@
#ifndef __LOOT_GAME_CRC_CACHE__
#define __LOOT_GAME_CRC_CACHE__
#include <string>
#include "../metadata_list.h"
#include "../masterlist.h"
#include "../plugin/plugin.h"
#include <cstdint>
#include <string>
#include <mutex>
#include <unordered_map>
#include <unordered_set>
namespace loot {
class GameCache {
@@ -39,15 +42,23 @@ namespace loot {
GameCache& operator=(const GameCache& cache);
void CacheCondition(const std::string& condition, bool result);
Masterlist& GetMasterlist();
MetadataList& GetUserlist();
// Returns false for second bool if no cached condition.
std::pair<bool, bool> GetCachedCondition(const std::string& condition) const;
void CacheCondition(const std::string& condition, bool result);
std::set<Plugin> GetPlugins() const;
const Plugin& GetPlugin(const std::string & pluginName) const;
void AddPlugin(const Plugin&& plugin);
void ClearCache();
private:
//Caches for condition results, CRCs and active plugins.
Masterlist masterlist;
MetadataList userlist;
std::unordered_map<std::string, bool> conditionCache;
std::unordered_map<std::string, Plugin> plugins;
mutable std::mutex mutex;
};
+4 -3
View File
@@ -293,9 +293,10 @@ namespace loot {
else {
// CRC could be for a plugin or a file.
// Get the CRC from the game plugin cache if possible.
auto pluginPairIt = _game->plugins.find(boost::locale::to_lower(file));
if (pluginPairIt != _game->plugins.end())
crc = pluginPairIt->second.Crc();
try {
crc = _game->GetPlugin(file).Crc();
}
catch (...) {}
if (crc == 0) {
if (boost::filesystem::exists(_game->DataPath() / file))
+4 -3
View File
@@ -98,9 +98,10 @@ namespace loot {
uint32_t crc = 0;
// Get the CRC from the game plugin cache if possible.
auto pluginPairIt = game.plugins.find(boost::locale::to_lower(pluginName));
if (pluginPairIt != game.plugins.end())
crc = pluginPairIt->second.Crc();
try {
crc = game.GetPlugin(pluginName).Crc();
}
catch (...) {}
// Otherwise calculate it from the file.
if (crc == 0) {
+4
View File
@@ -184,6 +184,10 @@ namespace loot {
return false;
}
bool Plugin::operator < (const Plugin & rhs) const {
return boost::ilexicographical_compare(Name(), rhs.Name());;
}
bool Plugin::IsActive() const {
return _isActive;
}
+2
View File
@@ -62,6 +62,8 @@ namespace loot {
//Validity checks.
bool CheckInstallValidity(const Game& game); //Checks that reqs and masters are all present, and that no incs are present. Returns true if the plugin is dirty.
static bool IsValid(const std::string& filename, const Game& game);
bool operator < (const Plugin& rhs) const;
private:
bool _isEmpty; // Does the plugin contain any records other than the TES4 header?
bool _isActive;
+4 -9
View File
@@ -177,21 +177,16 @@ namespace loot {
// Using a set of plugin names followed by finding the matching key
// in the unordered map, as it's probably faster than copying the
// full plugin objects then sorting them.
set<string> pluginNames;
for (const auto &plugin : game.plugins) {
pluginNames.insert(plugin.first);
}
for (const auto &plugin : pluginNames) {
vertex_t v = boost::add_vertex(game.plugins.find(plugin)->second, graph);
for (const auto &plugin : game.GetPlugins()) {
vertex_t v = boost::add_vertex(plugin, graph);
BOOST_LOG_TRIVIAL(trace) << "Merging for plugin \"" << graph[v].Name() << "\"";
//Check if there is a plugin entry in the masterlist. This will also find matching regex entries.
BOOST_LOG_TRIVIAL(trace) << "Merging masterlist data down to plugin list data.";
graph[v].MergeMetadata(game.masterlist.FindPlugin(graph[v]));
graph[v].MergeMetadata(game.GetMasterlist().FindPlugin(graph[v]));
//Check if there is a plugin entry in the userlist. This will also find matching regex entries.
PluginMetadata ulistPlugin = game.userlist.FindPlugin(graph[v]);
PluginMetadata ulistPlugin = game.GetUserlist().FindPlugin(graph[v]);
if (!ulistPlugin.HasNameOnly() && ulistPlugin.Enabled()) {
BOOST_LOG_TRIVIAL(trace) << "Merging userlist data down to plugin list data.";
+55 -53
View File
@@ -400,7 +400,7 @@ namespace loot {
void Handler::GetConflictingPlugins(const std::string& pluginName, CefRefPtr<CefFrame> frame, CefRefPtr<Callback> callback) {
BOOST_LOG_TRIVIAL(debug) << "Searching for plugins that conflict with " << pluginName;
auto pluginIt = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(pluginName));
auto plugin = _lootState.CurrentGame().GetPlugin(pluginName);
// Checking for FormID overlap will only work if the plugins have been loaded, so check if
// the plugins have been fully loaded, and if not load all plugins.
@@ -411,13 +411,13 @@ namespace loot {
SendProgressUpdate(frame, loc::translate("Checking for conflicting plugins..."));
YAML::Node node;
for (const auto& pluginPair : _lootState.CurrentGame().plugins) {
for (const auto& otherPlugin : _lootState.CurrentGame().GetPlugins()) {
YAML::Node pluginNode;
pluginNode["crc"] = pluginPair.second.Crc();
pluginNode["isEmpty"] = pluginPair.second.IsEmpty();
if (pluginIt != _lootState.CurrentGame().plugins.end() && pluginIt->second.DoFormIDsOverlap(pluginPair.second)) {
BOOST_LOG_TRIVIAL(debug) << "Found conflicting plugin: " << pluginPair.second.Name();
pluginNode["crc"] = otherPlugin.Crc();
pluginNode["isEmpty"] = otherPlugin.IsEmpty();
if (plugin.DoFormIDsOverlap(otherPlugin)) {
BOOST_LOG_TRIVIAL(debug) << "Found conflicting plugin: " << otherPlugin.Name();
pluginNode["conflicts"] = true;
}
else {
@@ -425,13 +425,13 @@ namespace loot {
}
// Plugin loading may have produced an error message, so rederive displayed data.
YAML::Node derivedNode = GenerateDerivedMetadata(pluginPair.second.Name());
YAML::Node derivedNode = GenerateDerivedMetadata(otherPlugin.Name());
for (const auto &pair : derivedNode) {
const string key = pair.first.as<string>();
pluginNode[key] = pair.second;
}
node[pluginPair.second.Name()] = pluginNode;
node[otherPlugin.Name()] = pluginNode;
}
if (node.size() > 0)
@@ -444,8 +444,8 @@ namespace loot {
BOOST_LOG_TRIVIAL(debug) << "Copying metadata for plugin " << pluginName;
// Get metadata from masterlist and userlist.
PluginMetadata plugin = _lootState.CurrentGame().masterlist.FindPlugin(pluginName);
plugin.MergeMetadata(_lootState.CurrentGame().userlist.FindPlugin(pluginName));
PluginMetadata plugin = _lootState.CurrentGame().GetMasterlist().FindPlugin(pluginName);
plugin.MergeMetadata(_lootState.CurrentGame().GetUserlist().FindPlugin(pluginName));
// Generate text representation.
string text;
@@ -465,10 +465,10 @@ namespace loot {
std::string Handler::ClearPluginMetadata(const std::string& pluginName) {
BOOST_LOG_TRIVIAL(debug) << "Clearing user metadata for plugin " << pluginName;
_lootState.CurrentGame().userlist.ErasePlugin(PluginMetadata(pluginName));
_lootState.CurrentGame().GetUserlist().ErasePlugin(PluginMetadata(pluginName));
// Save userlist edits.
_lootState.CurrentGame().userlist.Save(_lootState.CurrentGame().UserlistPath());
_lootState.CurrentGame().GetUserlist().Save(_lootState.CurrentGame().UserlistPath());
// Now rederive the displayed metadata from the masterlist.
YAML::Node derivedMetadata = GenerateDerivedMetadata(pluginName);
@@ -484,7 +484,7 @@ namespace loot {
PluginMetadata newUserlistEntry(pluginMetadata["name"].as<string>());
// Find existing userlist entry.
PluginMetadata ulistPlugin = _lootState.CurrentGame().userlist.FindPlugin(newUserlistEntry);
PluginMetadata ulistPlugin = _lootState.CurrentGame().GetUserlist().FindPlugin(newUserlistEntry);
// First sort out the priority value. This is only given if it was changed.
BOOST_LOG_TRIVIAL(trace) << "Calculating userlist metadata priority value from Javascript variables.";
@@ -537,28 +537,28 @@ namespace loot {
// For cleanliness, only data that does not duplicate masterlist and plugin data should be retained, so diff that.
BOOST_LOG_TRIVIAL(trace) << "Removing any user metadata that duplicates masterlist metadata.";
auto pluginIt = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(newUserlistEntry.Name()));
if (pluginIt != _lootState.CurrentGame().plugins.end()) {
Plugin tempPlugin(pluginIt->second);
tempPlugin.MergeMetadata(_lootState.CurrentGame().masterlist.FindPlugin(newUserlistEntry));
try {
Plugin tempPlugin(_lootState.CurrentGame().GetPlugin(newUserlistEntry.Name()));
tempPlugin.MergeMetadata(_lootState.CurrentGame().GetMasterlist().FindPlugin(newUserlistEntry));
newUserlistEntry = newUserlistEntry.NewMetadata(tempPlugin);
}
else
newUserlistEntry = newUserlistEntry.NewMetadata(_lootState.CurrentGame().masterlist.FindPlugin(newUserlistEntry));
catch (...) {
newUserlistEntry = newUserlistEntry.NewMetadata(_lootState.CurrentGame().GetMasterlist().FindPlugin(newUserlistEntry));
}
// Now erase any existing userlist entry.
if (!ulistPlugin.HasNameOnly()) {
BOOST_LOG_TRIVIAL(trace) << "Erasing the existing userlist entry.";
_lootState.CurrentGame().userlist.ErasePlugin(ulistPlugin);
_lootState.CurrentGame().GetUserlist().ErasePlugin(ulistPlugin);
}
// Add a new userlist entry if necessary.
if (!newUserlistEntry.HasNameOnly()) {
BOOST_LOG_TRIVIAL(trace) << "Adding new metadata to new userlist entry.";
_lootState.CurrentGame().userlist.AddPlugin(newUserlistEntry);
_lootState.CurrentGame().GetUserlist().AddPlugin(newUserlistEntry);
}
// Save edited userlist.
_lootState.CurrentGame().userlist.Save(_lootState.CurrentGame().UserlistPath());
_lootState.CurrentGame().GetUserlist().Save(_lootState.CurrentGame().UserlistPath());
// Now rederive the derived metadata.
BOOST_LOG_TRIVIAL(trace) << "Returning newly derived display metadata.";
@@ -642,17 +642,18 @@ namespace loot {
// First clear CRC and condition caches, otherwise they could lead to incorrect evaluations.
_lootState.CurrentGame().ClearCache();
bool isFirstLoad = _lootState.CurrentGame().plugins.empty();
bool isFirstLoad = _lootState.CurrentGame().GetPlugins().empty();
_lootState.CurrentGame().LoadPlugins(true);
//Sort plugins into their load order.
list<loot::Plugin> installed;
list<string> loadOrder = _lootState.CurrentGame().GetLoadOrder();
for (const auto &pluginName : loadOrder) {
const auto pos = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(pluginName));
if (pos != _lootState.CurrentGame().plugins.end())
installed.push_back(pos->second);
try {
const auto plugin = _lootState.CurrentGame().GetPlugin(pluginName);
installed.push_back(plugin);
}
catch (...) {}
}
list<Message> parsingErrors;
@@ -662,7 +663,7 @@ namespace loot {
SendProgressUpdate(frame, loc::translate("Parsing masterlist..."));
BOOST_LOG_TRIVIAL(debug) << "Parsing masterlist.";
try {
_lootState.CurrentGame().masterlist.Load(_lootState.CurrentGame().MasterlistPath());
_lootState.CurrentGame().GetMasterlist().Load(_lootState.CurrentGame().MasterlistPath());
}
catch (exception &e) {
parsingErrors.push_back(Message(Message::error, (boost::format(loc::translate(
@@ -679,7 +680,7 @@ namespace loot {
SendProgressUpdate(frame, loc::translate("Parsing userlist..."));
BOOST_LOG_TRIVIAL(debug) << "Parsing userlist.";
try {
_lootState.CurrentGame().userlist.Load(_lootState.CurrentGame().UserlistPath());
_lootState.CurrentGame().GetUserlist().Load(_lootState.CurrentGame().UserlistPath());
}
catch (exception &e) {
parsingErrors.push_back(Message(Message::error, (boost::format(loc::translate(
@@ -710,7 +711,7 @@ namespace loot {
// Store the masterlist revision and date.
try {
Masterlist::Info info = _lootState.CurrentGame().masterlist.GetInfo(_lootState.CurrentGame().MasterlistPath(), true);
Masterlist::Info info = _lootState.CurrentGame().GetMasterlist().GetInfo(_lootState.CurrentGame().MasterlistPath(), true);
gameNode["masterlist"]["revision"] = info.revision;
gameNode["masterlist"]["date"] = info.date;
}
@@ -730,11 +731,11 @@ namespace loot {
// description as part of it.
BOOST_LOG_TRIVIAL(trace) << "Getting masterlist metadata for: " << plugin.Name();
Plugin mlistPlugin(plugin);
mlistPlugin.MergeMetadata(_lootState.CurrentGame().masterlist.FindPlugin(plugin));
mlistPlugin.MergeMetadata(_lootState.CurrentGame().GetMasterlist().FindPlugin(plugin));
// Now do the same again for any userlist data.
BOOST_LOG_TRIVIAL(trace) << "Getting userlist metadata for: " << plugin.Name();
PluginMetadata ulistPlugin(_lootState.CurrentGame().userlist.FindPlugin(plugin));
PluginMetadata ulistPlugin(_lootState.CurrentGame().GetUserlist().FindPlugin(plugin));
pluginNode["__type"] = "Plugin"; // For conversion back into a JS typed object.
pluginNode["name"] = plugin.Name();
@@ -797,11 +798,11 @@ namespace loot {
//Evaluate any conditions in the global messages.
BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions.";
list<Message> messages = parsingErrors;
auto metadataListMessages = _lootState.CurrentGame().masterlist.Messages();
auto metadataListMessages = _lootState.CurrentGame().GetMasterlist().Messages();
messages.insert(end(messages),
begin(metadataListMessages),
end(metadataListMessages));
metadataListMessages = _lootState.CurrentGame().userlist.Messages();
metadataListMessages = _lootState.CurrentGame().GetUserlist().Messages();
messages.insert(messages.end(),
begin(metadataListMessages),
end(metadataListMessages));
@@ -850,20 +851,20 @@ namespace loot {
bool wasChanged = true;
try {
SendProgressUpdate(frame, loc::translate("Updating and parsing masterlist..."));
wasChanged = _lootState.CurrentGame().masterlist.Update(_lootState.CurrentGame());
wasChanged = _lootState.CurrentGame().GetMasterlist().Update(_lootState.CurrentGame());
}
catch (loot::error &e) {
if (e.code() == loot::error::ok) {
// There was a parsing error, but roll-back was successful, so the process
// should still complete.
_lootState.CurrentGame().masterlist.AppendMessage(Message(Message::error, e.what()));
_lootState.CurrentGame().GetMasterlist().AppendMessage(Message(Message::error, e.what()));
wasChanged = true;
}
else {
// Error wasn't a parsing error. Need to try parsing masterlist if it exists.
try {
_lootState.CurrentGame().masterlist.Load(_lootState.CurrentGame().MasterlistPath());
_lootState.CurrentGame().GetMasterlist().Load(_lootState.CurrentGame().MasterlistPath());
}
catch (...) {}
}
@@ -878,7 +879,7 @@ namespace loot {
// Store the masterlist revision and date.
try {
Masterlist::Info info = _lootState.CurrentGame().masterlist.GetInfo(_lootState.CurrentGame().MasterlistPath(), true);
Masterlist::Info info = _lootState.CurrentGame().GetMasterlist().GetInfo(_lootState.CurrentGame().MasterlistPath(), true);
gameNode["masterlist"]["revision"] = info.revision;
gameNode["masterlist"]["date"] = info.date;
}
@@ -887,9 +888,9 @@ namespace loot {
gameNode["masterlist"]["date"] = e.what();
}
for (const auto& pluginPair : _lootState.CurrentGame().plugins) {
Plugin mlistPlugin(pluginPair.second);
mlistPlugin.MergeMetadata(_lootState.CurrentGame().masterlist.FindPlugin(pluginPair.second));
for (const auto& plugin : _lootState.CurrentGame().GetPlugins()) {
Plugin mlistPlugin(plugin);
mlistPlugin.MergeMetadata(_lootState.CurrentGame().GetMasterlist().FindPlugin(plugin));
YAML::Node pluginNode;
if (!mlistPlugin.HasNameOnly()) {
@@ -905,7 +906,7 @@ namespace loot {
// Now merge masterlist and userlist metadata and evaluate,
// putting any resulting metadata into the base of the pluginNode.
YAML::Node derivedNode = GenerateDerivedMetadata(pluginPair.second.Name());
YAML::Node derivedNode = GenerateDerivedMetadata(plugin.Name());
for (const auto &pair : derivedNode) {
const string key = pair.first.as<string>();
@@ -917,7 +918,7 @@ namespace loot {
//Evaluate any conditions in the global messages.
BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions.";
list<Message> messages = _lootState.CurrentGame().masterlist.Messages();
list<Message> messages = _lootState.CurrentGame().GetMasterlist().Messages();
try {
list<Message>::iterator it = messages.begin();
while (it != messages.end()) {
@@ -954,16 +955,16 @@ namespace loot {
BOOST_LOG_TRIVIAL(debug) << "Clearing all user metadata.";
// Record which plugins have userlist entries.
vector<string> userlistPlugins;
for (const auto &plugin : _lootState.CurrentGame().userlist.Plugins()) {
for (const auto &plugin : _lootState.CurrentGame().GetUserlist().Plugins()) {
userlistPlugins.push_back(plugin.Name());
}
BOOST_LOG_TRIVIAL(trace) << "User metadata exists for " << userlistPlugins.size() << " plugins.";
// Clear the user metadata.
_lootState.CurrentGame().userlist.clear();
_lootState.CurrentGame().GetUserlist().clear();
// Save userlist edits.
_lootState.CurrentGame().userlist.Save(_lootState.CurrentGame().UserlistPath());
_lootState.CurrentGame().GetUserlist().Save(_lootState.CurrentGame().UserlistPath());
// Regenerate the derived metadata (priority, messages, tags and dirty state)
// for any plugins with userlist entries.
@@ -1074,15 +1075,16 @@ namespace loot {
YAML::Node Handler::GenerateDerivedMetadata(const std::string& pluginName) {
// Now rederive the displayed metadata from the masterlist and userlist.
auto pluginIt = _lootState.CurrentGame().plugins.find(boost::locale::to_lower(pluginName));
if (pluginIt != _lootState.CurrentGame().plugins.end()) {
PluginMetadata master(_lootState.CurrentGame().masterlist.FindPlugin(pluginIt->second));
PluginMetadata user(_lootState.CurrentGame().userlist.FindPlugin(pluginIt->second));
try {
auto plugin = _lootState.CurrentGame().GetPlugin(pluginName);
PluginMetadata master(_lootState.CurrentGame().GetMasterlist().FindPlugin(plugin));
PluginMetadata user(_lootState.CurrentGame().GetUserlist().FindPlugin(plugin));
return this->GenerateDerivedMetadata(pluginIt->second, master, user);
return this->GenerateDerivedMetadata(plugin, master, user);
}
catch (...) {
return YAML::Node();
}
return YAML::Node();
}
void Handler::CopyToClipboard(const std::string& text) {
+46 -46
View File
@@ -216,11 +216,11 @@ TEST_F(Game, LoadPlugins) {
game.SetGamePath(dataPath.parent_path());
EXPECT_NO_THROW(game.LoadPlugins(false));
EXPECT_EQ(11, game.plugins.size());
EXPECT_EQ(11, game.GetPlugins().size());
// Check that all the plugins' data have loaded correctly.
ASSERT_NE(game.plugins.end(), game.plugins.find("skyrim.esm"));
loot::Plugin plugin = game.plugins.find("skyrim.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("Skyrim.esm"));
loot::Plugin plugin = game.GetPlugin("Skyrim.esm");
EXPECT_EQ("Skyrim.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -241,8 +241,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0x187BE342, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank.esm"));
plugin = game.plugins.find("blank.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("blank.esm"));
plugin = game.GetPlugin("blank.esm");
EXPECT_EQ("Blank.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -263,8 +263,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0x187BE342, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different.esm"));
plugin = game.plugins.find("blank - different.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("Blank - Different.esm"));
plugin = game.GetPlugin("Blank - Different.esm");
EXPECT_EQ("Blank - Different.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -284,8 +284,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0x64B9F757, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - master dependent.esm"));
plugin = game.plugins.find("blank - master dependent.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esm"));
plugin = game.GetPlugin("blank - master dependent.esm");
EXPECT_EQ("Blank - Master Dependent.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -306,8 +306,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0xB2D4119E, plugin.Crc());
EXPECT_EQ(4, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different master dependent.esm"));
plugin = game.plugins.find("blank - different master dependent.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esm"));
plugin = game.GetPlugin("blank - different master dependent.esm");
EXPECT_EQ("Blank - Different Master Dependent.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -327,8 +327,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0xAADF6710, plugin.Crc());
EXPECT_EQ(4, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank.esp"));
plugin = game.plugins.find("blank.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank.esp"));
plugin = game.GetPlugin("blank.esp");
EXPECT_EQ("Blank.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -345,8 +345,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0x24F0E2A1, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different.esp"));
plugin = game.plugins.find("blank - different.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - different.esp"));
plugin = game.GetPlugin("blank - different.esp");
EXPECT_EQ("Blank - Different.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -362,8 +362,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0xD4C9B7AE, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - master dependent.esp"));
plugin = game.plugins.find("blank - master dependent.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esp"));
plugin = game.GetPlugin("blank - master dependent.esp");
EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -380,8 +380,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0x832152DC, plugin.Crc());
EXPECT_EQ(2, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different master dependent.esp"));
plugin = game.plugins.find("blank - different master dependent.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esp"));
plugin = game.GetPlugin("blank - different master dependent.esp");
EXPECT_EQ("Blank - Different Master Dependent.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -397,8 +397,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0x3AD17683, plugin.Crc());
EXPECT_EQ(2, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - plugin dependent.esp"));
plugin = game.plugins.find("blank - plugin dependent.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - plugin dependent.esp"));
plugin = game.GetPlugin("blank - plugin dependent.esp");
EXPECT_EQ("Blank - Plugin Dependent.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -413,8 +413,8 @@ TEST_F(Game, LoadPlugins) {
EXPECT_EQ(0x28EF26DB, plugin.Crc());
EXPECT_EQ(1, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different plugin dependent.esp"));
plugin = game.plugins.find("blank - different plugin dependent.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - different plugin dependent.esp"));
plugin = game.GetPlugin("blank - different plugin dependent.esp");
EXPECT_EQ("Blank - Different Plugin Dependent.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -434,11 +434,11 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
game.SetGamePath(dataPath.parent_path());
EXPECT_NO_THROW(game.LoadPlugins(true));
EXPECT_EQ(11, game.plugins.size());
EXPECT_EQ(11, game.GetPlugins().size());
// Check that all the plugins' data have loaded correctly.
ASSERT_NE(game.plugins.end(), game.plugins.find("skyrim.esm"));
loot::Plugin plugin = game.plugins.find("skyrim.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("Skyrim.esm"));
loot::Plugin plugin = game.GetPlugin("Skyrim.esm");
EXPECT_EQ("Skyrim.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -448,8 +448,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank.esm"));
plugin = game.plugins.find("blank.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("blank.esm"));
plugin = game.GetPlugin("blank.esm");
EXPECT_EQ("Blank.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -459,8 +459,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different.esm"));
plugin = game.plugins.find("blank - different.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("Blank - Different.esm"));
plugin = game.GetPlugin("Blank - Different.esm");
EXPECT_EQ("Blank - Different.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -470,8 +470,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - master dependent.esm"));
plugin = game.plugins.find("blank - master dependent.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esm"));
plugin = game.GetPlugin("blank - master dependent.esm");
EXPECT_EQ("Blank - Master Dependent.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -483,8 +483,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different master dependent.esm"));
plugin = game.plugins.find("blank - different master dependent.esm")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esm"));
plugin = game.GetPlugin("blank - different master dependent.esm");
EXPECT_EQ("Blank - Different Master Dependent.esm", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_TRUE(plugin.isMasterFile());
@@ -496,8 +496,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank.esp"));
plugin = game.plugins.find("blank.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank.esp"));
plugin = game.GetPlugin("blank.esp");
EXPECT_EQ("Blank.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -507,8 +507,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different.esp"));
plugin = game.plugins.find("blank - different.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - different.esp"));
plugin = game.GetPlugin("blank - different.esp");
EXPECT_EQ("Blank - Different.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -518,8 +518,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - master dependent.esp"));
plugin = game.plugins.find("blank - master dependent.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esp"));
plugin = game.GetPlugin("blank - master dependent.esp");
EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -531,8 +531,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different master dependent.esp"));
plugin = game.plugins.find("blank - different master dependent.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esp"));
plugin = game.GetPlugin("blank - different master dependent.esp");
EXPECT_EQ("Blank - Different Master Dependent.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -544,8 +544,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - plugin dependent.esp"));
plugin = game.plugins.find("blank - plugin dependent.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - plugin dependent.esp"));
plugin = game.GetPlugin("blank - plugin dependent.esp");
EXPECT_EQ("Blank - Plugin Dependent.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
@@ -557,8 +557,8 @@ TEST_F(Game, LoadPlugins_HeadersOnly) {
EXPECT_EQ(0, plugin.Crc());
EXPECT_EQ(0, plugin.NumOverrideFormIDs());
ASSERT_NE(game.plugins.end(), game.plugins.find("blank - different plugin dependent.esp"));
plugin = game.plugins.find("blank - different plugin dependent.esp")->second;
ASSERT_NO_THROW(game.GetPlugin("blank - different plugin dependent.esp"));
plugin = game.GetPlugin("blank - different plugin dependent.esp");
EXPECT_EQ("Blank - Different Plugin Dependent.esp", plugin.Name());
EXPECT_FALSE(plugin.IsEmpty());
EXPECT_FALSE(plugin.isMasterFile());
+4 -4
View File
@@ -94,7 +94,7 @@ TEST_F(PluginSorter, Sort_WithPriority) {
ASSERT_NO_THROW(game.LoadPlugins(false));
loot::PluginMetadata plugin("Blank - Different Master Dependent.esp");
plugin.Priority(-1100000);
game.userlist.AddPlugin(plugin);
game.GetUserlist().AddPlugin(plugin);
loot::PluginSorter ps;
std::list<std::string> expectedSortedOrder({
@@ -122,7 +122,7 @@ TEST_F(PluginSorter, Sort_WithLoadAfter) {
loot::File("Blank - Different.esp"),
loot::File("Blank - Different Plugin Dependent.esp"),
});
game.userlist.AddPlugin(plugin);
game.GetUserlist().AddPlugin(plugin);
loot::PluginSorter ps;
std::list<std::string> expectedSortedOrder({
@@ -150,7 +150,7 @@ TEST_F(PluginSorter, Sort_WithRequirements) {
loot::File("Blank - Different.esp"),
loot::File("Blank - Different Plugin Dependent.esp"),
});
game.userlist.AddPlugin(plugin);
game.GetUserlist().AddPlugin(plugin);
loot::PluginSorter ps;
std::list<std::string> expectedSortedOrder({
@@ -175,7 +175,7 @@ TEST_F(PluginSorter, Sort_HasCycle) {
ASSERT_NO_THROW(game.LoadPlugins(false));
loot::PluginMetadata plugin("Blank.esm");
plugin.LoadAfter({loot::File("Blank - Master Dependent.esm")});
game.userlist.AddPlugin(plugin);
game.GetUserlist().AddPlugin(plugin);
loot::PluginSorter ps;
EXPECT_ANY_THROW(ps.Sort(game, loot::Language::english, callback));