// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors. // All rights reserved. // Code licensed under the BSD License. // http://www.anki3d.org/LICENSE #pragma once #include #include #include #include #include namespace anki { /// @addtogroup util_patterns /// @{ /// A hierarchical object template class Hierarchy { public: using Value = T; using Container = List; Hierarchy() : m_parent(nullptr) { } Hierarchy(const Hierarchy&) = delete; // Non-copyable /// Delete children from the last entered to the first and update parent virtual ~Hierarchy() { ANKI_ASSERT(m_parent == nullptr && m_children.isEmpty() && "Requires manual desruction"); } Hierarchy& operator=(const Hierarchy&) = delete; // Non-copyable template void destroy(TAllocator alloc); const Value* getParent() const { return m_parent; } Value* getParent() { return m_parent; } Value& getChild(PtrSize i) { return *(*(m_children.getBegin() + i)); } const Value& getChild(PtrSize i) const { return *(*(m_children.getBegin() + i)); } /// Add a new child. template void addChild(TAllocator alloc, Value* child); /// Remove a child. template void removeChild(TAllocator alloc, Value* child); /// Visit the children and the children's children. Use it with lambda template ANKI_USE_RESULT Error visitChildren(VisitorFunc vis); /// Visit this object and move to the children. Use it with lambda template ANKI_USE_RESULT Error visitThisAndChildren(VisitorFunc vis); /// Visit the whole tree. Use it with lambda template ANKI_USE_RESULT Error visitTree(VisitorFunc vis); /// Visit the children and limit the depth. Use it with lambda. template ANKI_USE_RESULT Error visitChildrenMaxDepth(I maxDepth, VisitorFunc vis); private: Value* m_parent; ///< May be nullptr Container m_children; /// Cast the Hierarchy to the given type Value* getSelf() { return static_cast(this); } /// Find the child typename Container::Iterator findChild(Value* child) { typename Container::Iterator it = m_children.find(child); return it; } }; /// @} } // end namespace anki #include