Metadata plugin lists now stored as hashsets.

Closes #249.
This commit is contained in:
WrinklyNinja
2014-08-25 23:08:29 +01:00
parent 69525cb5f6
commit c259553833
8 changed files with 91 additions and 35 deletions
+4 -14
View File
@@ -108,7 +108,7 @@ namespace loot {
in.close();
if (metadataList["plugins"])
plugins = metadataList["plugins"].as< list<Plugin> >();
plugins = metadataList["plugins"].as< unordered_set<Plugin, plugin_hash> >();
if (metadataList["globals"])
messages = metadataList["globals"].as< list<Message> >();
@@ -141,7 +141,7 @@ namespace loot {
}
else {
for (const auto& rhsPlugin : rhs.plugins) {
const auto it = std::find(this->plugins.begin(), this->plugins.end(), rhsPlugin);
const auto it = this->plugins.find(rhsPlugin);
if (it == this->plugins.end()) {
BOOST_LOG_TRIVIAL(info) << "Metadata added for plugin: " << it->Name();
@@ -166,15 +166,6 @@ namespace loot {
return true;
}
Plugin MetadataList::FindPlugin(const std::string& name) const {
auto it = std::find(plugins.begin(), plugins.end(), Plugin(name));
if (it != plugins.end())
return *it;
else
return Plugin(name);
}
// Masterlist member functions
//----------------------------
@@ -752,11 +743,10 @@ namespace loot {
BOOST_LOG_TRIVIAL(info) << "Merging masterlist, userlist into plugin list, evaluating conditions and checking for install validity.";
for (const auto &plugin : this->plugins) {
vertex_t v = boost::add_vertex(plugin.second, graph);
list<loot::Plugin>::iterator pos;
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.
pos = std::find(this->masterlist.plugins.begin(), this->masterlist.plugins.end(), graph[v]);
auto pos = this->masterlist.plugins.find(graph[v]);
if (pos != this->masterlist.plugins.end()) {
BOOST_LOG_TRIVIAL(trace) << "Merging masterlist data down to plugin list data.";
@@ -764,7 +754,7 @@ namespace loot {
}
//Check if there is a plugin entry in the userlist. This will also find matching regex entries.
pos = std::find(this->userlist.plugins.begin(), this->userlist.plugins.end(), graph[v]);
pos = this->userlist.plugins.find(graph[v]);
if (pos != this->userlist.plugins.end() && pos->Enabled()) {
BOOST_LOG_TRIVIAL(trace) << "Merging userlist data down to plugin list data.";
+1 -3
View File
@@ -61,9 +61,7 @@ namespace loot {
bool operator == (const MetadataList& rhs) const; //Compares content.
Plugin FindPlugin(const std::string& name) const;
std::list<Plugin> plugins;
std::unordered_set<Plugin, plugin_hash> plugins;
std::list<Message> messages;
};
+12
View File
@@ -30,6 +30,7 @@
#include <string>
#include <list>
#include <unordered_set>
#include <boost/filesystem.hpp>
namespace YAML {
@@ -44,6 +45,17 @@ namespace YAML {
return out;
}
template<class T, class Hash>
Emitter& operator << (Emitter& out, const std::unordered_set<T, Hash>& rhs) {
out << BeginSeq;
for (const auto &element : rhs) {
out << element;
}
out << EndSeq;
return out;
}
Emitter& operator << (Emitter& out, const loot::PluginDirtyInfo& rhs);
Emitter& operator << (Emitter& out, const loot::Game& rhs);
+4 -2
View File
@@ -431,9 +431,11 @@ namespace loot {
try {
this->MetadataList::Load(game.MasterlistPath());
for (auto &plugin: plugins) {
plugin.EvalAllConditions(game, language);
unordered_set<Plugin, plugin_hash> tempSet;
for (auto &plugin : plugins) {
tempSet.insert(Plugin(plugin).EvalAllConditions(game, language));
}
plugins = tempSet;
for (auto &message: messages) {
message.EvalCondition(game, language);
+4 -2
View File
@@ -573,7 +573,7 @@ namespace loot {
_dirtyInfo = dirtyInfo;
}
void Plugin::EvalAllConditions(loot::Game& game, const unsigned int language) {
Plugin& Plugin::EvalAllConditions(loot::Game& game, const unsigned int language) {
for (auto it = loadAfter.begin(); it != loadAfter.end();) {
if (!it->EvalCondition(game))
loadAfter.erase(it++);
@@ -629,6 +629,8 @@ namespace loot {
else
++it;
}
return *this;
}
bool Plugin::HasNameOnly() const {
@@ -798,7 +800,7 @@ namespace loot {
size_t plugin_hash::operator () (const Plugin& p) const {
size_t seed = 0;
boost::hash_combine(seed, p.Name());
boost::hash_combine(seed, boost::locale::to_lower(p.Name()));
return seed;
}
+1 -1
View File
@@ -202,7 +202,7 @@ namespace loot {
void Tags(const std::set<Tag>& tags);
void DirtyInfo(const std::set<PluginDirtyInfo>& info);
void EvalAllConditions(loot::Game& game, const unsigned int language);
Plugin& EvalAllConditions(loot::Game& game, const unsigned int language);
bool HasNameOnly() const;
bool IsRegexPlugin() const;
bool LoadsBSA(const Game& game) const;
+23
View File
@@ -315,6 +315,29 @@ namespace YAML {
}
};
template<class T, class Hash>
struct convert< std::unordered_set<T, Hash> > {
static Node encode(const std::unordered_set<T, Hash>& rhs) {
Node node;
for (const auto &element : rhs) {
node.push_back(element);
}
return node;
}
static bool decode(const Node& node, std::unordered_set<T, Hash>& rhs) {
if (!node.IsSequence())
return false;
rhs.clear();
for (const auto &element : node) {
rhs.insert(element.as<T>());
}
return true;
}
};
template<>
struct convert<loot::Plugin> {
static Node encode(const loot::Plugin& rhs) {
+42 -13
View File
@@ -381,8 +381,15 @@ namespace loot {
BOOST_LOG_TRIVIAL(debug) << "Copying metadata for plugin " << pluginName;
// Get metadata from masterlist and userlist.
Plugin plugin = g_app_state.CurrentGame().masterlist.FindPlugin(pluginName);
plugin.MergeMetadata(g_app_state.CurrentGame().userlist.FindPlugin(pluginName));
Plugin plugin;
auto it = g_app_state.CurrentGame().masterlist.plugins.find(pluginName);
if (it != g_app_state.CurrentGame().masterlist.plugins.end()) {
plugin = *it;
}
it = g_app_state.CurrentGame().userlist.plugins.find(pluginName);
if (it != g_app_state.CurrentGame().userlist.plugins.end()) {
plugin.MergeMetadata(*it);
}
// Generate text representation.
string text;
@@ -405,7 +412,7 @@ namespace loot {
std::string Handler::ClearPluginMetadata(const std::string& pluginName) {
BOOST_LOG_TRIVIAL(debug) << "Clearing user metadata for plugin " << pluginName;
auto ulistPluginIt = find(g_app_state.CurrentGame().userlist.plugins.begin(), g_app_state.CurrentGame().userlist.plugins.end(), Plugin(pluginName));
auto ulistPluginIt = g_app_state.CurrentGame().userlist.plugins.find(Plugin(pluginName));
if (ulistPluginIt != g_app_state.CurrentGame().userlist.plugins.end()) {
g_app_state.CurrentGame().userlist.plugins.erase(ulistPluginIt);
@@ -439,7 +446,7 @@ namespace loot {
Plugin newUserlistEntry(pluginMetadata["name"].as<string>());
// Find existing userlist entry.
auto ulistPluginIt = find(g_app_state.CurrentGame().userlist.plugins.begin(), g_app_state.CurrentGame().userlist.plugins.end(), newUserlistEntry);
auto ulistPluginIt = g_app_state.CurrentGame().userlist.plugins.find(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.";
@@ -491,12 +498,15 @@ namespace loot {
BOOST_LOG_TRIVIAL(trace) << "Replacing existing userlist entry with new metadata.";
if (newUserlistEntry.HasNameOnly())
g_app_state.CurrentGame().userlist.plugins.erase(ulistPluginIt);
else
*ulistPluginIt = newUserlistEntry;
else {
// Set members are static, so just erase and add the new data.
g_app_state.CurrentGame().userlist.plugins.erase(ulistPluginIt);
g_app_state.CurrentGame().userlist.plugins.insert(newUserlistEntry);
}
}
else {
BOOST_LOG_TRIVIAL(trace) << "Adding new metadata to new userlist entry.";
g_app_state.CurrentGame().userlist.plugins.push_back(newUserlistEntry);
g_app_state.CurrentGame().userlist.plugins.insert(newUserlistEntry);
}
// Now rederive the derived metadata.
@@ -641,11 +651,17 @@ namespace loot {
// description as part of it.
BOOST_LOG_TRIVIAL(trace) << "Getting masterlist metadata for: " << plugin.Name();
Plugin mlistPlugin(plugin);
mlistPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(plugin.Name()));
auto it = g_app_state.CurrentGame().masterlist.plugins.find(plugin.Name());
if (it != g_app_state.CurrentGame().masterlist.plugins.end()) {
mlistPlugin.MergeMetadata(*it);
}
// Now do the same again for any userlist data.
BOOST_LOG_TRIVIAL(trace) << "Getting userlist metadata for: " << plugin.Name();
Plugin ulistPlugin(g_app_state.CurrentGame().userlist.FindPlugin(plugin.Name()));
Plugin ulistPlugin;
it = g_app_state.CurrentGame().userlist.plugins.find(plugin.Name());
if (it != g_app_state.CurrentGame().userlist.plugins.end()) {
ulistPlugin = *it;
}
pluginNode["__type"] = "Plugin"; // For conversion back into a JS typed object.
pluginNode["name"] = plugin.Name();
@@ -762,7 +778,10 @@ namespace loot {
for (const auto& pluginPair : g_app_state.CurrentGame().plugins) {
Plugin mlistPlugin(pluginPair.second);
mlistPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(pluginPair.second.Name()));
auto it = g_app_state.CurrentGame().masterlist.plugins.find(pluginPair.second);
if (it != g_app_state.CurrentGame().masterlist.plugins.end()) {
mlistPlugin.MergeMetadata(*it);
}
YAML::Node pluginNode;
if (!mlistPlugin.HasNameOnly()) {
@@ -916,8 +935,18 @@ namespace loot {
auto pluginIt = g_app_state.CurrentGame().plugins.find(boost::locale::to_lower(pluginName));
if (pluginIt != g_app_state.CurrentGame().plugins.end()) {
const Plugin master = g_app_state.CurrentGame().masterlist.FindPlugin(pluginIt->second.Name());
const Plugin user = g_app_state.CurrentGame().userlist.FindPlugin(pluginIt->second.Name());
Plugin master;
Plugin user;
auto it = g_app_state.CurrentGame().masterlist.plugins.find(pluginIt->second.Name());
if (it != g_app_state.CurrentGame().masterlist.plugins.end()) {
master = *it;
}
it = g_app_state.CurrentGame().userlist.plugins.find(pluginIt->second.Name());
if (it != g_app_state.CurrentGame().userlist.plugins.end()) {
user = *it;
}
return this->GenerateDerivedMetadata(pluginIt->second, master, user);
}