Object.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #ifndef ANKI_UTIL_OBJECT_H
  2. #define ANKI_UTIL_OBJECT_H
  3. #include "anki/util/Assert.h"
  4. #include "anki/util/Vector.h"
  5. #include "anki/util/StdTypes.h"
  6. #include "anki/util/Allocator.h"
  7. #include <algorithm>
  8. namespace anki {
  9. /// @addtogroup util
  10. /// @{
  11. /// @addtogroup patterns
  12. /// @{
  13. /// A hierarchical object
  14. template<typename T, typename Alloc = Allocator<T>>
  15. class Object
  16. {
  17. public:
  18. typedef T Value;
  19. typedef Vector<Value*, Alloc> Container;
  20. /// Calls addChild if parent is not nullptr
  21. Object(Value* parent_, const Alloc& alloc = Alloc())
  22. : childs(alloc)
  23. {
  24. if(parent_ != nullptr)
  25. {
  26. parent_->addChild(getSelf());
  27. }
  28. parent = parent_;
  29. }
  30. /// Delete children from the last entered to the first and update parent
  31. virtual ~Object()
  32. {
  33. if(parent != nullptr)
  34. {
  35. parent->removeChild(getSelf());
  36. }
  37. // Remove all children (fast version)
  38. for(Value* child : childs)
  39. {
  40. child->parent = nullptr;
  41. }
  42. }
  43. /// @name Accessors
  44. /// @{
  45. const Value* getParent() const
  46. {
  47. return parent;
  48. }
  49. Value* getParent()
  50. {
  51. return parent;
  52. }
  53. typename Container::const_iterator getChildrenBegin() const
  54. {
  55. return childs.begin();
  56. }
  57. typename Container::iterator getChildrenBegin()
  58. {
  59. return childs.begin();
  60. }
  61. typename Container::const_iterator getChildrenEnd() const
  62. {
  63. return childs.end();
  64. }
  65. typename Container::iterator getChildrenEnd()
  66. {
  67. return childs.end();
  68. }
  69. PtrSize getChildrenSize() const
  70. {
  71. return childs.size();
  72. }
  73. /// @}
  74. /// Add a new child
  75. void addChild(Value* child)
  76. {
  77. ANKI_ASSERT(child != nullptr && "Null arg");
  78. ANKI_ASSERT(child != getSelf() && "Cannot put itself");
  79. ANKI_ASSERT(child->parent == nullptr && "Child already has parent");
  80. ANKI_ASSERT(child->findChild(getSelf()) == child->childs.end()
  81. && "Cyclic add");
  82. ANKI_ASSERT(findChild(child) == childs.end() && "Already a child");
  83. child->parent = getSelf();
  84. childs.push_back(child);
  85. }
  86. /// Remove a child
  87. void removeChild(Value* child)
  88. {
  89. ANKI_ASSERT(child != nullptr && "Null arg");
  90. ANKI_ASSERT(child->parent == getSelf() && "Child has other parent");
  91. typename Container::iterator it = findChild(child);
  92. ANKI_ASSERT(it != childs.end() && "Child not found");
  93. childs.erase(it);
  94. child->parent = nullptr;
  95. }
  96. /// Visit
  97. template<typename Visitor>
  98. void visitTreeDepth(Visitor& vis)
  99. {
  100. vis(*getSelf());
  101. for(Value* c : childs)
  102. {
  103. c->visitTreeDepth(vis);
  104. }
  105. }
  106. private:
  107. Value* parent; ///< May be nullptr
  108. Container childs;
  109. /// Cast the Object to the given type
  110. Value* getSelf()
  111. {
  112. return static_cast<Value*>(this);
  113. }
  114. /// Find the child
  115. typename Container::iterator findChild(Value* child)
  116. {
  117. typename Container::iterator it =
  118. std::find(childs.begin(), childs.end(), child);
  119. return it;
  120. }
  121. };
  122. /// @}
  123. /// @}
  124. } // end namespace anki
  125. #endif