Split regex plugins into separate container.

Now they can get found correctly, they weren't getting matched in the
hashset. Timing puts having the hashset at about a half-second faster on
my computer than with just a list, so it is an improvement.
This commit is contained in:
WrinklyNinja
2014-08-26 11:53:48 +01:00
parent 805ccdf83e
commit a7fc173b9b
5 changed files with 91 additions and 61 deletions
+58 -11
View File
@@ -107,8 +107,15 @@ namespace loot {
YAML::Node metadataList = YAML::Load(in);
in.close();
if (metadataList["plugins"])
plugins = metadataList["plugins"].as< unordered_set<Plugin> >();
if (metadataList["plugins"]) {
for (const auto& node : metadataList["plugins"]) {
Plugin plugin(node.as<Plugin>());
if (plugin.IsRegexPlugin())
regexPlugins.push_back(plugin);
else
plugins.insert(plugin);
}
}
if (metadataList["globals"])
messages = metadataList["globals"].as< list<Message> >();
@@ -166,6 +173,50 @@ namespace loot {
return true;
}
std::list<Plugin> MetadataList::Plugins() const {
list<Plugin> pluginList(plugins.begin(), plugins.end());
pluginList.insert(pluginList.end(), regexPlugins.begin(), regexPlugins.end());
return pluginList;
}
Plugin MetadataList::FindPlugin(const Plugin& plugin) const {
auto it = plugins.find(plugin);
if (it != plugins.end())
return *it;
it = find(regexPlugins.begin(), regexPlugins.end(), plugin);
if (it != regexPlugins.end())
return *it;
else
return Plugin(plugin.Name());
}
void MetadataList::AddPlugin(const Plugin& plugin) {
if (plugin.IsRegexPlugin())
regexPlugins.push_back(plugin);
else
plugins.insert(plugin);
}
void MetadataList::ErasePlugin(const Plugin& plugin) {
auto it = plugins.find(plugin);
if (it != plugins.end()) {
plugins.erase(it);
return;
}
it = find(regexPlugins.begin(), regexPlugins.end(), plugin);
if (it != regexPlugins.end()) {
regexPlugins.erase(it);
}
}
// Masterlist member functions
//----------------------------
@@ -746,19 +797,15 @@ namespace loot {
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.
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.";
graph[v].MergeMetadata(*pos);
}
BOOST_LOG_TRIVIAL(trace) << "Merging masterlist data down to plugin list data.";
graph[v].MergeMetadata(this->masterlist.FindPlugin(graph[v]));
//Check if there is a plugin entry in the userlist. This will also find matching regex entries.
pos = this->userlist.plugins.find(graph[v]);
Plugin ulistPlugin = this->userlist.FindPlugin(graph[v]);
if (pos != this->userlist.plugins.end() && pos->Enabled()) {
if (!ulistPlugin.HasNameOnly() && ulistPlugin.Enabled()) {
BOOST_LOG_TRIVIAL(trace) << "Merging userlist data down to plugin list data.";
graph[v].MergeMetadata(*pos);
graph[v].MergeMetadata(ulistPlugin);
}
//Now that items are merged, evaluate any conditions they have.
+9 -1
View File
@@ -34,6 +34,7 @@
#include <unordered_set>
#include <boost/filesystem.hpp>
#include <boost/locale.hpp>
#include <api/libloadorder.h>
#include <src/libespm.h>
@@ -61,8 +62,15 @@ namespace loot {
bool operator == (const MetadataList& rhs) const; //Compares content.
std::unordered_set<Plugin> plugins;
std::list<Plugin> Plugins() const;
Plugin FindPlugin(const Plugin& plugin) const;
void AddPlugin(const Plugin& plugin);
void ErasePlugin(const Plugin& plugin);
std::list<Message> messages;
protected:
std::unordered_set<Plugin> plugins;
std::list<Plugin> regexPlugins;
};
class Masterlist : public MetadataList {
+3
View File
@@ -436,6 +436,9 @@ namespace loot {
tempSet.insert(Plugin(plugin).EvalAllConditions(game, language));
}
plugins = tempSet;
for (auto &plugin : regexPlugins) {
plugin.EvalAllConditions(game, language);
}
for (auto &message: messages) {
message.EvalCondition(game, language);
+2
View File
@@ -413,6 +413,8 @@ namespace loot {
void Plugin::MergeMetadata(const Plugin& plugin) {
BOOST_LOG_TRIVIAL(trace) << "Merging metadata for: " << name;
if (plugin.HasNameOnly())
return;
//For 'enabled' and 'priority' metadata, use the given plugin's values, but if the 'priority' user value is not explicit, ignore it.
enabled = plugin.Enabled();
+19 -49
View File
@@ -381,15 +381,8 @@ namespace loot {
BOOST_LOG_TRIVIAL(debug) << "Copying metadata for plugin " << pluginName;
// Get metadata from masterlist and userlist.
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);
}
Plugin plugin = g_app_state.CurrentGame().masterlist.FindPlugin(pluginName);
plugin.MergeMetadata(g_app_state.CurrentGame().userlist.FindPlugin(pluginName));
// Generate text representation.
string text;
@@ -412,11 +405,7 @@ namespace loot {
std::string Handler::ClearPluginMetadata(const std::string& pluginName) {
BOOST_LOG_TRIVIAL(debug) << "Clearing user metadata for 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);
}
g_app_state.CurrentGame().userlist.ErasePlugin(Plugin(pluginName));
// Now rederive the displayed metadata from the masterlist.
YAML::Node derivedMetadata = GenerateDerivedMetadata(pluginName);
@@ -446,7 +435,7 @@ namespace loot {
Plugin newUserlistEntry(pluginMetadata["name"].as<string>());
// Find existing userlist entry.
auto ulistPluginIt = g_app_state.CurrentGame().userlist.plugins.find(newUserlistEntry);
Plugin ulistPlugin = g_app_state.CurrentGame().userlist.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.";
@@ -467,9 +456,9 @@ namespace loot {
else {
// Priority value wasn't changed, use the existing userlist value.
BOOST_LOG_TRIVIAL(trace) << "Priority value is unchanged, using existing userlist value (if it exists).";
if (ulistPluginIt != g_app_state.CurrentGame().userlist.plugins.end()) {
newUserlistEntry.Priority(ulistPluginIt->Priority());
newUserlistEntry.SetPriorityExplicit(ulistPluginIt->IsPriorityExplicit());
if (!ulistPlugin.HasNameOnly()) {
newUserlistEntry.Priority(ulistPlugin.Priority());
newUserlistEntry.SetPriorityExplicit(ulistPlugin.IsPriorityExplicit());
}
}
@@ -494,19 +483,19 @@ namespace loot {
newUserlistEntry.DirtyInfo(pluginMetadata["userlist"]["dirty"].as<set<PluginDirtyInfo>>());
// Now replace existing userlist entry with the new one.
if (ulistPluginIt != g_app_state.CurrentGame().userlist.plugins.end()) {
if (!ulistPlugin.HasNameOnly()) {
BOOST_LOG_TRIVIAL(trace) << "Replacing existing userlist entry with new metadata.";
if (newUserlistEntry.HasNameOnly())
g_app_state.CurrentGame().userlist.plugins.erase(ulistPluginIt);
g_app_state.CurrentGame().userlist.ErasePlugin(ulistPlugin);
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);
g_app_state.CurrentGame().userlist.ErasePlugin(ulistPlugin);
g_app_state.CurrentGame().userlist.AddPlugin(newUserlistEntry);
}
}
else {
BOOST_LOG_TRIVIAL(trace) << "Adding new metadata to new userlist entry.";
g_app_state.CurrentGame().userlist.plugins.insert(newUserlistEntry);
g_app_state.CurrentGame().userlist.AddPlugin(newUserlistEntry);
}
// Now rederive the derived metadata.
@@ -651,17 +640,11 @@ namespace loot {
// description as part of it.
BOOST_LOG_TRIVIAL(trace) << "Getting masterlist metadata for: " << plugin.Name();
Plugin mlistPlugin(plugin);
auto it = g_app_state.CurrentGame().masterlist.plugins.find(plugin.Name());
if (it != g_app_state.CurrentGame().masterlist.plugins.end()) {
mlistPlugin.MergeMetadata(*it);
}
mlistPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(plugin));
// Now do the same again for any userlist data.
BOOST_LOG_TRIVIAL(trace) << "Getting userlist metadata for: " << 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;
}
Plugin ulistPlugin(g_app_state.CurrentGame().userlist.FindPlugin(plugin));
pluginNode["__type"] = "Plugin"; // For conversion back into a JS typed object.
pluginNode["name"] = plugin.Name();
@@ -778,10 +761,7 @@ namespace loot {
for (const auto& pluginPair : g_app_state.CurrentGame().plugins) {
Plugin mlistPlugin(pluginPair.second);
auto it = g_app_state.CurrentGame().masterlist.plugins.find(pluginPair.second);
if (it != g_app_state.CurrentGame().masterlist.plugins.end()) {
mlistPlugin.MergeMetadata(*it);
}
mlistPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(pluginPair.second));
YAML::Node pluginNode;
if (!mlistPlugin.HasNameOnly()) {
@@ -836,7 +816,7 @@ namespace loot {
BOOST_LOG_TRIVIAL(debug) << "Clearing all user metadata.";
// Record which plugins have userlist entries.
vector<string> userlistPlugins;
for (const auto &plugin : g_app_state.CurrentGame().userlist.plugins) {
for (const auto &plugin : g_app_state.CurrentGame().userlist.Plugins()) {
userlistPlugins.push_back(plugin.Name());
}
BOOST_LOG_TRIVIAL(trace) << "User metadata exists for " << userlistPlugins.size() << " plugins.";
@@ -935,18 +915,8 @@ namespace loot {
auto pluginIt = g_app_state.CurrentGame().plugins.find(boost::locale::to_lower(pluginName));
if (pluginIt != g_app_state.CurrentGame().plugins.end()) {
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;
}
Plugin master(g_app_state.CurrentGame().masterlist.FindPlugin(pluginIt->second));
Plugin user(g_app_state.CurrentGame().userlist.FindPlugin(pluginIt->second));
return this->GenerateDerivedMetadata(pluginIt->second, master, user);
}