Hierarchy.inl.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. namespace anki
  6. {
  7. template<typename T>
  8. template<typename TAllocator>
  9. void Hierarchy<T>::destroy(TAllocator alloc)
  10. {
  11. if(m_parent != nullptr)
  12. {
  13. m_parent->removeChild(alloc, getSelf());
  14. m_parent = nullptr;
  15. }
  16. // Remove all children (fast version)
  17. auto it = m_children.getBegin();
  18. auto end = m_children.getEnd();
  19. for(; it != end; ++it)
  20. {
  21. Value* child = *it;
  22. child->m_parent = nullptr;
  23. }
  24. m_children.destroy(alloc);
  25. }
  26. template<typename T>
  27. template<typename TAllocator>
  28. void Hierarchy<T>::addChild(TAllocator alloc, Value* child)
  29. {
  30. ANKI_ASSERT(child != nullptr && "Null arg");
  31. ANKI_ASSERT(child != getSelf() && "Cannot put itself");
  32. ANKI_ASSERT(child->m_parent == nullptr && "Child already has parent");
  33. ANKI_ASSERT(child->findChild(getSelf()) == child->m_children.getEnd() && "Cyclic add");
  34. ANKI_ASSERT(findChild(child) == m_children.getEnd() && "Already has that child");
  35. child->m_parent = getSelf();
  36. m_children.emplaceBack(alloc, child);
  37. }
  38. template<typename T>
  39. template<typename TAllocator>
  40. void Hierarchy<T>::removeChild(TAllocator alloc, Value* child)
  41. {
  42. ANKI_ASSERT(child != nullptr && "Null arg");
  43. ANKI_ASSERT(child->m_parent == getSelf() && "Child has other parent");
  44. typename Container::Iterator it = findChild(child);
  45. ANKI_ASSERT(it != m_children.getEnd() && "Child not found");
  46. m_children.erase(alloc, it);
  47. child->m_parent = nullptr;
  48. }
  49. template<typename T>
  50. template<typename VisitorFunc>
  51. Error Hierarchy<T>::visitChildren(VisitorFunc vis)
  52. {
  53. Error err = Error::NONE;
  54. typename Container::Iterator it = m_children.getBegin();
  55. for(; it != m_children.getEnd() && !err; it++)
  56. {
  57. err = vis(*(*it));
  58. if(!err)
  59. {
  60. err = (*it)->visitChildren(vis);
  61. }
  62. }
  63. return err;
  64. }
  65. template<typename T>
  66. template<typename VisitorFunc>
  67. Error Hierarchy<T>::visitThisAndChildren(VisitorFunc vis)
  68. {
  69. Error err = vis(*getSelf());
  70. if(!err)
  71. {
  72. err = visitChildren(vis);
  73. }
  74. return err;
  75. }
  76. template<typename T>
  77. template<typename VisitorFunc>
  78. Error Hierarchy<T>::visitTree(VisitorFunc vis)
  79. {
  80. // Move to root
  81. Value* root = getSelf();
  82. while(root->m_parent != nullptr)
  83. {
  84. root = root->m_parent;
  85. }
  86. return root->visitThisAndChildren(vis);
  87. }
  88. template<typename T>
  89. template<typename VisitorFunc>
  90. Error Hierarchy<T>::visitChildrenMaxDepth(I maxDepth, VisitorFunc vis)
  91. {
  92. ANKI_ASSERT(maxDepth >= 0);
  93. Error err = Error::NONE;
  94. --maxDepth;
  95. typename Container::Iterator it = m_children.getBegin();
  96. for(; it != m_children.getEnd() && !err; ++it)
  97. {
  98. err = vis(*(*it));
  99. if(!err && maxDepth >= 0)
  100. {
  101. err = (*it)->visitChildrenMaxDepth(maxDepth, vis);
  102. }
  103. }
  104. return err;
  105. }
  106. } // end namespace anki