mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Remove plugin priorities
This commit is contained in:
@@ -174,7 +174,6 @@ set (LOOT_API_SRC "${CMAKE_BINARY_DIR}/generated/loot_version.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/metadata/message_content.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/metadata/plugin_cleaning_data.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/metadata/plugin_metadata.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/metadata/priority.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/metadata/tag.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/game/game.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/game/game_cache.cpp"
|
||||
@@ -212,7 +211,6 @@ set (LOOT_API_HEADERS "${CMAKE_SOURCE_DIR}/include/loot/api.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/metadata/message_content.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/metadata/plugin_cleaning_data.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/metadata/plugin_metadata.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/metadata/priority.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/metadata/tag.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/plugin_interface.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/struct/masterlist_info.h"
|
||||
@@ -263,7 +261,6 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/api/internals/game/game_t
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/message_content_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/plugin_cleaning_data_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/plugin_metadata_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/priority_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/tag_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/plugin_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/sorting/group_sort_test.h"
|
||||
|
||||
@@ -75,9 +75,6 @@ Classes
|
||||
.. doxygenclass:: loot::PluginMetadata
|
||||
:members:
|
||||
|
||||
.. doxygenclass:: loot::Priority
|
||||
:members:
|
||||
|
||||
.. doxygenclass:: loot::Tag
|
||||
:members:
|
||||
|
||||
|
||||
@@ -52,31 +52,6 @@ the group-derived plugin to the plugin would cause a cycle, and if not the edge
|
||||
is recorded. Once all potential edges have been checked, the recorded edges are
|
||||
added to the graph.
|
||||
|
||||
At this point, all explicit interdependencies have been graphed. Plugin priority
|
||||
metadata values must now be propagated down the dependency trees to ensure that
|
||||
priority edges are added correctly later in the process. To do this:
|
||||
|
||||
1. Create a list of all vertices with a global or non-global priority value
|
||||
greater than zero.
|
||||
2. Sort the list in order of decreasing priority value.
|
||||
3. For each vertex, perform a depth-first search, setting priorities at each
|
||||
vertex visited until equal or larger values are encountered.
|
||||
|
||||
Now that the priorities have been propagated, the priority edges can be added.
|
||||
For each plugin, if it has a global priority value of zero, overrides no records
|
||||
and loads no archive, skip it, otherwise iterate over all other plugins and:
|
||||
|
||||
* If the other plugin's global and non-global priority values equal the
|
||||
plugin's own values, or if both plugins have a global priority of zero and
|
||||
have no FormIDs in common, skip the other plugin.
|
||||
* Otherwise, add an edge from the plugin with lower global priority to the
|
||||
plugin with higher global priority, if that edge does not cause a cycle. A
|
||||
cycle is caused if a circular dependency is introduced, for example for two
|
||||
vertices A and B, A -> B -> A is a cycle.
|
||||
|
||||
If the global priorities are equal, compare the non-global priorities
|
||||
instead.
|
||||
|
||||
Plugin overlap edges are then added. Two plugins overlap if they contain the
|
||||
same FormID, i.e. if they both edit the same record or if one edits a record the
|
||||
other plugin adds.
|
||||
|
||||
@@ -53,24 +53,6 @@ This is the structure that brings all the others together, and forms the main co
|
||||
dependency when combined in isolation with the third rule, but having all
|
||||
three rules applied causes a cycle.
|
||||
|
||||
.. describe:: priority
|
||||
|
||||
``integer``
|
||||
|
||||
Modifies plugin position relative to others that change one or more of the same records, but which are otherwise unrelated (ie. neither plugin lists the other as a master, requirement, or in its ``after`` list). Plugins that don't change any of the same records are not compared, unless one of the plugins contains only a header record.
|
||||
|
||||
A plugin with a higher ``priority`` value will load after a plugin with a lower ``priority`` value. The value can be anything in the range ``-127`` to ``127`` inclusive, and if unspecified defaults to ``0``.
|
||||
|
||||
.. describe:: global_priority
|
||||
|
||||
``integer``
|
||||
|
||||
Modifies plugin position relative to all unrelated plugins (ie. neither plugin lists the other as a master, requirement, or in its ``after`` list).
|
||||
|
||||
A plugin with a higher ``global_priority`` value will load after a plugin with a lower priority value. The value can be anything in the range ``-127`` to ``127`` inclusive, and if unspecified defaults to ``0``.
|
||||
|
||||
``global_priority`` takes precedence over ``priority`` when comparing two plugins' priorities: the ``priority`` value is only compared if the two plugins have the same ``global_priority`` value.
|
||||
|
||||
.. describe:: after
|
||||
|
||||
``file set``
|
||||
@@ -138,8 +120,6 @@ Key Merge Behaviour (merging B into A)
|
||||
name Not merged.
|
||||
enabled Replaced by B's value.
|
||||
group Replaced by B's value.
|
||||
priority Replaced by B's value, unless that value is ``0`` and it was not explicitly set.
|
||||
global_priority Replaced by B's value, unless that value is ``0`` and it was not explicitly set.
|
||||
after Merged. If B's file set contains an item that is equal to one already present in A's file set, B's item is discarded.
|
||||
req Merged. If B's file set contains an item that is equal to one already present in A's file set, B's item is discarded.
|
||||
inc Merged. If B's file set contains an item that is equal to one already present in A's file set, B's item is discarded.
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "loot/metadata/location.h"
|
||||
#include "loot/metadata/message.h"
|
||||
#include "loot/metadata/plugin_cleaning_data.h"
|
||||
#include "loot/metadata/priority.h"
|
||||
#include "loot/metadata/tag.h"
|
||||
|
||||
namespace loot {
|
||||
@@ -64,10 +63,9 @@ public:
|
||||
* Merge metadata from the given PluginMetadata object into this object.
|
||||
*
|
||||
* If an equal metadata object already exists in this PluginMetadata object,
|
||||
* it is not duplicated. This object's priorities are replaced if the given
|
||||
* PluginMetadata object's priorities are explicit. This object's enabled
|
||||
* state is replaced by the given object's state. This object's group is
|
||||
* replaced by the given object's group if the latter is explicit.
|
||||
* it is not duplicated. This object's enabled state is replaced by the given
|
||||
* object's state. This object's group is replaced by the given object's group
|
||||
* if the latter is explicit.
|
||||
* @param plugin
|
||||
* The plugin metadata to merge.
|
||||
*/
|
||||
@@ -80,10 +78,7 @@ public:
|
||||
* The PluginMetadata object to compare against.
|
||||
* @return A PluginMetadata object containing the metadata in this object that
|
||||
* is not in the given object. The returned object inherits this
|
||||
* object's enabled state and group. The returned object also inherits
|
||||
* this plugin's priorities, unless a priority is equal to the given
|
||||
* object's priority, in which case the returned object is given
|
||||
* an implicit zero priority instead.
|
||||
* object's enabled state and group.
|
||||
*/
|
||||
LOOT_API PluginMetadata NewMetadata(const PluginMetadata& plugin) const;
|
||||
|
||||
@@ -118,18 +113,6 @@ public:
|
||||
*/
|
||||
LOOT_API bool IsGroupExplicit() const;
|
||||
|
||||
/**
|
||||
* Get the plugin's local priority metadata.
|
||||
* @return The plugin's local priority metadata.
|
||||
*/
|
||||
LOOT_API Priority GetLocalPriority() const;
|
||||
|
||||
/**
|
||||
* Get the plugin's global priority metadata.
|
||||
* @return The plugin's global priority metadata.
|
||||
*/
|
||||
LOOT_API Priority GetGlobalPriority() const;
|
||||
|
||||
/**
|
||||
* Get the plugins that the plugin must load after.
|
||||
* @return The plugins that the plugin must load after.
|
||||
@@ -201,20 +184,6 @@ public:
|
||||
*/
|
||||
LOOT_API void SetGroup(const std::string& group);
|
||||
|
||||
/**
|
||||
* Set the plugin's local priority.
|
||||
* @param priority
|
||||
* The value to set.
|
||||
*/
|
||||
LOOT_API void SetLocalPriority(const Priority& priority);
|
||||
|
||||
/**
|
||||
* Set the plugin's local priority.
|
||||
* @param priority
|
||||
* The value to set.
|
||||
*/
|
||||
LOOT_API void SetGlobalPriority(const Priority& priority);
|
||||
|
||||
/**
|
||||
* Set the files that the plugin must load after.
|
||||
* @param after
|
||||
@@ -273,8 +242,8 @@ public:
|
||||
|
||||
/**
|
||||
* Check if no plugin metadata is set.
|
||||
* @return True if the group and local and global priorities are implicit and
|
||||
* the metadata containers are all empty, false otherwise.
|
||||
* @return True if the group is implicit and the metadata containers are all
|
||||
* empty, false otherwise.
|
||||
*/
|
||||
LOOT_API bool HasNameOnly() const;
|
||||
|
||||
@@ -320,8 +289,6 @@ private:
|
||||
bool enabled_;
|
||||
std::string group_;
|
||||
bool isGroupExplicit_;
|
||||
Priority localPriority_;
|
||||
Priority globalPriority_;
|
||||
std::set<File> loadAfter_;
|
||||
std::set<File> requirements_;
|
||||
std::set<File> incompatibilities_;
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/* LOOT
|
||||
|
||||
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
|
||||
Fallout: New Vegas.
|
||||
|
||||
Copyright (C) 2012-2016 WrinklyNinja
|
||||
|
||||
This file is part of LOOT.
|
||||
|
||||
LOOT is free software: you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
LOOT is distributed in the hope that it will
|
||||
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with LOOT. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LOOT_METADATA_PRIORITY
|
||||
#define LOOT_METADATA_PRIORITY
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "loot/api_decorator.h"
|
||||
|
||||
namespace loot {
|
||||
/**
|
||||
* Represents the priority of a plugin in the load order.
|
||||
*
|
||||
* Plugins have a default implicit priority of zero. Lower priority values cause
|
||||
* plugins to be loaded earlier, and higher priority values cause plugins to be
|
||||
* loaded later.
|
||||
*/
|
||||
class Priority {
|
||||
public:
|
||||
/**
|
||||
* Construct a Priority object with an implicit value of zero.
|
||||
* @return A Priority object.
|
||||
*/
|
||||
LOOT_API Priority();
|
||||
|
||||
// Take an int to prevent literals that are too large for one byte from
|
||||
// wrapping around to negative values.
|
||||
/**
|
||||
* Construct a Priority object with the given priority value.
|
||||
*
|
||||
* If the given value is zero, it is marked as being set explicitly. This
|
||||
* affects how priority metadata values get merged in PluginMetadata objects.
|
||||
* @param value
|
||||
* The priority value to set. The valid range of values is -127 to 127
|
||||
* inclusive, and values passed to the constructor that lie outside
|
||||
* this range are clamped. The input type is an int to avoid invalid
|
||||
* values from implicitly wrapping around.
|
||||
* @return A Priority object.
|
||||
*/
|
||||
LOOT_API explicit Priority(const int value);
|
||||
|
||||
/**
|
||||
* Get the stored priority value.
|
||||
* @return The priority value. While the valid value range fits in 8 bits,
|
||||
* a short is returned to avoid interpreting the value as a character.
|
||||
*/
|
||||
LOOT_API short GetValue() const;
|
||||
|
||||
/**
|
||||
* Check if the priority value is explicit or not.
|
||||
* @return Returns true if the value is non-zero or was explicitly set to
|
||||
* zero, and false otherwise.
|
||||
*/
|
||||
LOOT_API bool IsExplicit() const;
|
||||
|
||||
/**
|
||||
* Check if this Priority object is less than another.
|
||||
* @return True if this Priority object's value is less than the given
|
||||
* Priority object's value.
|
||||
*/
|
||||
LOOT_API bool operator<(const Priority& rhs) const;
|
||||
|
||||
/**
|
||||
* Check if this Priority object is greater than another.
|
||||
* @return True if this Priority object's value is greater than the given
|
||||
* Priority object's value, false otherwise.
|
||||
*/
|
||||
LOOT_API bool operator>(const Priority& rhs) const;
|
||||
|
||||
/**
|
||||
* Check if this Priority object is greater than or equal to another.
|
||||
* @return True if this Priority object's value is greater than or equal to
|
||||
* the given Priority object's value, false otherwise.
|
||||
*/
|
||||
LOOT_API bool operator>=(const Priority& rhs) const;
|
||||
|
||||
/**
|
||||
* Check if this Priority object is equal to another.
|
||||
* @return True if this Priority object's value is equal to the given
|
||||
* Priority object's value, false otherwise.
|
||||
*/
|
||||
LOOT_API bool operator==(const Priority& rhs) const;
|
||||
|
||||
/**
|
||||
* Check if this Priority object is greater than a given priority value.
|
||||
* @return True if this Priority object's value is greater than the given
|
||||
* value, false otherwise.
|
||||
*/
|
||||
LOOT_API bool operator>(const uint8_t rhs) const;
|
||||
|
||||
private:
|
||||
bool isExplicitZeroValue_;
|
||||
int8_t value_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -108,8 +108,6 @@ PluginMetadata ConditionEvaluator::evaluateAll(
|
||||
|
||||
PluginMetadata evaluatedMetadata(pluginMetadata.GetName());
|
||||
evaluatedMetadata.SetEnabled(pluginMetadata.IsEnabled());
|
||||
evaluatedMetadata.SetLocalPriority(pluginMetadata.GetLocalPriority());
|
||||
evaluatedMetadata.SetGlobalPriority(pluginMetadata.GetGlobalPriority());
|
||||
evaluatedMetadata.SetLocations(pluginMetadata.GetLocations());
|
||||
|
||||
if (pluginMetadata.IsGroupExplicit()) {
|
||||
|
||||
@@ -40,9 +40,9 @@ using std::set;
|
||||
using std::vector;
|
||||
|
||||
namespace loot {
|
||||
PluginMetadata::PluginMetadata() :
|
||||
enabled_(true),
|
||||
group_("default"),
|
||||
PluginMetadata::PluginMetadata() :
|
||||
enabled_(true),
|
||||
group_("default"),
|
||||
isGroupExplicit_(false) {}
|
||||
|
||||
PluginMetadata::PluginMetadata(const std::string& n) :
|
||||
@@ -64,8 +64,8 @@ void PluginMetadata::MergeMetadata(const PluginMetadata& plugin) {
|
||||
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.
|
||||
// For 'enabled' and 'group' metadata, use the given plugin's values,
|
||||
// but if the 'group' value is not explicit, ignore it.
|
||||
enabled_ = plugin.IsEnabled();
|
||||
|
||||
if (plugin.IsGroupExplicit()) {
|
||||
@@ -73,14 +73,6 @@ void PluginMetadata::MergeMetadata(const PluginMetadata& plugin) {
|
||||
isGroupExplicit_ = true;
|
||||
}
|
||||
|
||||
if (plugin.localPriority_.IsExplicit()) {
|
||||
SetLocalPriority(plugin.localPriority_);
|
||||
}
|
||||
|
||||
if (plugin.globalPriority_.IsExplicit()) {
|
||||
SetGlobalPriority(plugin.globalPriority_);
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -202,10 +194,6 @@ bool PluginMetadata::IsGroupExplicit() const {
|
||||
return isGroupExplicit_;
|
||||
}
|
||||
|
||||
Priority PluginMetadata::GetLocalPriority() const { return localPriority_; }
|
||||
|
||||
Priority PluginMetadata::GetGlobalPriority() const { return globalPriority_; }
|
||||
|
||||
std::set<File> PluginMetadata::GetLoadAfterFiles() const { return loadAfter_; }
|
||||
|
||||
std::set<File> PluginMetadata::GetRequirements() const { return requirements_; }
|
||||
@@ -248,14 +236,6 @@ void PluginMetadata::SetGroup(const std::string& group) {
|
||||
isGroupExplicit_ = true;
|
||||
}
|
||||
|
||||
void PluginMetadata::SetLocalPriority(const Priority& priority) {
|
||||
localPriority_ = priority;
|
||||
}
|
||||
|
||||
void PluginMetadata::SetGlobalPriority(const Priority& priority) {
|
||||
globalPriority_ = priority;
|
||||
}
|
||||
|
||||
void PluginMetadata::SetLoadAfterFiles(const std::set<File>& l) {
|
||||
loadAfter_ = l;
|
||||
}
|
||||
@@ -288,8 +268,7 @@ void PluginMetadata::SetLocations(const std::set<Location>& locations) {
|
||||
}
|
||||
|
||||
bool PluginMetadata::HasNameOnly() const {
|
||||
return !IsGroupExplicit() && !localPriority_.IsExplicit() &&
|
||||
!globalPriority_.IsExplicit() &&
|
||||
return !IsGroupExplicit() &&
|
||||
loadAfter_.empty() && requirements_.empty() &&
|
||||
incompatibilities_.empty() && messages_.empty() && tags_.empty() &&
|
||||
dirtyInfo_.empty() && cleanInfo_.empty() && locations_.empty();
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/* LOOT
|
||||
|
||||
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
|
||||
Fallout: New Vegas.
|
||||
|
||||
Copyright (C) 2012-2016 WrinklyNinja
|
||||
|
||||
This file is part of LOOT.
|
||||
|
||||
LOOT is free software: you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
LOOT is distributed in the hope that it will
|
||||
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with LOOT. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "loot/metadata/priority.h"
|
||||
|
||||
namespace loot {
|
||||
Priority::Priority() : value_(0), isExplicitZeroValue_(false) {}
|
||||
|
||||
Priority::Priority(const int value) : isExplicitZeroValue_(true) {
|
||||
if (value > 127) {
|
||||
value_ = 127;
|
||||
} else if (value < -127) {
|
||||
value_ = -127;
|
||||
} else {
|
||||
value_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
short Priority::GetValue() const { return value_; }
|
||||
|
||||
bool Priority::IsExplicit() const {
|
||||
return value_ != 0 || isExplicitZeroValue_;
|
||||
}
|
||||
|
||||
bool Priority::operator<(const Priority& rhs) const {
|
||||
return value_ < rhs.value_;
|
||||
}
|
||||
|
||||
bool Priority::operator>(const Priority& rhs) const {
|
||||
return value_ > rhs.value_;
|
||||
}
|
||||
|
||||
bool Priority::operator>=(const Priority& rhs) const {
|
||||
return value_ >= rhs.value_;
|
||||
}
|
||||
|
||||
bool Priority::operator==(const Priority& rhs) const {
|
||||
return value_ == rhs.value_;
|
||||
}
|
||||
|
||||
bool Priority::operator>(const uint8_t rhs) const { return value_ > rhs; }
|
||||
}
|
||||
@@ -56,12 +56,6 @@ struct convert<loot::PluginMetadata> {
|
||||
if (rhs.IsGroupExplicit())
|
||||
node["group"] = rhs.GetGroup();
|
||||
|
||||
if (rhs.GetLocalPriority().IsExplicit())
|
||||
node["priority"] = rhs.GetLocalPriority().GetValue();
|
||||
|
||||
if (rhs.GetGlobalPriority().IsExplicit())
|
||||
node["global_priority"] = rhs.GetGlobalPriority().GetValue();
|
||||
|
||||
if (!rhs.GetLoadAfterFiles().empty())
|
||||
node["after"] = rhs.GetLoadAfterFiles();
|
||||
if (!rhs.GetRequirements().empty())
|
||||
@@ -112,16 +106,6 @@ struct convert<loot::PluginMetadata> {
|
||||
if (node["group"])
|
||||
rhs.SetGroup(node["group"].as<std::string>());
|
||||
|
||||
// Read priority values as int to prevent values that are too large from
|
||||
// being converted to -128.
|
||||
if (node["priority"]) {
|
||||
rhs.SetLocalPriority(loot::Priority(node["priority"].as<int>()));
|
||||
}
|
||||
|
||||
if (node["global_priority"]) {
|
||||
rhs.SetGlobalPriority(loot::Priority(node["global_priority"].as<int>()));
|
||||
}
|
||||
|
||||
if (node["after"])
|
||||
rhs.SetLoadAfterFiles(node["after"].as<std::set<loot::File>>());
|
||||
if (node["req"])
|
||||
@@ -170,15 +154,6 @@ inline Emitter& operator<<(Emitter& out, const loot::PluginMetadata& rhs) {
|
||||
if (rhs.IsGroupExplicit())
|
||||
out << Key << "group" << Value << YAML::SingleQuoted << rhs.GetGroup();
|
||||
|
||||
if (rhs.GetLocalPriority().IsExplicit()) {
|
||||
out << Key << "priority" << Value << rhs.GetLocalPriority().GetValue();
|
||||
}
|
||||
|
||||
if (rhs.GetGlobalPriority().IsExplicit()) {
|
||||
out << Key << "global_priority" << Value
|
||||
<< rhs.GetGlobalPriority().GetValue();
|
||||
}
|
||||
|
||||
if (!rhs.GetLoadAfterFiles().empty())
|
||||
out << Key << "after" << Value << rhs.GetLoadAfterFiles();
|
||||
|
||||
|
||||
@@ -134,13 +134,6 @@ std::vector<std::string> PluginSorter::Sort(Game& game) {
|
||||
|
||||
AddGroupEdges();
|
||||
|
||||
PropagatePriorities();
|
||||
|
||||
if (logger_) {
|
||||
logger_->debug("Adding priority edges.");
|
||||
}
|
||||
AddPriorityEdges();
|
||||
|
||||
if (logger_) {
|
||||
logger_->debug("Adding overlap edges.");
|
||||
}
|
||||
@@ -318,98 +311,6 @@ bool PluginSorter::EdgeCreatesCycle(const vertex_t& fromVertex,
|
||||
return false;
|
||||
}
|
||||
|
||||
void PluginSorter::PropagatePriorities() {
|
||||
/* If a plugin has a priority value > 0, that value should be
|
||||
inherited by all plugins that have edges coming from that
|
||||
plugin, ie. those that load after it, unless the plugin being
|
||||
compared itself has a larger value. */
|
||||
|
||||
// Find all vertices with priorities > 0.
|
||||
std::vector<vertex_t> positivePriorityVertices;
|
||||
vertex_it vit, vitend;
|
||||
tie(vit, vitend) = boost::vertices(graph_);
|
||||
std::copy_if(vit,
|
||||
vitend,
|
||||
std::back_inserter(positivePriorityVertices),
|
||||
[&](const vertex_t& vertex) {
|
||||
return graph_[vertex].GetLocalPriority() > 0 ||
|
||||
graph_[vertex].GetGlobalPriority() > 0;
|
||||
});
|
||||
|
||||
// To reduce the number of priorities that will need setting,
|
||||
// sort the vertices in order of decreasing priority.
|
||||
std::sort(begin(positivePriorityVertices),
|
||||
end(positivePriorityVertices),
|
||||
[&](const vertex_t& lhs, const vertex_t& rhs) {
|
||||
return graph_[lhs].GetLocalPriority() >
|
||||
graph_[rhs].GetLocalPriority() ||
|
||||
graph_[lhs].GetGlobalPriority() >
|
||||
graph_[rhs].GetGlobalPriority();
|
||||
});
|
||||
|
||||
// Create a color map.
|
||||
std::vector<boost::default_color_type> colorVec(num_vertices(graph_));
|
||||
boost::iterator_property_map<boost::default_color_type*, vertex_map_t>
|
||||
colorMap(&colorVec.front(), vertexIndexMap_);
|
||||
|
||||
// Now loop over the vertices. For each one, do a depth-first
|
||||
// search, setting priorities until an equal or larger value is
|
||||
// encountered.
|
||||
for (const vertex_t& vertex : positivePriorityVertices) {
|
||||
if (logger_) {
|
||||
logger_->trace(
|
||||
"Doing DFS for {} which has local priority {} and global priority {}",
|
||||
graph_[vertex].GetName(),
|
||||
graph_[vertex].GetLocalPriority().GetValue(),
|
||||
graph_[vertex].GetGlobalPriority().GetValue());
|
||||
}
|
||||
boost::dfs_visitor<> visitor;
|
||||
boost::depth_first_visit(
|
||||
graph_,
|
||||
vertex,
|
||||
visitor,
|
||||
colorMap,
|
||||
[&](const vertex_t& currentVertex, const PluginGraph& graph) {
|
||||
// depth_first_search takes a const graph, so cast it if modifying a
|
||||
// vertex.
|
||||
if (graph[currentVertex].GetLocalPriority() <
|
||||
graph[vertex].GetLocalPriority()) {
|
||||
if (logger_) {
|
||||
logger_->trace("Overriding local priority for {} from {} to {}",
|
||||
graph[currentVertex].GetName(),
|
||||
graph[currentVertex].GetLocalPriority().GetValue(),
|
||||
graph[vertex].GetLocalPriority().GetValue());
|
||||
}
|
||||
const_cast<PluginGraph&>(graph)[currentVertex].SetLocalPriority(
|
||||
graph[vertex].GetLocalPriority());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (graph[currentVertex].GetGlobalPriority() <
|
||||
graph[vertex].GetGlobalPriority()) {
|
||||
if (logger_) {
|
||||
logger_->trace(
|
||||
"Overriding global priority for {} from {} to {}",
|
||||
graph[currentVertex].GetName(),
|
||||
graph[currentVertex].GetGlobalPriority().GetValue(),
|
||||
graph[vertex].GetGlobalPriority().GetValue());
|
||||
}
|
||||
const_cast<PluginGraph&>(graph)[currentVertex].SetGlobalPriority(
|
||||
graph[vertex].GetGlobalPriority());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return currentVertex != vertex &&
|
||||
graph[currentVertex].GetLocalPriority() >=
|
||||
graph[vertex].GetLocalPriority() &&
|
||||
graph[currentVertex].GetGlobalPriority() >=
|
||||
graph[vertex].GetGlobalPriority();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void PluginSorter::AddEdge(const vertex_t& fromVertex,
|
||||
const vertex_t& toVertex) {
|
||||
if (!boost::edge(fromVertex, toVertex, graph_).second) {
|
||||
@@ -424,8 +325,7 @@ void PluginSorter::AddEdge(const vertex_t& fromVertex,
|
||||
}
|
||||
|
||||
void PluginSorter::AddSpecificEdges() {
|
||||
// Add edges for all relationships that aren't overlaps or priority
|
||||
// differences.
|
||||
// Add edges for all relationships that aren't overlaps.
|
||||
vertex_it vit, vitend;
|
||||
for (tie(vit, vitend) = boost::vertices(graph_); vit != vitend; ++vit) {
|
||||
if (logger_) {
|
||||
@@ -514,58 +414,6 @@ void PluginSorter::AddGroupEdges() {
|
||||
}
|
||||
}
|
||||
|
||||
void PluginSorter::AddPriorityEdges() {
|
||||
for (const auto& vertex :
|
||||
boost::make_iterator_range(boost::vertices(graph_))) {
|
||||
if (logger_) {
|
||||
logger_->trace("Adding priority difference edges to vertex for \"{}\".",
|
||||
graph_[vertex].GetName());
|
||||
}
|
||||
// If the plugin has a global priority of zero and doesn't load
|
||||
// an archive and has no override records, skip it. Plugins without
|
||||
// override records can only conflict with plugins that override
|
||||
// the records they add, so any edge necessary will be added when
|
||||
// evaluating that plugin.
|
||||
if (graph_[vertex].GetGlobalPriority().GetValue() == 0 &&
|
||||
graph_[vertex].NumOverrideFormIDs() == 0 &&
|
||||
!graph_[vertex].LoadsArchive()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto& otherVertex :
|
||||
boost::make_iterator_range(boost::vertices(graph_))) {
|
||||
// If the plugins have equal priority, or have non-global
|
||||
// priorities but don't conflict, don't add a priority edge.
|
||||
if ((graph_[vertex].GetLocalPriority() ==
|
||||
graph_[otherVertex].GetLocalPriority() &&
|
||||
graph_[vertex].GetGlobalPriority() ==
|
||||
graph_[otherVertex].GetGlobalPriority()) ||
|
||||
(graph_[vertex].GetGlobalPriority().GetValue() == 0 &&
|
||||
graph_[otherVertex].GetGlobalPriority().GetValue() == 0 &&
|
||||
!graph_[vertex].DoFormIDsOverlap(graph_[otherVertex]))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vertex_t toVertex, fromVertex;
|
||||
if (graph_[vertex].GetGlobalPriority() <
|
||||
graph_[otherVertex].GetGlobalPriority() ||
|
||||
(graph_[vertex].GetGlobalPriority() ==
|
||||
graph_[otherVertex].GetGlobalPriority() &&
|
||||
graph_[vertex].GetLocalPriority() <
|
||||
graph_[otherVertex].GetLocalPriority())) {
|
||||
fromVertex = vertex;
|
||||
toVertex = otherVertex;
|
||||
} else {
|
||||
fromVertex = otherVertex;
|
||||
toVertex = vertex;
|
||||
}
|
||||
|
||||
if (!EdgeCreatesCycle(fromVertex, toVertex))
|
||||
AddEdge(fromVertex, toVertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PluginSorter::AddOverlapEdges() {
|
||||
for (const auto& vertex :
|
||||
boost::make_iterator_range(boost::vertices(graph_))) {
|
||||
|
||||
@@ -57,12 +57,9 @@ private:
|
||||
int ComparePlugins(const std::string& plugin1,
|
||||
const std::string& plugin2) const;
|
||||
|
||||
void PropagatePriorities();
|
||||
|
||||
void AddPluginVertices(Game& game);
|
||||
void AddSpecificEdges();
|
||||
void AddGroupEdges();
|
||||
void AddPriorityEdges();
|
||||
void AddOverlapEdges();
|
||||
void AddTieBreakEdges();
|
||||
|
||||
|
||||
@@ -43,13 +43,9 @@ public:
|
||||
std::unordered_set<std::string> GetAfterGroupPlugins() const;
|
||||
void SetAfterGroupPlugins(std::unordered_set<std::string> plugins);
|
||||
|
||||
using PluginMetadata::GetGlobalPriority;
|
||||
using PluginMetadata::GetGroup;
|
||||
using PluginMetadata::GetLoadAfterFiles;
|
||||
using PluginMetadata::GetLocalPriority;
|
||||
using PluginMetadata::GetRequirements;
|
||||
using PluginMetadata::SetGlobalPriority;
|
||||
using PluginMetadata::SetLocalPriority;
|
||||
|
||||
private:
|
||||
const Plugin& plugin_;
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include "tests/api/internals/metadata/message_test.h"
|
||||
#include "tests/api/internals/metadata/plugin_cleaning_data_test.h"
|
||||
#include "tests/api/internals/metadata/plugin_metadata_test.h"
|
||||
#include "tests/api/internals/metadata/priority_test.h"
|
||||
#include "tests/api/internals/metadata/tag_test.h"
|
||||
#include "tests/api/internals/metadata_list_test.h"
|
||||
#include "tests/api/internals/sorting/group_sort_test.h"
|
||||
|
||||
@@ -133,7 +133,7 @@ TEST_P(PluginMetadataTest,
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin2.SetEnabled(false);
|
||||
plugin2.SetLocalPriority(Priority(5));
|
||||
plugin2.SetGroup("group1");
|
||||
ASSERT_FALSE(plugin2.HasNameOnly());
|
||||
plugin1.MergeMetadata(plugin2);
|
||||
|
||||
@@ -161,78 +161,6 @@ TEST_P(PluginMetadataTest, mergeMetadataShouldNotUseMergedGroupIfItIsImplicit) {
|
||||
EXPECT_EQ("group1", plugin1.GetGroup());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
mergeMetadataShouldUseMergedNonZeroLocalPriorityValue) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin1.SetLocalPriority(Priority(5));
|
||||
plugin2.SetLocalPriority(Priority(3));
|
||||
plugin1.MergeMetadata(plugin2);
|
||||
|
||||
EXPECT_EQ(3, plugin1.GetLocalPriority().GetValue());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
mergeMetadataShouldUseMergedNonZeroGlobalPriorityValue) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin1.SetGlobalPriority(Priority(5));
|
||||
plugin2.SetGlobalPriority(Priority(3));
|
||||
plugin1.MergeMetadata(plugin2);
|
||||
|
||||
EXPECT_EQ(3, plugin1.GetGlobalPriority().GetValue());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
mergeMetadataShouldNotUseImplicitZeroLocalPriorityValue) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin1.SetLocalPriority(Priority(5));
|
||||
plugin1.MergeMetadata(plugin2);
|
||||
|
||||
EXPECT_EQ(5, plugin1.GetLocalPriority().GetValue());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
mergeMetadataShouldNotUseImplicitZeroGlobalPriorityValue) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin1.SetGlobalPriority(Priority(5));
|
||||
plugin1.MergeMetadata(plugin2);
|
||||
|
||||
EXPECT_EQ(5, plugin1.GetGlobalPriority().GetValue());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
mergeMetadataShouldMergeAnExplicitLocalPriorityValueOfZero) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin1.SetLocalPriority(Priority(5));
|
||||
plugin2.SetLocalPriority(Priority(0));
|
||||
plugin1.MergeMetadata(plugin2);
|
||||
|
||||
EXPECT_EQ(0, plugin1.GetLocalPriority().GetValue());
|
||||
EXPECT_TRUE(plugin1.GetLocalPriority().IsExplicit());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
mergeMetadataShouldMergeAnExplicitGlobalPriorityValueOfZero) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin1.SetGlobalPriority(Priority(5));
|
||||
plugin2.SetGlobalPriority(Priority(0));
|
||||
plugin1.MergeMetadata(plugin2);
|
||||
|
||||
EXPECT_EQ(0, plugin1.GetGlobalPriority().GetValue());
|
||||
EXPECT_TRUE(plugin1.GetGlobalPriority().IsExplicit());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest, mergeMetadataShouldMergeLoadAfterData) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
@@ -362,26 +290,6 @@ TEST_P(PluginMetadataTest, newMetadataShouldUseSourcePluginEnabledState) {
|
||||
EXPECT_FALSE(newMetadata.IsEnabled());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest, newMetadataShouldUseSourcePluginLocalPriority) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin1.SetLocalPriority(Priority(5));
|
||||
PluginMetadata newMetadata = plugin1.NewMetadata(plugin2);
|
||||
|
||||
EXPECT_EQ(5, newMetadata.GetLocalPriority().GetValue());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest, newMetadataShouldUseSourcePluginGlobalPriority) {
|
||||
PluginMetadata plugin1;
|
||||
PluginMetadata plugin2;
|
||||
|
||||
plugin1.SetGlobalPriority(Priority(5));
|
||||
PluginMetadata newMetadata = plugin1.NewMetadata(plugin2);
|
||||
|
||||
EXPECT_EQ(5, newMetadata.GetGlobalPriority().GetValue());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
newMetadataShouldOutputLoadAfterDataThatAreNotCommonToBothInputPlugins) {
|
||||
PluginMetadata plugin1;
|
||||
@@ -560,22 +468,6 @@ TEST_P(PluginMetadataTest,
|
||||
EXPECT_FALSE(plugin.HasNameOnly());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
hasNameOnlyShouldBeFalseIfTheLocalPriorityIsExplicit) {
|
||||
PluginMetadata plugin(blankEsp);
|
||||
plugin.SetLocalPriority(Priority(0));
|
||||
|
||||
EXPECT_FALSE(plugin.HasNameOnly());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
hasNameOnlyShouldBeFalseIfTheGlobalPriorityIsExplicit) {
|
||||
PluginMetadata plugin(blankEsp);
|
||||
plugin.SetGlobalPriority(Priority(0));
|
||||
|
||||
EXPECT_FALSE(plugin.HasNameOnly());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfLoadAfterMetadataExists) {
|
||||
PluginMetadata plugin(blankEsp);
|
||||
plugin.SetLoadAfterFiles({File(blankEsm)});
|
||||
@@ -694,7 +586,7 @@ TEST_P(PluginMetadataTest,
|
||||
emittingAsYamlShouldOutputAPluginOmittingAnImplicitGroup) {
|
||||
PluginMetadata plugin(blankEsm);
|
||||
plugin.SetLoadAfterFiles({ File(blankEsm) });
|
||||
|
||||
|
||||
YAML::Emitter emitter;
|
||||
emitter << plugin;
|
||||
|
||||
@@ -719,39 +611,11 @@ TEST_P(PluginMetadataTest,
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
emittingAsYamlShouldOutputAPluginWithAnExplicitLocalPriorityCorrectly) {
|
||||
PluginMetadata plugin(blankEsm);
|
||||
plugin.SetLocalPriority(Priority(0));
|
||||
|
||||
YAML::Emitter emitter;
|
||||
emitter << plugin;
|
||||
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esm'\n"
|
||||
"priority: 0",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
emittingAsYamlShouldOutputAPluginWithAnExplicitGlobalPriorityCorrectly) {
|
||||
PluginMetadata plugin(blankEsm);
|
||||
plugin.SetGlobalPriority(Priority(0));
|
||||
|
||||
YAML::Emitter emitter;
|
||||
emitter << plugin;
|
||||
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esm'\n"
|
||||
"global_priority: 0",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
PluginMetadataTest,
|
||||
emittingAsYamlShouldOutputAPluginThatIsDisabledAndIsNotNameOnlyCorrectly) {
|
||||
PluginMetadata plugin(blankEsm);
|
||||
plugin.SetGlobalPriority(Priority(0));
|
||||
plugin.SetGroup("group1");
|
||||
plugin.SetEnabled(false);
|
||||
|
||||
YAML::Emitter emitter;
|
||||
@@ -760,7 +624,7 @@ TEST_P(
|
||||
EXPECT_STREQ(
|
||||
"name: 'Blank.esm'\n"
|
||||
"enabled: false\n"
|
||||
"global_priority: 0",
|
||||
"group: 'group1'",
|
||||
emitter.c_str());
|
||||
}
|
||||
|
||||
@@ -908,7 +772,6 @@ TEST_P(PluginMetadataTest, encodingAsYamlShouldOmitAllUnsetFields) {
|
||||
|
||||
EXPECT_EQ(plugin.GetName(), node["name"].as<std::string>());
|
||||
EXPECT_FALSE(node["enabled"]);
|
||||
EXPECT_FALSE(node["priority"]);
|
||||
EXPECT_FALSE(node["after"]);
|
||||
EXPECT_FALSE(node["req"]);
|
||||
EXPECT_FALSE(node["inc"]);
|
||||
@@ -919,44 +782,6 @@ TEST_P(PluginMetadataTest, encodingAsYamlShouldOmitAllUnsetFields) {
|
||||
EXPECT_FALSE(node["url"]);
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
encodingAsYamlShouldSetPriorityFieldIfLocalPriorityIsExplicit) {
|
||||
PluginMetadata plugin(blankEsp);
|
||||
plugin.SetLocalPriority(Priority(0));
|
||||
YAML::Node node;
|
||||
node = plugin;
|
||||
|
||||
EXPECT_EQ(0, node["priority"].as<short>());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
encodingAsYamlShouldSetGlobalPriorityFieldIfGlobalPriorityIsExplicit) {
|
||||
PluginMetadata plugin(blankEsp);
|
||||
plugin.SetGlobalPriority(Priority(0));
|
||||
YAML::Node node;
|
||||
node = plugin;
|
||||
|
||||
EXPECT_EQ(0, node["global_priority"].as<short>());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
encodingAsYamlShouldNotSetPriorityFieldIfLocalPriorityIsImplicit) {
|
||||
PluginMetadata plugin(blankEsp);
|
||||
YAML::Node node;
|
||||
node = plugin;
|
||||
|
||||
EXPECT_FALSE(node["priority"]);
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
encodingAsYamlShouldNotSetPriorityFieldIfGlobalPriorityIsImplicit) {
|
||||
PluginMetadata plugin(blankEsp);
|
||||
YAML::Node node;
|
||||
node = plugin;
|
||||
|
||||
EXPECT_FALSE(node["global_priority"]);
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest, encodingAsYamlShouldSetEnabledFieldIfItIsFalse) {
|
||||
PluginMetadata plugin(blankEsp);
|
||||
plugin.SetEnabled(false);
|
||||
@@ -1042,24 +867,10 @@ TEST_P(PluginMetadataTest, encodingAsYamlShouldSetUrlFieldIfLocationsExist) {
|
||||
EXPECT_EQ(plugin.GetLocations(), node["url"].as<std::set<Location>>());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest,
|
||||
decodingFromYamlShouldSetDefaultPriorityValuesIfNoneAreSpecified) {
|
||||
YAML::Node node = YAML::Load("name: " + blankEsp);
|
||||
PluginMetadata plugin = node.as<PluginMetadata>();
|
||||
|
||||
EXPECT_EQ(blankEsp, plugin.GetName());
|
||||
EXPECT_EQ(0, plugin.GetLocalPriority().GetValue());
|
||||
EXPECT_FALSE(plugin.GetLocalPriority().IsExplicit());
|
||||
EXPECT_EQ(0, plugin.GetGlobalPriority().GetValue());
|
||||
EXPECT_FALSE(plugin.GetGlobalPriority().IsExplicit());
|
||||
}
|
||||
|
||||
TEST_P(PluginMetadataTest, decodingFromYamlShouldStoreAllGivenData) {
|
||||
YAML::Node node = YAML::Load(
|
||||
"name: 'Blank.esp'\n"
|
||||
"enabled: false\n"
|
||||
"priority: 5\n"
|
||||
"global_priority: 3\n"
|
||||
"after:\n"
|
||||
" - 'Blank.esm'\n"
|
||||
"req:\n"
|
||||
@@ -1084,8 +895,6 @@ TEST_P(PluginMetadataTest, decodingFromYamlShouldStoreAllGivenData) {
|
||||
PluginMetadata plugin = node.as<PluginMetadata>();
|
||||
|
||||
EXPECT_EQ("Blank.esp", plugin.GetName());
|
||||
EXPECT_EQ(5, plugin.GetLocalPriority().GetValue());
|
||||
EXPECT_EQ(3, plugin.GetGlobalPriority().GetValue());
|
||||
EXPECT_EQ(std::set<File>({File("Blank.esm")}), plugin.GetLoadAfterFiles());
|
||||
EXPECT_EQ(std::set<File>({File("Blank.esm")}), plugin.GetRequirements());
|
||||
EXPECT_EQ(std::set<File>({File("Blank.esm")}), plugin.GetIncompatibilities());
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/* LOOT
|
||||
|
||||
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
|
||||
Fallout: New Vegas.
|
||||
|
||||
Copyright (C) 2014-2016 WrinklyNinja
|
||||
|
||||
This file is part of LOOT.
|
||||
|
||||
LOOT is free software: you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
LOOT is distributed in the hope that it will
|
||||
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with LOOT. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_PRIORITY_TEST
|
||||
#define LOOT_TESTS_API_INTERNALS_METADATA_PRIORITY_TEST
|
||||
|
||||
#include "loot/metadata/priority.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
TEST(Priority, defaultConstructorShouldInitialiseAnImplicitZeroPriority) {
|
||||
Priority priority;
|
||||
|
||||
EXPECT_EQ(0, priority.GetValue());
|
||||
EXPECT_FALSE(priority.IsExplicit());
|
||||
}
|
||||
|
||||
TEST(Priority, valueConstructorShouldInitialseAnExplicitValue) {
|
||||
Priority priority(0);
|
||||
|
||||
EXPECT_EQ(0, priority.GetValue());
|
||||
EXPECT_TRUE(priority.IsExplicit());
|
||||
|
||||
priority = Priority(5);
|
||||
|
||||
EXPECT_EQ(5, priority.GetValue());
|
||||
EXPECT_TRUE(priority.IsExplicit());
|
||||
}
|
||||
|
||||
TEST(Priority, valueConstructorTruncatesOutOfRangeValues) {
|
||||
EXPECT_EQ(127, Priority(127).GetValue());
|
||||
EXPECT_EQ(127, Priority(128).GetValue());
|
||||
|
||||
EXPECT_EQ(-127, Priority(-127).GetValue());
|
||||
EXPECT_EQ(-127, Priority(-128).GetValue());
|
||||
}
|
||||
|
||||
TEST(Priority, lessThanOperatorShouldCompareValues) {
|
||||
Priority priority1(1);
|
||||
Priority priority2(2);
|
||||
|
||||
EXPECT_TRUE(priority1 < priority2);
|
||||
EXPECT_FALSE(priority2 < priority1);
|
||||
|
||||
EXPECT_FALSE(priority1 < priority1);
|
||||
}
|
||||
|
||||
TEST(Priority, greaterThanOperatorShouldCompareValues) {
|
||||
Priority priority1(1);
|
||||
Priority priority2(2);
|
||||
|
||||
EXPECT_FALSE(priority1 > priority2);
|
||||
EXPECT_TRUE(priority2 > priority1);
|
||||
|
||||
EXPECT_FALSE(priority1 > priority1);
|
||||
}
|
||||
|
||||
TEST(Priority, greaterThanOrEqualToOperatorShouldCompareValues) {
|
||||
Priority priority1(1);
|
||||
Priority priority2(2);
|
||||
|
||||
EXPECT_FALSE(priority1 >= priority2);
|
||||
EXPECT_TRUE(priority2 >= priority1);
|
||||
|
||||
EXPECT_TRUE(priority1 >= priority1);
|
||||
}
|
||||
|
||||
TEST(Priority, equalityOperatorShouldCompareValues) {
|
||||
Priority priority1(1);
|
||||
Priority priority2(2);
|
||||
|
||||
EXPECT_FALSE(priority1 == priority2);
|
||||
EXPECT_FALSE(priority2 == priority1);
|
||||
|
||||
EXPECT_TRUE(priority1 == priority1);
|
||||
}
|
||||
|
||||
TEST(Priority, greaterThanUint8OperatorShouldCompareValue) {
|
||||
Priority priority1(1);
|
||||
Priority priority2(3);
|
||||
uint8_t value = 2;
|
||||
|
||||
EXPECT_FALSE(priority1 > value);
|
||||
EXPECT_TRUE(priority2 > value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -285,13 +285,13 @@ TEST_P(MetadataListTest, addPluginShouldStoreGivenSpecificPluginMetadata) {
|
||||
metadataList.FindPlugin(PluginMetadata(blankDifferentEsm)).HasNameOnly());
|
||||
|
||||
PluginMetadata plugin(blankDifferentEsm);
|
||||
plugin.SetLocalPriority(Priority(100));
|
||||
plugin.SetGroup("group1");
|
||||
metadataList.AddPlugin(plugin);
|
||||
|
||||
plugin = metadataList.FindPlugin(plugin);
|
||||
|
||||
EXPECT_EQ(blankDifferentEsm, plugin.GetName());
|
||||
EXPECT_EQ(100, plugin.GetLocalPriority().GetValue());
|
||||
EXPECT_EQ("group1", plugin.GetGroup());
|
||||
}
|
||||
|
||||
TEST_P(MetadataListTest, addPluginShouldStoreGivenRegexPluginMetadata) {
|
||||
@@ -299,12 +299,12 @@ TEST_P(MetadataListTest, addPluginShouldStoreGivenRegexPluginMetadata) {
|
||||
ASSERT_NO_THROW(metadataList.Load(metadataPath));
|
||||
|
||||
PluginMetadata plugin(".+Dependent\\.esp");
|
||||
plugin.SetLocalPriority(Priority(-10));
|
||||
plugin.SetGroup("group1");
|
||||
metadataList.AddPlugin(plugin);
|
||||
|
||||
plugin = metadataList.FindPlugin(PluginMetadata(blankPluginDependentEsp));
|
||||
|
||||
EXPECT_EQ(-10, plugin.GetLocalPriority().GetValue());
|
||||
EXPECT_EQ("group1", plugin.GetGroup());
|
||||
}
|
||||
|
||||
TEST_P(MetadataListTest, addPluginShouldThrowIfAMatchingPluginAlreadyExists) {
|
||||
|
||||
@@ -266,91 +266,6 @@ TEST_P(PluginSorterTest, sortingShouldIgnoreAGroupEdgeIfItWouldCauseACycle) {
|
||||
EXPECT_EQ(expectedSortedOrder, sorted);
|
||||
}
|
||||
|
||||
TEST_P(PluginSorterTest, sortingShouldEvaluateRelativeGlobalPriorities) {
|
||||
ASSERT_NO_THROW(loadInstalledPlugins(game_, false));
|
||||
PluginMetadata plugin(blankDifferentMasterDependentEsp);
|
||||
plugin.SetGlobalPriority(Priority(-100));
|
||||
game_.GetDatabase()->SetPluginUserMetadata(plugin);
|
||||
|
||||
PluginSorter ps;
|
||||
std::vector<std::string> expectedSortedOrder({
|
||||
masterFile,
|
||||
blankEsm,
|
||||
blankDifferentEsm,
|
||||
blankMasterDependentEsm,
|
||||
blankDifferentMasterDependentEsm,
|
||||
blankDifferentMasterDependentEsp,
|
||||
blankEsp,
|
||||
blankDifferentEsp,
|
||||
blankMasterDependentEsp,
|
||||
blankPluginDependentEsp,
|
||||
blankDifferentPluginDependentEsp,
|
||||
});
|
||||
|
||||
if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) {
|
||||
expectedSortedOrder.insert(expectedSortedOrder.begin() + 5, blankEsl);
|
||||
}
|
||||
|
||||
std::vector<std::string> sorted = ps.Sort(game_);
|
||||
EXPECT_EQ(expectedSortedOrder, sorted);
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
PluginSorterTest,
|
||||
sortingWithGlobalPrioritiesShouldInheritRecursivelyRegardlessOfEvaluationOrder) {
|
||||
ASSERT_NO_THROW(loadInstalledPlugins(game_, false));
|
||||
|
||||
// Set Blank.esp's priority.
|
||||
PluginMetadata plugin(blankEsp);
|
||||
plugin.SetGlobalPriority(Priority(2));
|
||||
game_.GetDatabase()->SetPluginUserMetadata(plugin);
|
||||
|
||||
// Load Blank - Master Dependent.esp after Blank.esp so that it
|
||||
// inherits Blank.esp's priority.
|
||||
plugin = PluginMetadata(blankMasterDependentEsp);
|
||||
plugin.SetLoadAfterFiles({
|
||||
File(blankEsp),
|
||||
});
|
||||
game_.GetDatabase()->SetPluginUserMetadata(plugin);
|
||||
|
||||
// Load Blank - Different.esp after Blank - Master Dependent.esp, so
|
||||
// that it inherits its inherited priority.
|
||||
plugin = PluginMetadata(blankDifferentEsp);
|
||||
plugin.SetLoadAfterFiles({
|
||||
File(blankMasterDependentEsp),
|
||||
});
|
||||
game_.GetDatabase()->SetPluginUserMetadata(plugin);
|
||||
|
||||
// Set Blank - Different Master Dependent.esp to have a higher priority
|
||||
// than 0 but lower than Blank.esp. Need to also make it a global priority
|
||||
// because it doesn't otherwise conflict with the other plugins.
|
||||
plugin = PluginMetadata(blankDifferentMasterDependentEsp);
|
||||
plugin.SetGlobalPriority(Priority(1));
|
||||
game_.GetDatabase()->SetPluginUserMetadata(plugin);
|
||||
|
||||
PluginSorter ps;
|
||||
std::vector<std::string> expectedSortedOrder({
|
||||
masterFile,
|
||||
blankEsm,
|
||||
blankDifferentEsm,
|
||||
blankMasterDependentEsm,
|
||||
blankDifferentMasterDependentEsm,
|
||||
blankDifferentMasterDependentEsp,
|
||||
blankEsp,
|
||||
blankMasterDependentEsp,
|
||||
blankDifferentEsp,
|
||||
blankPluginDependentEsp,
|
||||
blankDifferentPluginDependentEsp,
|
||||
});
|
||||
|
||||
if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) {
|
||||
expectedSortedOrder.insert(expectedSortedOrder.begin() + 5, blankEsl);
|
||||
}
|
||||
|
||||
std::vector<std::string> sorted = ps.Sort(game_);
|
||||
EXPECT_EQ(expectedSortedOrder, sorted);
|
||||
}
|
||||
|
||||
TEST_P(PluginSorterTest,
|
||||
sortingShouldUseLoadAfterMetadataWhenDecidingRelativePluginPositions) {
|
||||
ASSERT_NO_THROW(loadInstalledPlugins(game_, false));
|
||||
|
||||
Reference in New Issue
Block a user