diff --git a/src/backend/generators.h b/src/backend/generators.h index 4e8313d8..94029244 100644 --- a/src/backend/generators.h +++ b/src/backend/generators.h @@ -736,7 +736,7 @@ namespace YAML { out << BeginMap << Key << "name" << Value << rhs.Name(); - if (rhs.Priority() != 0) + if (rhs.IsPriorityExplicit()) out << Key << "priority" << Value << rhs.Priority(); if (!rhs.Enabled()) diff --git a/src/backend/metadata.cpp b/src/backend/metadata.cpp index 8a729620..e268694b 100644 --- a/src/backend/metadata.cpp +++ b/src/backend/metadata.cpp @@ -295,15 +295,15 @@ namespace boss { return _name; } - Plugin::Plugin() : enabled(true), priority(0), isMaster(false), crc(0), numOverrideRecords(0) {} - Plugin::Plugin(const std::string& n) : name(n), enabled(true), priority(0), isMaster(false), crc(0), numOverrideRecords(0) { + Plugin::Plugin() : enabled(true), priority(0), isMaster(false), crc(0), numOverrideRecords(0), _isPriorityExplicit(false) {} + Plugin::Plugin(const std::string& n) : name(n), enabled(true), priority(0), isMaster(false), crc(0), numOverrideRecords(0), _isPriorityExplicit(false) { //If the name passed ends in '.ghost', that should be trimmed. if (boost::iends_with(name, ".ghost")) name = name.substr(0, name.length() - 6); } Plugin::Plugin(boss::Game& game, const std::string& n, const bool headerOnly) - : name(n), enabled(true), priority(0), isMaster(false), crc(0), numOverrideRecords(0) { + : name(n), enabled(true), priority(0), isMaster(false), crc(0), numOverrideRecords(0), _isPriorityExplicit(false) { // Get data from file contents using libespm. Assumes libespm has already been initialised. BOOST_LOG_TRIVIAL(trace) << name << ": " << "Opening with libespm..."; @@ -403,10 +403,12 @@ namespace boss { void Plugin::MergeMetadata(const Plugin& plugin) { BOOST_LOG_TRIVIAL(trace) << "Merging metadata for: " << name; - //For 'enabled' and 'priority' metadata, use the given plugin's values, but if the 'priority' user value is zero, ignore it. + //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(); - if (plugin.Priority() != 0) + if (plugin.IsPriorityExplicit()) { priority = plugin.Priority(); + _isPriorityExplicit = true; + } //Merge the following. If any files in the source already exist in the destination, they will be skipped. Files have display strings and condition strings which aren't considered when comparing them, so will be lost if the plugin being merged in has additional data in these strings. std::set files = plugin.LoadAfter(); @@ -437,10 +439,15 @@ namespace boss { Plugin p(*this); p.Enabled(plugin.Enabled()); - if (priority != plugin.Priority()) + if (priority != plugin.Priority()) { p.Priority(plugin.Priority()); - else + p.SetPriorityExplicit(plugin.IsPriorityExplicit()); + } + else { p.Priority(0); + p.SetPriorityExplicit(false); + } + //Compare this plugin against the given plugin. set files = plugin.LoadAfter(); @@ -523,6 +530,10 @@ namespace boss { enabled = e; } + void Plugin::SetPriorityExplicit(bool state) { + _isPriorityExplicit = state; + } + void Plugin::Priority(const int p) { priority = p; } @@ -610,13 +621,17 @@ namespace boss { } bool Plugin::HasNameOnly() const { - return priority == 0 && enabled == true && loadAfter.empty() && requirements.empty() && incompatibilities.empty() && messages.empty() && tags.empty() && _dirtyInfo.empty(); + return !IsPriorityExplicit() && enabled == true && loadAfter.empty() && requirements.empty() && incompatibilities.empty() && messages.empty() && tags.empty() && _dirtyInfo.empty(); } bool Plugin::IsRegexPlugin() const { return boost::iends_with(name, "\\.esm") || boost::iends_with(name, "\\.esp"); } + bool Plugin::IsPriorityExplicit() const { + return priority != 0 || _isPriorityExplicit; + } + bool Plugin::operator == (const Plugin& rhs) const { return (boost::iequals(name, rhs.Name()) || (IsRegexPlugin() && boost::regex_match(rhs.Name(), boost::regex(name, boost::regex::perl|boost::regex::icase))) diff --git a/src/backend/metadata.h b/src/backend/metadata.h index 0b968503..2c4548d7 100644 --- a/src/backend/metadata.h +++ b/src/backend/metadata.h @@ -185,6 +185,7 @@ namespace boss { void Name(const std::string& name); void Enabled(const bool enabled); + void SetPriorityExplicit(bool state); void Priority(const int priority); void LoadAfter(const std::set& after); void Reqs(const std::set& reqs); @@ -197,6 +198,7 @@ namespace boss { bool HasNameOnly() const; bool IsRegexPlugin() const; bool LoadsBSA(const Game& game) const; + bool IsPriorityExplicit() const; //Compare name strings. bool operator == (const Plugin& rhs) const; @@ -214,6 +216,7 @@ namespace boss { private: std::string name; bool enabled; //Default to true. + bool _isPriorityExplicit; //If false and priority is 0, then priority was not explicitly set as such. int priority; //Default to 0 : >0 is lower down in load order, <0 is higher up. std::set loadAfter; std::set requirements; diff --git a/src/backend/parsers.h b/src/backend/parsers.h index 4c997808..fd473316 100644 --- a/src/backend/parsers.h +++ b/src/backend/parsers.h @@ -339,8 +339,10 @@ namespace YAML { if (node["enabled"]) rhs.Enabled(node["enabled"].as()); - if (node["priority"]) + if (node["priority"]) { rhs.Priority(node["priority"].as()); + rhs.SetPriorityExplicit(true); + } if (node["after"]) rhs.LoadAfter(node["after"].as< std::set >());