diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2021-01-09 15:12:56 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-09 15:12:56 -0500 |
| commit | eaec140f7c823012c09536175d8917dddcacdb7c (patch) | |
| tree | aaec7165d5ceee9b581944602c7d2c1400c04961 | |
| parent | 135d23c20a705825af8fe5c38d7dbba1d3934986 (diff) | |
| parent | 6781451ab2e0bda097a699d216c092e6d3842aa1 (diff) | |
Merge pull request #1349 from isanae/master
Handle category cycles by putting parent ids in a set
| -rw-r--r-- | src/categories.cpp | 18 | ||||
| -rw-r--r-- | src/categories.h | 5 | ||||
| -rw-r--r-- | src/modinfo.cpp | 2 |
3 files changed, 20 insertions, 5 deletions
diff --git a/src/categories.cpp b/src/categories.cpp index b1e08a3a..7952fed4 100644 --- a/src/categories.cpp +++ b/src/categories.cpp @@ -282,9 +282,23 @@ bool CategoryFactory::categoryExists(int id) const }
-bool CategoryFactory::isDecendantOf(int id, int parentID) const
+bool CategoryFactory::isDescendantOf(int id, int parentID) const
{
+ // handles cycles
+ std::set<int> seen;
+ return isDescendantOfImpl(id, parentID, seen);
+}
+
+bool CategoryFactory::isDescendantOfImpl(
+ int id, int parentID, std::set<int>& seen) const
+{
+ if (!seen.insert(id).second) {
+ log::error("cycle in category: {}", id);
+ return false;
+ }
+
std::map<int, unsigned int>::const_iterator iter = m_IDMap.find(id);
+
if (iter != m_IDMap.end()) {
unsigned int index = iter->second;
if (m_Categories[index].m_ParentID == 0) {
@@ -292,7 +306,7 @@ bool CategoryFactory::isDecendantOf(int id, int parentID) const } else if (m_Categories[index].m_ParentID == parentID) {
return true;
} else {
- return isDecendantOf(m_Categories[index].m_ParentID, parentID);
+ return isDescendantOfImpl(m_Categories[index].m_ParentID, parentID, seen);
}
} else {
log::warn("{} is no valid category id", id);
diff --git a/src/categories.h b/src/categories.h index e8ec763b..e4a3ede9 100644 --- a/src/categories.h +++ b/src/categories.h @@ -124,7 +124,7 @@ public: * @param parentID the parent id to test for
* @return true if id is a child of parentID
**/
- bool isDecendantOf(int id, int parentID) const;
+ bool isDescendantOf(int id, int parentID) const;
/**
* @brief test if the specified category has child categories
@@ -209,7 +209,8 @@ private: std::map<int, unsigned int> m_NexusMap;
private:
-
+ // called by isDescendantOf()
+ bool isDescendantOfImpl(int id, int parentID, std::set<int>& seen) const;
};
diff --git a/src/modinfo.cpp b/src/modinfo.cpp index a0382fe8..16fcf93a 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -516,7 +516,7 @@ bool ModInfo::categorySet(int categoryID) const { for (std::set<int>::const_iterator iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) { if ((*iter == categoryID) || - (CategoryFactory::instance().isDecendantOf(*iter, categoryID))) { + (CategoryFactory::instance().isDescendantOf(*iter, categoryID))) { return true; } } |
