diff --git a/include/loot/enum/edge_type.h b/include/loot/enum/edge_type.h index e81a7d5f..950cebb9 100644 --- a/include/loot/enum/edge_type.h +++ b/include/loot/enum/edge_type.h @@ -43,7 +43,8 @@ enum struct EdgeType : unsigned int { userLoadAfter, masterlistGroup, userGroup, - overlap, + recordOverlap, + assetOverlap, tieBreak, }; } diff --git a/src/api/sorting/plugin_graph.cpp b/src/api/sorting/plugin_graph.cpp index 6987e894..b1aac77a 100644 --- a/src/api/sorting/plugin_graph.cpp +++ b/src/api/sorting/plugin_graph.cpp @@ -215,8 +215,10 @@ std::string describeEdgeType(EdgeType edgeType) { return "Masterlist Group"; case EdgeType::userGroup: return "User Group"; - case EdgeType::overlap: - return "Overlap"; + case EdgeType::recordOverlap: + return "Record Overlap"; + case EdgeType::assetOverlap: + return "Asset Overlap"; case EdgeType::tieBreak: return "Tie Break"; default: @@ -549,6 +551,16 @@ std::optional> PluginGraph::FindPath( return visitor.GetPath(); } +std::optional PluginGraph::GetEdgeType(const vertex_t& fromVertex, + const vertex_t& toVertex) { + const auto edge = boost::edge(fromVertex, toVertex, graph_); + if (!edge.second) { + return std::nullopt; + } + + return graph_[edge.first]; +} + void PluginGraph::AddEdge(const vertex_t& fromVertex, const vertex_t& toVertex, EdgeType edgeType) { @@ -856,6 +868,7 @@ void PluginGraph::AddOverlapEdges() { // record counts are equal. auto thisPluginLoadsFirst = false; + EdgeType edgeType = EdgeType::recordOverlap; const auto otherPluginRecordCount = otherPlugin.GetOverrideRecordCount(); @@ -872,6 +885,7 @@ void PluginGraph::AddOverlapEdges() { continue; } else { thisPluginLoadsFirst = pluginAssetCount > otherPluginAssetCount; + edgeType = EdgeType::assetOverlap; } } else { // Records overlap and override different numbers of records. @@ -883,7 +897,14 @@ void PluginGraph::AddOverlapEdges() { const auto toVertex = thisPluginLoadsFirst ? otherVertex : vertex; if (!PathExists(toVertex, fromVertex)) { - AddEdge(fromVertex, toVertex, EdgeType::overlap); + AddEdge(fromVertex, toVertex, edgeType); + } else if (logger) { + logger->debug( + "Skipping {} edge from \"{}\" to \"{}\" as it would " + "create a cycle.", + describeEdgeType(edgeType), + GetPlugin(fromVertex).GetName(), + GetPlugin(toVertex).GetName()); } } } diff --git a/src/api/sorting/plugin_graph.h b/src/api/sorting/plugin_graph.h index 7bf8ea39..e2744fad 100644 --- a/src/api/sorting/plugin_graph.h +++ b/src/api/sorting/plugin_graph.h @@ -84,6 +84,8 @@ public: std::optional> FindPath(const vertex_t& fromVertex, const vertex_t& toVertex); + std::optional GetEdgeType(const vertex_t& fromVertex, + const vertex_t& toVertex); void AddEdge(const vertex_t& fromVertex, const vertex_t& toVertex, diff --git a/src/tests/api/internals/sorting/plugin_graph_test.h b/src/tests/api/internals/sorting/plugin_graph_test.h index 80da1934..9e72f77c 100644 --- a/src/tests/api/internals/sorting/plugin_graph_test.h +++ b/src/tests/api/internals/sorting/plugin_graph_test.h @@ -207,7 +207,7 @@ TEST_F( graph.AddOverlapEdges(); - EXPECT_TRUE(graph.EdgeExists(v1, v2)); + EXPECT_EQ(EdgeType::recordOverlap, graph.GetEdgeType(v1, v2).value()); EXPECT_FALSE(graph.EdgeExists(v2, v1)); } @@ -301,7 +301,7 @@ TEST_F( graph.AddOverlapEdges(); - EXPECT_TRUE(graph.EdgeExists(v1, v2)); + EXPECT_EQ(EdgeType::assetOverlap, graph.GetEdgeType(v1, v2).value()); EXPECT_FALSE(graph.EdgeExists(v2, v1)); } @@ -326,7 +326,7 @@ TEST_F( graph.AddOverlapEdges(); - EXPECT_TRUE(graph.EdgeExists(v1, v2)); + EXPECT_EQ(EdgeType::assetOverlap, graph.GetEdgeType(v1, v2).value()); EXPECT_FALSE(graph.EdgeExists(v2, v1)); } @@ -352,7 +352,7 @@ TEST_F( graph.AddOverlapEdges(); - EXPECT_TRUE(graph.EdgeExists(v1, v2)); + EXPECT_EQ(EdgeType::assetOverlap, graph.GetEdgeType(v1, v2).value()); EXPECT_FALSE(graph.EdgeExists(v2, v1)); } @@ -378,7 +378,7 @@ TEST_F(PluginGraphTest, graph.AddOverlapEdges(); - EXPECT_TRUE(graph.EdgeExists(v1, v2)); + EXPECT_EQ(EdgeType::recordOverlap, graph.GetEdgeType(v1, v2).value()); EXPECT_FALSE(graph.EdgeExists(v2, v1)); } @@ -436,16 +436,16 @@ TEST_F( vertex_t seven = graph.GetVertexByName("7.esp").value(); vertex_t eight = graph.GetVertexByName("8.esp").value(); - graph.AddEdge(six, seven, EdgeType::overlap); - graph.AddEdge(seven, eight, EdgeType::overlap); - graph.AddEdge(eight, five, EdgeType::overlap); + graph.AddEdge(six, seven, EdgeType::recordOverlap); + graph.AddEdge(seven, eight, EdgeType::recordOverlap); + graph.AddEdge(eight, five, EdgeType::recordOverlap); // Also add a path going from 6 to 3 and another from 8 to 4. vertex_t three = graph.GetVertexByName("3.esp").value(); vertex_t four = graph.GetVertexByName("4.esp").value(); - graph.AddEdge(six, three, EdgeType::overlap); - graph.AddEdge(eight, four, EdgeType::overlap); + graph.AddEdge(six, three, EdgeType::recordOverlap); + graph.AddEdge(eight, four, EdgeType::recordOverlap); graph.AddTieBreakEdges(); const auto sorted = graph.TopologicalSort(); @@ -482,9 +482,9 @@ TEST_F( vertex_t two = graph.GetVertexByName("2.esp").value(); vertex_t three = graph.GetVertexByName("3.esp").value(); - graph.AddEdge(one, two, EdgeType::overlap); - graph.AddEdge(two, three, EdgeType::overlap); - graph.AddEdge(three, zero, EdgeType::overlap); + graph.AddEdge(one, two, EdgeType::recordOverlap); + graph.AddEdge(two, three, EdgeType::recordOverlap); + graph.AddEdge(three, zero, EdgeType::recordOverlap); graph.AddTieBreakEdges(); const auto sorted = graph.TopologicalSort();