diff --git a/headers/enduro2d/high/node.hpp b/headers/enduro2d/high/node.hpp index 028a1105..2d3d4ec6 100644 --- a/headers/enduro2d/high/node.hpp +++ b/headers/enduro2d/high/node.hpp @@ -125,16 +125,6 @@ namespace e2d node_iptr next_sibling() noexcept; const_node_iptr next_sibling() const noexcept; - - template < typename F > - void for_each_child(F&& f); - template < typename F > - void for_each_child(F&& f) const; - - template < typename F > - void for_each_child_reversed(F&& f); - template < typename F > - void for_each_child_reversed(F&& f) const; protected: node() = default; node(gobject owner); @@ -161,76 +151,114 @@ namespace e2d namespace e2d::nodes { - template < typename Iter > - std::size_t extract_nodes(const node_iptr& root, Iter iter); - template < typename Iter > - std::size_t extract_nodes(const const_node_iptr& root, Iter iter); + class options final { + public: + options() = default; - template < typename Iter > - std::size_t extract_nodes_reversed(const node_iptr& root, Iter iter); - template < typename Iter > - std::size_t extract_nodes_reversed(const const_node_iptr& root, Iter iter); + options& reversed(bool value) noexcept; + options& recursive(bool value) noexcept; + options& include_root(bool value) noexcept; - template < typename Iter > - std::size_t extract_parents(const node_iptr& root, Iter iter); - template < typename Iter > - std::size_t extract_parents(const const_node_iptr& root, Iter iter); - - template < typename Iter > - std::size_t extract_parents_reversed(const node_iptr& root, Iter iter); - template < typename Iter > - std::size_t extract_parents_reversed(const const_node_iptr& root, Iter iter); + [[nodiscard]] bool reversed() const noexcept; + [[nodiscard]] bool recursive() const noexcept; + [[nodiscard]] bool include_root() const noexcept; + private: + enum flag_masks : u8 { + fm_reversed = 1u << 0, + fm_recursive = 1u << 1, + fm_include_root = 1u << 2, + }; + private: + std::underlying_type_t flags_{}; + }; } namespace e2d::nodes { - vector extract_nodes(const node_iptr& root); - vector extract_nodes(const const_node_iptr& root); + template < typename Node, typename F > + bool for_each_child( + const intrusive_ptr& root, + F&& f, + const options& opts = options()); - vector extract_nodes_reversed(const node_iptr& root); - vector extract_nodes_reversed(const const_node_iptr& root); - - vector extract_parents(const node_iptr& root); - vector extract_parents(const const_node_iptr& root); - - vector extract_parents_reversed(const node_iptr& root); - vector extract_parents_reversed(const const_node_iptr& root); + template < typename Node, typename F > + bool for_each_parent( + const intrusive_ptr& root, + F&& f, + const options& opts = options()); } namespace e2d::nodes { - template < typename F > - void for_extracted_nodes(const node_iptr& root, F&& f); - template < typename F > - void for_extracted_nodes(const const_node_iptr& root, F&& f); + template < typename Node, typename Iter > + std::size_t extract_parents( + const intrusive_ptr& root, + Iter iter, + const options& opts = options()); - template < typename F > - void for_extracted_nodes_reversed(const node_iptr& root, F&& f); - template < typename F > - void for_extracted_nodes_reversed(const const_node_iptr& root, F&& f); - - template < typename F > - void for_extracted_parents(const node_iptr& parents, F&& f); - template < typename F > - void for_extracted_parents(const const_node_iptr& parents, F&& f); - - template < typename F > - void for_extracted_parents_reversed(const node_iptr& parents, F&& f); - template < typename F > - void for_extracted_parents_reversed(const const_node_iptr& parents, F&& f); + template < typename Node, typename Iter > + std::size_t extract_children( + const intrusive_ptr& root, + Iter iter, + const options& opts = options()); } namespace e2d::nodes { - template < typename Component > - gcomponent get_component_in_parent(const const_node_iptr& root); - template < typename Component, typename Iter > - std::size_t get_components_in_parent(const const_node_iptr& root, Iter iter); + template < typename Node, typename F > + bool for_extracted_parents( + const intrusive_ptr& root, + F&& f, + const options& opts = options()); - template < typename Component > - gcomponent get_component_in_children(const const_node_iptr& root); - template < typename Component, typename Iter > - std::size_t get_components_in_children(const const_node_iptr& root, Iter iter); + template < typename Node, typename F > + bool for_extracted_children( + const intrusive_ptr& root, + F&& f, + const options& opts = options()); +} + +namespace e2d::nodes +{ + template < typename Component, typename Node, typename Iter > + std::size_t extract_components_from_parents( + const intrusive_ptr& root, + Iter iter, + const options& opts = options()); + + template < typename Component, typename Node, typename Iter > + std::size_t extract_components_from_children( + const intrusive_ptr& root, + Iter iter, + const options& opts = options()); +} + +namespace e2d::nodes +{ + template < typename Component, typename Node, typename F > + bool for_extracted_components_from_parents( + const intrusive_ptr& root, + F&& f, + const options& opts = options()); + + template < typename Component, typename Node, typename F > + bool for_extracted_components_from_children( + const intrusive_ptr& root, + F&& f, + const options& opts = options()); +} + +namespace e2d::nodes +{ + template < typename Component, typename Node > + gcomponent find_component_from_parents( + const intrusive_ptr& root, + const options& opts = options()); + + template < typename Component, typename Node > + gcomponent find_component_from_children( + const intrusive_ptr& root, + const options& opts = options()); } #include "node.inl" diff --git a/headers/enduro2d/high/node.inl b/headers/enduro2d/high/node.inl index 8aef0205..18b2b894 100644 --- a/headers/enduro2d/high/node.inl +++ b/headers/enduro2d/high/node.inl @@ -8,388 +8,327 @@ #include "node.hpp" -namespace e2d +namespace e2d::nodes::impl { - template < typename F > - void node::for_each_child(F&& f) { - for ( auto iter = children_.begin(); iter != children_.end(); ++iter ) { - f(node_iptr(&*iter)); - } - } - - template < typename F > - void node::for_each_child(F&& f) const { - for ( auto iter = children_.begin(); iter != children_.end(); ++iter ) { - f(const_node_iptr(&*iter)); - } - } - - template < typename F > - void node::for_each_child_reversed(F&& f) { - for ( auto iter = children_.rbegin(); iter != children_.rend(); ++iter ) { - f(node_iptr(&*iter)); - } - } - - template < typename F > - void node::for_each_child_reversed(F&& f) const { - for ( auto iter = children_.rbegin(); iter != children_.rend(); ++iter ) { - f(const_node_iptr(&*iter)); + template < typename F, typename... Args > + bool invoke_with_force_bool(F&& f, Args&&... args) { + if constexpr ( std::is_invocable_r_v ) { + return std::invoke(std::forward(f), std::forward(args)...); + } else { + std::invoke(std::forward(f), std::forward(args)...); + return true; } } } namespace e2d::nodes { - template < typename Iter > - std::size_t extract_nodes(const node_iptr& root, Iter iter) { - std::size_t count{0u}; - if ( root ) { - ++count; - iter++ = root; - root->for_each_child([&iter, &count](const node_iptr& child){ - count += extract_nodes(child, iter); - }); - } - return count; - } - - template < typename Iter > - std::size_t extract_nodes(const const_node_iptr& root, Iter iter) { - std::size_t count{0u}; - if ( root ) { - ++count; - iter++ = root; - root->for_each_child([&iter, &count](const const_node_iptr& child){ - count += extract_nodes(child, iter); - }); - } - return count; - } - - template < typename Iter > - std::size_t extract_nodes_reversed(const node_iptr& root, Iter iter) { - std::size_t count{0u}; - if ( root ) { - root->for_each_child_reversed([&iter, &count](const node_iptr& child){ - count += extract_nodes_reversed(child, iter); - }); - ++count; - iter++ = root; - } - return count; - } - - template < typename Iter > - std::size_t extract_nodes_reversed(const const_node_iptr& root, Iter iter) { - std::size_t count{0u}; - if ( root ) { - root->for_each_child_reversed([&iter, &count](const const_node_iptr& child){ - count += extract_nodes_reversed(child, iter); - }); - ++count; - iter++ = root; - } - return count; - } -} - -namespace e2d::nodes -{ - template < typename Iter > - std::size_t extract_parents(const node_iptr& root, Iter iter) { - std::size_t count{0u}; - if ( root ) { - ++count; - iter++ = root; - count += extract_parents(root->parent(), iter); - } - return count; - } - - template < typename Iter > - std::size_t extract_parents(const const_node_iptr& root, Iter iter) { - std::size_t count{0u}; - if ( root ) { - ++count; - iter++ = root; - count += extract_parents(root->parent(), iter); - } - return count; - } - - template < typename Iter > - std::size_t extract_parents_reversed(const node_iptr& root, Iter iter) { - std::size_t count{0u}; - if ( root ) { - count += extract_parents(root->parent(), iter); - ++count; - iter++ = root; - } - return count; - } - - template < typename Iter > - std::size_t extract_parents_reversed(const const_node_iptr& root, Iter iter) { - std::size_t count{0u}; - if ( root ) { - count += extract_parents(root->parent(), iter); - ++count; - iter++ = root; - } - return count; - } -} - -namespace e2d::nodes -{ - template < typename F > - void for_extracted_nodes(const node_iptr& root, F&& f) { - //TODO(BlackMat): replace it to frame allocator - static thread_local vector nodes; - - const std::size_t begin_index = nodes.size(); - E2D_DEFER([begin_index](){ - nodes.erase( - nodes.begin() + begin_index, - nodes.end()); - }); - - extract_nodes( - root, - std::back_inserter(nodes)); - - const std::size_t end_index = nodes.size(); - for ( std::size_t i = begin_index; i < end_index; ++i ) { - f(nodes[i]); - } - } - - template < typename F > - void for_extracted_nodes(const const_node_iptr& root, F&& f) { - //TODO(BlackMat): replace it to frame allocator - static thread_local vector nodes; - - const std::size_t begin_index = nodes.size(); - E2D_DEFER([begin_index](){ - nodes.erase( - nodes.begin() + begin_index, - nodes.end()); - }); - - extract_nodes( - root, - std::back_inserter(nodes)); - - const std::size_t end_index = nodes.size(); - for ( std::size_t i = begin_index; i < end_index; ++i ) { - f(nodes[i]); - } - } - - template < typename F > - void for_extracted_nodes_reversed(const node_iptr& root, F&& f) { - //TODO(BlackMat): replace it to frame allocator - static thread_local vector nodes; - - const std::size_t begin_index = nodes.size(); - E2D_DEFER([begin_index](){ - nodes.erase( - nodes.begin() + begin_index, - nodes.end()); - }); - - extract_nodes_reversed( - root, - std::back_inserter(nodes)); - - const std::size_t end_index = nodes.size(); - for ( std::size_t i = begin_index; i < end_index; ++i ) { - f(nodes[i]); - } - } - - template < typename F > - void for_extracted_nodes_reversed(const const_node_iptr& root, F&& f) { - //TODO(BlackMat): replace it to frame allocator - static thread_local vector nodes; - - const std::size_t begin_index = nodes.size(); - E2D_DEFER([begin_index](){ - nodes.erase( - nodes.begin() + begin_index, - nodes.end()); - }); - - extract_nodes_reversed( - root, - std::back_inserter(nodes)); - - const std::size_t end_index = nodes.size(); - for ( std::size_t i = begin_index; i < end_index; ++i ) { - f(nodes[i]); - } - } -} - -namespace e2d::nodes -{ - template < typename F > - void for_extracted_parents(const node_iptr& root, F&& f) { - //TODO(BlackMat): replace it to frame allocator - static thread_local vector parents; - - const std::size_t begin_index = parents.size(); - E2D_DEFER([begin_index](){ - parents.erase( - parents.begin() + begin_index, - parents.end()); - }); - - extract_parents( - root, - std::back_inserter(parents)); - - const std::size_t end_index = parents.size(); - for ( std::size_t i = begin_index; i < end_index; ++i ) { - f(parents[i]); - } - } - - template < typename F > - void for_extracted_parents(const const_node_iptr& root, F&& f) { - //TODO(BlackMat): replace it to frame allocator - static thread_local vector parents; - - const std::size_t begin_index = parents.size(); - E2D_DEFER([begin_index](){ - parents.erase( - parents.begin() + begin_index, - parents.end()); - }); - - extract_parents( - root, - std::back_inserter(parents)); - - const std::size_t end_index = parents.size(); - for ( std::size_t i = begin_index; i < end_index; ++i ) { - f(parents[i]); - } - } - - template < typename F > - void for_extracted_parents_reversed(const node_iptr& root, F&& f) { - //TODO(BlackMat): replace it to frame allocator - static thread_local vector parents; - - const std::size_t begin_index = parents.size(); - E2D_DEFER([begin_index](){ - parents.erase( - parents.begin() + begin_index, - parents.end()); - }); - - extract_parents_reversed( - root, - std::back_inserter(parents)); - - const std::size_t end_index = parents.size(); - for ( std::size_t i = begin_index; i < end_index; ++i ) { - f(parents[i]); - } - } - - template < typename F > - void for_extracted_parents_reversed(const const_node_iptr& root, F&& f) { - //TODO(BlackMat): replace it to frame allocator - static thread_local vector parents; - - const std::size_t begin_index = parents.size(); - E2D_DEFER([begin_index](){ - parents.erase( - parents.begin() + begin_index, - parents.end()); - }); - - extract_parents_reversed( - root, - std::back_inserter(parents)); - - const std::size_t end_index = parents.size(); - for ( std::size_t i = begin_index; i < end_index; ++i ) { - f(parents[i]); - } - } -} - -namespace e2d::nodes -{ - template < typename Component > - gcomponent get_component_in_parent(const const_node_iptr& root) { + template < typename Node, typename F > + bool for_each_child( + const intrusive_ptr& root, + F&& f, + const options& opts) + { if ( !root ) { - return {}; + return true; } - if ( auto component = root->owner().component() ) { - return component; - } + if ( opts.reversed() ) { + for ( auto child = root->last_child(); child; child = child->prev_sibling() ) { + if ( opts.recursive() && !for_each_child(child, f, options(opts).include_root(false)) ) { + return false; + } - return get_component_in_parent(root->parent()); - } + if ( !impl::invoke_with_force_bool(f, child) ) { + return false; + } + } - template < typename Component, typename Iter > - std::size_t get_components_in_parent(const const_node_iptr& root, Iter iter) { - std::size_t count{0u}; + if ( opts.include_root() && !impl::invoke_with_force_bool(f, root) ) { + return false; + } + } else { + if ( opts.include_root() && !impl::invoke_with_force_bool(f, root) ) { + return false; + } - if ( !root ) { - return count; - } + for ( auto child = root->first_child(); child; child = child->next_sibling() ) { + if ( !impl::invoke_with_force_bool(f, child) ) { + return false; + } - if ( auto component = root->owner().component() ) { - ++count; - iter++ = component; - } - - return count + get_components_in_parent(root->parent(), iter); - } - - template < typename Component > - gcomponent get_component_in_children(const const_node_iptr& root) { - if ( !root ) { - return {}; - } - - if ( auto component = root->owner().component() ) { - return component; - } - - for ( const_node_iptr child = root->first_child(); child; child = child->next_sibling() ) { - if ( auto component = get_component_in_children(child) ) { - return component; + if ( opts.recursive() && !for_each_child(child, f, options(opts).include_root(false)) ) { + return false; + } } } - return {}; + return true; } - template < typename Component, typename Iter > - std::size_t get_components_in_children(const const_node_iptr& root, Iter iter) { - std::size_t count{0u}; - + template < typename Node, typename F > + bool for_each_parent( + const intrusive_ptr& root, + F&& f, + const options& opts) + { if ( !root ) { - return count; + return true; } - if ( auto component = root->owner().component() ) { + if ( opts.reversed() ) { + if ( root->has_parent() ) { + if ( opts.recursive() && !for_each_parent(root->parent(), f, options(opts).include_root(false)) ) { + return false; + } + + if ( !impl::invoke_with_force_bool(f, root->parent()) ) { + return false; + } + } + + if ( opts.include_root() && !impl::invoke_with_force_bool(f, root) ) { + return false; + } + } else { + if ( opts.include_root() && !impl::invoke_with_force_bool(f, root) ) { + return false; + } + + if ( root->has_parent() ) { + if ( !impl::invoke_with_force_bool(f, root->parent()) ) { + return false; + } + + if ( opts.recursive() && !for_each_parent(root->parent(), f, options(opts).include_root(false)) ) { + return false; + } + } + } + + return true; + } +} + +namespace e2d::nodes +{ + template < typename Node, typename Iter > + std::size_t extract_parents( + const intrusive_ptr& root, + Iter iter, + const options& opts) + { + std::size_t count{0u}; + for_each_parent(root, [&count, &iter](const auto& parent){ ++count; - iter++ = component; - } - - for ( const_node_iptr child = root->first_child(); child; child = child->next_sibling() ) { - count += get_components_in_children(child, iter); - } + iter++ = parent; + }, opts); + return count; + } + template < typename Node, typename Iter > + std::size_t extract_children( + const intrusive_ptr& root, + Iter iter, + const options& opts) + { + std::size_t count{0u}; + for_each_child(root, [&count, &iter](const auto& child){ + ++count; + iter++ = child; + }, opts); return count; } } + +namespace e2d::nodes +{ + template < typename Node, typename F > + bool for_extracted_parents( + const intrusive_ptr& root, + F&& f, + const options& opts) + { + //TODO(BlackMat): replace it to frame allocator + static thread_local vector> parents; + + const std::size_t begin_index = parents.size(); + E2D_DEFER([begin_index](){ + parents.erase( + parents.begin() + begin_index, + parents.end()); + }); + + extract_parents( + root, + std::back_inserter(parents), + opts); + + const std::size_t end_index = parents.size(); + for ( std::size_t i = begin_index; i < end_index; ++i ) { + if ( !impl::invoke_with_force_bool(f, parents[i]) ) { + return false; + } + } + + return true; + } + + template < typename Node, typename F > + bool for_extracted_children( + const intrusive_ptr& root, + F&& f, + const options& opts) + { + //TODO(BlackMat): replace it to frame allocator + static thread_local vector> children; + + const std::size_t begin_index = children.size(); + E2D_DEFER([begin_index](){ + children.erase( + children.begin() + begin_index, + children.end()); + }); + + extract_children( + root, + std::back_inserter(children), + opts); + + const std::size_t end_index = children.size(); + for ( std::size_t i = begin_index; i < end_index; ++i ) { + if ( !impl::invoke_with_force_bool(f, children[i]) ) { + return false; + } + } + + return true; + } +} + +namespace e2d::nodes +{ + template < typename Component, typename Node, typename Iter > + std::size_t extract_components_from_parents( + const intrusive_ptr& root, + Iter iter, + const options& opts) + { + std::size_t count{0u}; + for_each_parent(root, [&count, &iter](const auto& parent){ + if ( auto component = parent->owner().template component() ) { + ++count; + iter++ = component; + } + }, opts); + return count; + } + + template < typename Component, typename Node, typename Iter > + std::size_t extract_components_from_children( + const intrusive_ptr& root, + Iter iter, + const options& opts) + { + std::size_t count{0u}; + for_each_child(root, [&count, &iter](const auto& child){ + if ( auto component = child->owner().template component() ) { + ++count; + iter++ = component; + } + }, opts); + return count; + } +} + +namespace e2d::nodes +{ + template < typename Component, typename Node, typename F > + bool for_extracted_components_from_parents( + const intrusive_ptr& root, + F&& f, + const options& opts) + { + //TODO(BlackMat): replace it to frame allocator + static thread_local vector> components; + + const std::size_t begin_index = components.size(); + E2D_DEFER([begin_index](){ + components.erase( + components.begin() + begin_index, + components.end()); + }); + + extract_components_from_parents( + root, + std::back_inserter(components), + opts); + + const std::size_t end_index = components.size(); + for ( std::size_t i = begin_index; i < end_index; ++i ) { + if ( !impl::invoke_with_force_bool(f, components[i]) ) { + return false; + } + } + + return true; + } + + template < typename Component, typename Node, typename F > + bool for_extracted_components_from_children( + const intrusive_ptr& root, + F&& f, + const options& opts) + { + //TODO(BlackMat): replace it to frame allocator + static thread_local vector> components; + + const std::size_t begin_index = components.size(); + E2D_DEFER([begin_index](){ + components.erase( + components.begin() + begin_index, + components.end()); + }); + + extract_components_from_children( + root, + std::back_inserter(components), + opts); + + const std::size_t end_index = components.size(); + for ( std::size_t i = begin_index; i < end_index; ++i ) { + if ( !impl::invoke_with_force_bool(f, components[i]) ) { + return false; + } + } + + return true; + } +} + +namespace e2d::nodes +{ + template < typename Component, typename Node > + gcomponent find_component_from_parents( + const intrusive_ptr& root, + const options& opts) + { + gcomponent component; + for_each_parent(root, [&component](const auto& child){ + return !(component = child->owner().template component()); + }, opts); + return component; + } + + template < typename Component, typename Node > + gcomponent find_component_from_children( + const intrusive_ptr& root, + const options& opts) + { + gcomponent component; + for_each_child(root, [&component](const auto& child){ + return !(component = child->owner().template component()); + }, opts); + return component; + } +} diff --git a/sources/enduro2d/high/node.cpp b/sources/enduro2d/high/node.cpp index d6517e6a..764e995e 100644 --- a/sources/enduro2d/high/node.cpp +++ b/sources/enduro2d/high/node.cpp @@ -5,7 +5,6 @@ ******************************************************************************/ #include -#include namespace e2d { @@ -446,54 +445,36 @@ namespace e2d namespace e2d::nodes { - vector extract_nodes(const node_iptr& root) { - vector nodes; - extract_nodes(root, std::back_inserter(nodes)); - return nodes; + options& options::reversed(bool value) noexcept { + if ( value != reversed() ) { + math::flip_flags_inplace(flags_, fm_reversed); + } + return *this; } - vector extract_nodes(const const_node_iptr& root) { - vector nodes; - extract_nodes(root, std::back_inserter(nodes)); - return nodes; + options& options::recursive(bool value) noexcept { + if ( value != recursive() ) { + math::flip_flags_inplace(flags_, fm_recursive); + } + return *this; } - vector extract_nodes_reversed(const node_iptr& root) { - vector nodes; - extract_nodes_reversed(root, std::back_inserter(nodes)); - return nodes; + options& options::include_root(bool value) noexcept { + if ( value != include_root() ) { + math::flip_flags_inplace(flags_, fm_include_root); + } + return *this; } - vector extract_nodes_reversed(const const_node_iptr& root) { - vector nodes; - extract_nodes_reversed(root, std::back_inserter(nodes)); - return nodes; - } -} - -namespace e2d::nodes -{ - vector extract_parents(const node_iptr& child) { - vector parents; - extract_parents(child, std::back_inserter(parents)); - return parents; - } - - vector extract_parents(const const_node_iptr& child) { - vector parents; - extract_parents(child, std::back_inserter(parents)); - return parents; - } - - vector extract_parents_reversed(const node_iptr& child) { - vector parents; - extract_parents_reversed(child, std::back_inserter(parents)); - return parents; - } - - vector extract_parents_reversed(const const_node_iptr& child) { - vector parents; - extract_parents_reversed(child, std::back_inserter(parents)); - return parents; + bool options::reversed() const noexcept { + return math::check_any_flags(flags_, fm_reversed); + } + + bool options::recursive() const noexcept { + return math::check_any_flags(flags_, fm_recursive); + } + + bool options::include_root() const noexcept { + return math::check_any_flags(flags_, fm_include_root); } } diff --git a/sources/enduro2d/high/systems/render_system.cpp b/sources/enduro2d/high/systems/render_system.cpp index 0b49bf94..4e78c4f3 100644 --- a/sources/enduro2d/high/systems/render_system.cpp +++ b/sources/enduro2d/high/systems/render_system.cpp @@ -30,9 +30,9 @@ namespace const scene&, const actor& scn_a) { - nodes::for_extracted_nodes(scn_a.node(), [&ctx](const const_node_iptr& node){ + nodes::for_extracted_children(scn_a.node(), [&ctx](const const_node_iptr& node){ ctx.draw(node); - }); + }, nodes::options().recursive(true).include_root(true)); }; ecsex::for_extracted_sorted_components( diff --git a/sources/enduro2d/high/widgets/hierarchy_widget.cpp b/sources/enduro2d/high/widgets/hierarchy_widget.cpp index b0d1946a..98df2685 100644 --- a/sources/enduro2d/high/widgets/hierarchy_widget.cpp +++ b/sources/enduro2d/high/widgets/hierarchy_widget.cpp @@ -103,7 +103,7 @@ namespace } if ( tree_node_opened ) { - root->for_each_child([&e, &i, &w](const node_iptr& child){ + nodes::for_each_child(root, [&e, &i, &w](const node_iptr& child){ show_tree_for_node(e, i, w, child); }); } diff --git a/sources/enduro2d/high/world.cpp b/sources/enduro2d/high/world.cpp index d9d6b82a..30a390e7 100644 --- a/sources/enduro2d/high/world.cpp +++ b/sources/enduro2d/high/world.cpp @@ -142,32 +142,36 @@ namespace } void shutdown_instance(gobject& inst) noexcept { - if ( gcomponent inst_a{inst}; inst_a ) { - nodes::for_extracted_nodes(inst_a->node(), [](const node_iptr& node){ - if ( gcomponent inst_b{node->owner()}; inst_b ) { - behaviours::call_meta_method( - *inst_b, - "on_shutdown", - node->owner()); - } - }); + gcomponent inst_a = inst.component(); + if ( !inst_a ) { + return; } + nodes::for_extracted_components_from_children( + inst_a->node(), + [](gcomponent& inst_b){ + behaviours::call_meta_method( + *inst_b, + "on_shutdown", + inst_b.owner()); + }, nodes::options().recursive(true).include_root(true)); } void start_instance(gobject& inst) { - if ( gcomponent inst_a{inst}; inst_a ) { - nodes::for_extracted_nodes(inst_a->node(), [&inst](const node_iptr& node){ - if ( gcomponent inst_b{node->owner()}; inst_b ) { - const auto result = behaviours::call_meta_method( - *inst_b, - "on_start", - node->owner()); - if ( result == behaviours::call_result::failed ) { - inst.component>().assign(); - } - } - }); + gcomponent inst_a = inst.component(); + if ( !inst_a ) { + return; } + nodes::for_extracted_components_from_children( + inst_a->node(), + [&inst](gcomponent& inst_b){ + const auto result = behaviours::call_meta_method( + *inst_b, + "on_start", + inst_b.owner()); + if ( result == behaviours::call_result::failed ) { + inst.component>().assign(); + } + }, nodes::options().recursive(true).include_root(true)); } } diff --git a/untests/sources/untests_high/node.cpp b/untests/sources/untests_high/node.cpp index dae683c6..ce6a38bc 100644 --- a/untests/sources/untests_high/node.cpp +++ b/untests/sources/untests_high/node.cpp @@ -595,7 +595,7 @@ TEST_CASE("node") { node::create(p)}; { std::size_t count = 0; - p->for_each_child([&ns, &count](const node_iptr& n){ + nodes::for_each_child(p, [&ns, &count](const node_iptr& n){ REQUIRE(ns[count++] == n); }); REQUIRE(count == 3); @@ -603,7 +603,7 @@ TEST_CASE("node") { { const_node_iptr cp = p; std::size_t count = 0; - cp->for_each_child([&ns, &count](const const_node_iptr& n){ + nodes::for_each_child(cp, [&ns, &count](const const_node_iptr& n){ REQUIRE(ns[count++] == n); }); REQUIRE(count == 3); @@ -617,13 +617,19 @@ TEST_CASE("node") { const vector ns{p, c1, c2, c3}; { vector ns2; - REQUIRE(4u == nodes::extract_nodes(p, std::back_inserter(ns2))); + REQUIRE(4u == nodes::extract_children( + p, + std::back_inserter(ns2), + nodes::options().recursive(true).include_root(true))); REQUIRE(ns == ns2); } { const_node_iptr cp = p; vector ns2; - REQUIRE(4u == nodes::extract_nodes(cp, std::back_inserter(ns2))); + REQUIRE(4u == nodes::extract_children( + cp, + std::back_inserter(ns2), + nodes::options().recursive(true).include_root(true))); REQUIRE(ns.size() == ns2.size()); for ( std::size_t i = 0; i < ns.size(); ++i ) { REQUIRE(ns[i] == ns2[i]);