From a7fc173b9b7d78546029e68f23ff62df08080852 Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Tue, 26 Aug 2014 11:53:48 +0100 Subject: [PATCH] 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. --- src/backend/game.cpp | 69 +++++++++++++++++++++++++++++++++------- src/backend/game.h | 10 +++++- src/backend/git.cpp | 3 ++ src/backend/metadata.cpp | 2 ++ src/gui/handler.cpp | 68 +++++++++++---------------------------- 5 files changed, 91 insertions(+), 61 deletions(-) diff --git a/src/backend/game.cpp b/src/backend/game.cpp index d1486017..097e8845 100644 --- a/src/backend/game.cpp +++ b/src/backend/game.cpp @@ -107,8 +107,15 @@ namespace loot { YAML::Node metadataList = YAML::Load(in); in.close(); - if (metadataList["plugins"]) - plugins = metadataList["plugins"].as< unordered_set >(); + if (metadataList["plugins"]) { + for (const auto& node : metadataList["plugins"]) { + Plugin plugin(node.as()); + if (plugin.IsRegexPlugin()) + regexPlugins.push_back(plugin); + else + plugins.insert(plugin); + } + } if (metadataList["globals"]) messages = metadataList["globals"].as< list >(); @@ -166,6 +173,50 @@ namespace loot { return true; } + std::list MetadataList::Plugins() const { + list 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. diff --git a/src/backend/game.h b/src/backend/game.h index 6996624c..e303002c 100644 --- a/src/backend/game.h +++ b/src/backend/game.h @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -61,8 +62,15 @@ namespace loot { bool operator == (const MetadataList& rhs) const; //Compares content. - std::unordered_set plugins; + std::list Plugins() const; + Plugin FindPlugin(const Plugin& plugin) const; + void AddPlugin(const Plugin& plugin); + void ErasePlugin(const Plugin& plugin); + std::list messages; + protected: + std::unordered_set plugins; + std::list regexPlugins; }; class Masterlist : public MetadataList { diff --git a/src/backend/git.cpp b/src/backend/git.cpp index a49b79cb..2c2b15d9 100644 --- a/src/backend/git.cpp +++ b/src/backend/git.cpp @@ -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); diff --git a/src/backend/metadata.cpp b/src/backend/metadata.cpp index 978a60df..c61dd678 100644 --- a/src/backend/metadata.cpp +++ b/src/backend/metadata.cpp @@ -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(); diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index a4a12315..f5273529 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -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()); // 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>()); // 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 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); }