Hierarchy.h 2.4 KB

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