diff --git a/src/backend/graph.cpp b/src/backend/graph.cpp index f5333805..21643a47 100644 --- a/src/backend/graph.cpp +++ b/src/backend/graph.cpp @@ -63,15 +63,9 @@ namespace boss { std::string key; std::string value; //Priority values should override the number of override records as the deciding factor if they differ. - if (it->MustLoadAfter(*jt) || jt->MustLoadAfter(*it)) + if (it->MustLoadAfter(*jt) || jt->MustLoadAfter(*it) || it->Priority() != jt->Priority()) continue; - if (it->Priority() < jt->Priority()) { - key = jt->Name(); - value = it->Name(); - } else if (jt->Priority() < it->Priority()) { - key = it->Name(); - value = jt->Name(); - } else if (it->NumOverrideFormIDs() >= jt->NumOverrideFormIDs()) { + if (it->NumOverrideFormIDs() >= jt->NumOverrideFormIDs()) { key = jt->Name(); value = it->Name(); } else { @@ -89,6 +83,37 @@ namespace boss { } } + void CalcPriorityMap(const std::list& plugins, boost::unordered_map< std::string, std::vector >& priorityMap) { + for (list::const_iterator it=plugins.begin(), + endit=plugins.end(); + it != endit; + ++it) { + list::const_iterator jt = it; + ++jt; + for (; jt != endit; ++jt) { + BOOST_LOG_TRIVIAL(trace) << "Checking for priority difference between \"" << it->Name() << "\" and \"" << jt->Name() << "\"."; + if (it->MustLoadAfter(*jt) || jt->MustLoadAfter(*it) || it->Priority() == jt->Priority()) + continue; + + std::string key; + std::string value; + if (it->Priority() < jt->Priority()) { + key = jt->Name(); + value = it->Name(); + } else if (jt->Priority() < it->Priority()) { + key = it->Name(); + value = jt->Name(); + } + boost::unordered_map< string, vector >::iterator mapIt = priorityMap.find(key); + if (mapIt == priorityMap.end()) { + priorityMap.insert(pair >(key, vector(1, value))); + } else { + mapIt->second.push_back(value); + } + } + } + } + bool GetVertexByName(const PluginGraph& graph, const std::string& name, vertex_t& vertex) { vertex_it vit, vit_end; boost::tie(vit, vit_end) = boost::vertices(graph); @@ -165,7 +190,7 @@ namespace boss { boost::depth_first_search(graph, visitor(vis).vertex_index_map(v_index_map)); } - void AddNonOverlapEdges(PluginGraph& graph) { + void AddNonOverlapEdges(PluginGraph& graph, const boost::unordered_map< std::string, std::vector >& priorityMap) { //First find the position of the first non-master. boss::vertex_it vitFirstNonMaster, vit, vitend; for (boost::tie(vit, vitend) = boost::vertices(graph); vit != vitend; ++vit) { @@ -228,6 +253,21 @@ namespace boss { boost::add_edge(parentVertex, *vit, graph); } } + + BOOST_LOG_TRIVIAL(trace) << "Adding in-edges for priority differences."; + boost::unordered_map< string, vector >::const_iterator priorityIt = priorityMap.find(graph[*vit]->Name()); + if (priorityIt != priorityMap.end()) { + for (vector::const_iterator it=priorityIt->second.begin(), itend=priorityIt->second.end(); it != itend; ++it) { + if (boss::GetVertexByName(graph, *it, parentVertex) && + !boost::edge(parentVertex, *vit, graph).second && + !EdgeCreatesCycle(graph, parentVertex, *vit)) { //No edge going the other way, OK to add this edge. + + BOOST_LOG_TRIVIAL(trace) << "Adding edge from \"" << graph[parentVertex]->Name() << "\" to \"" << graph[*vit]->Name() << "\"."; + + boost::add_edge(parentVertex, *vit, graph); + } + } + } } } diff --git a/src/backend/graph.h b/src/backend/graph.h index cfa1821f..d97f5c4d 100644 --- a/src/backend/graph.h +++ b/src/backend/graph.h @@ -58,6 +58,8 @@ namespace boss { //The map maps each plugin name to a vector of names of plugins that overlap with it and should load before it. void CalcPluginOverlaps(const std::list& plugins, boost::unordered_map< std::string, std::vector >& overlapMap); + void CalcPriorityMap(const std::list& plugins, boost::unordered_map< std::string, std::vector >& priorityMap); + bool GetVertexByName(const PluginGraph& graph, const std::string& name, vertex_t& vertex); void SaveGraph(const PluginGraph& graph, const boost::filesystem::path outpath); @@ -66,7 +68,7 @@ namespace boss { void CheckForCycles(const PluginGraph& graph); - void AddNonOverlapEdges(PluginGraph& graph); + void AddNonOverlapEdges(PluginGraph& graph, const boost::unordered_map< std::string, std::vector >& priorityMap); void AddOverlapEdges(PluginGraph& graph, const boost::unordered_map< std::string, std::vector >& overlapMap); diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 0d4c21ae..5aff5dab 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -600,17 +600,20 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { progDia->Pulse(); - //First sort the plugins list so that masters come before non-masters. BOOST_LOG_TRIVIAL(trace) << "Moving masters before non-masters."; plugins.sort(boss::master_sort); progDia->Pulse(); - //Now build overlap map. + BOOST_LOG_TRIVIAL(trace) << "Building plugin overlap map."; boost::unordered_map< string, vector > overlapMap; CalcPluginOverlaps(plugins, overlapMap); + BOOST_LOG_TRIVIAL(trace) << "Building plugin priority map."; + boost::unordered_map< string, vector > priorityMap; + CalcPriorityMap(plugins, priorityMap); + progDia->Pulse(); BOOST_LOG_TRIVIAL(trace) << "Building the plugin dependency graph..."; @@ -625,7 +628,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { boost::add_vertex(it, graph); } - AddNonOverlapEdges(graph); + AddNonOverlapEdges(graph, priorityMap); AddOverlapEdges(graph, overlapMap);