Hierarchy.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. #pragma once
  6. #include <AnKi/Util/Assert.h>
  7. #include <AnKi/Util/List.h>
  8. #include <AnKi/Util/StdTypes.h>
  9. #include <AnKi/Util/Allocator.h>
  10. #include <algorithm>
  11. namespace anki {
  12. /// @addtogroup util_patterns
  13. /// @{
  14. /// A hierarchical object
  15. template<typename T>
  16. class Hierarchy
  17. {
  18. public:
  19. using Value = T;
  20. using Container = List<Value*>;
  21. Hierarchy()
  22. : m_parent(nullptr)
  23. {
  24. }
  25. Hierarchy(const Hierarchy&) = delete; // Non-copyable
  26. /// Delete children from the last entered to the first and update parent
  27. virtual ~Hierarchy()
  28. {
  29. ANKI_ASSERT(m_parent == nullptr && m_children.isEmpty() && "Requires manual desruction");
  30. }
  31. Hierarchy& operator=(const Hierarchy&) = delete; // Non-copyable
  32. template<typename TAllocator>
  33. void destroy(TAllocator alloc);
  34. const Value* getParent() const
  35. {
  36. return m_parent;
  37. }
  38. Value* getParent()
  39. {
  40. return m_parent;
  41. }
  42. Value& getChild(PtrSize i)
  43. {
  44. return *(*(m_children.getBegin() + i));
  45. }
  46. const Value& getChild(PtrSize i) const
  47. {
  48. return *(*(m_children.getBegin() + i));
  49. }
  50. /// Add a new child.
  51. template<typename TAllocator>
  52. void addChild(TAllocator alloc, Value* child);
  53. /// Remove a child.
  54. template<typename TAllocator>
  55. void removeChild(TAllocator alloc, Value* child);
  56. /// Visit the children and the children's children. Use it with lambda
  57. template<typename VisitorFunc>
  58. ANKI_USE_RESULT Error visitChildren(VisitorFunc vis);
  59. /// Visit this object and move to the children. Use it with lambda
  60. template<typename VisitorFunc>
  61. ANKI_USE_RESULT Error visitThisAndChildren(VisitorFunc vis);
  62. /// Visit the whole tree. Use it with lambda
  63. template<typename VisitorFunc>
  64. ANKI_USE_RESULT Error visitTree(VisitorFunc vis);
  65. /// Visit the children and limit the depth. Use it with lambda.
  66. template<typename VisitorFunc>
  67. ANKI_USE_RESULT Error visitChildrenMaxDepth(I maxDepth, VisitorFunc vis);
  68. private:
  69. Value* m_parent; ///< May be nullptr
  70. Container m_children;
  71. /// Cast the Hierarchy to the given type
  72. Value* getSelf()
  73. {
  74. return static_cast<Value*>(this);
  75. }
  76. /// Find the child
  77. typename Container::Iterator findChild(Value* child)
  78. {
  79. typename Container::Iterator it = m_children.find(child);
  80. return it;
  81. }
  82. };
  83. /// @}
  84. } // end namespace anki
  85. #include <AnKi/Util/Hierarchy.inl.h>