Object.h 3.2 KB

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