diff --git a/headers/enduro2d/high/node.hpp b/headers/enduro2d/high/node.hpp index 9a6de45e..245c97ce 100644 --- a/headers/enduro2d/high/node.hpp +++ b/headers/enduro2d/high/node.hpp @@ -127,15 +127,13 @@ namespace e2d template < typename F > void for_each_child(F&& f); - template < typename F > void for_each_child(F&& f) const; - template < typename Iter > - std::size_t extract_all_nodes(Iter iter); - - template < typename Iter > - std::size_t extract_all_nodes(Iter iter) 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); @@ -160,4 +158,39 @@ 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); + + 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); +} + +namespace e2d::nodes +{ + vector extract_nodes(const node_iptr& root); + vector extract_nodes(const const_node_iptr& root); + + vector extract_nodes_reversed(const node_iptr& root); + vector extract_nodes_reversed(const const_node_iptr& root); +} + +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 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); +} + #include "node.inl" diff --git a/headers/enduro2d/high/node.inl b/headers/enduro2d/high/node.inl index 06895416..b0e82a5d 100644 --- a/headers/enduro2d/high/node.inl +++ b/headers/enduro2d/high/node.inl @@ -12,35 +12,151 @@ namespace e2d { template < typename F > void node::for_each_child(F&& f) { - for ( node& child : children_ ) { - f(node_iptr(&child)); + 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 ( const node& child : children_ ) { - f(const_node_iptr(&child)); + 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)); + } + } +} + +namespace e2d::nodes +{ template < typename Iter > - std::size_t node::extract_all_nodes(Iter iter) { - std::size_t count{1u}; - iter++ = node_iptr(this); - for_each_child([&iter, &count](const node_iptr& child){ - count += child->extract_all_nodes(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 node::extract_all_nodes(Iter iter) const { - std::size_t count{1u}; - iter++ = const_node_iptr(this); - for_each_child([&iter, &count](const const_node_iptr& child){ - count += child->extract_all_nodes(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 F > + void for_extracted_nodes(const node_iptr& root, F&& f) { + //TODO(BlackMat): replace it to frame allocator + static thread_local vector nodes; + try { + extract_nodes(root, std::back_inserter(nodes)); + for ( const node_iptr& n : nodes ) { + f(n); + } + } catch (...) { + nodes.clear(); + throw; + } + nodes.clear(); + } + + 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; + try { + extract_nodes(root, std::back_inserter(nodes)); + for ( const const_node_iptr& n : nodes ) { + f(n); + } + } catch (...) { + nodes.clear(); + throw; + } + nodes.clear(); + } + + 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; + try { + extract_nodes_reversed(root, std::back_inserter(nodes)); + for ( const node_iptr& n : nodes ) { + f(n); + } + } catch (...) { + nodes.clear(); + throw; + } + nodes.clear(); + } + + 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; + try { + extract_nodes_reversed(root, std::back_inserter(nodes)); + for ( const const_node_iptr& n : nodes ) { + f(n); + } + } catch (...) { + nodes.clear(); + throw; + } + nodes.clear(); + } +} diff --git a/sources/enduro2d/high/node.cpp b/sources/enduro2d/high/node.cpp index d72a3d78..212fbd54 100644 --- a/sources/enduro2d/high/node.cpp +++ b/sources/enduro2d/high/node.cpp @@ -439,3 +439,30 @@ namespace e2d : local_matrix(); } } + +namespace e2d::nodes +{ + vector extract_nodes(const node_iptr& root) { + vector nodes; + extract_nodes(root, std::back_inserter(nodes)); + return nodes; + } + + vector extract_nodes(const const_node_iptr& root) { + vector nodes; + extract_nodes(root, std::back_inserter(nodes)); + return nodes; + } + + vector extract_nodes_reversed(const node_iptr& root) { + vector nodes; + extract_nodes_reversed(root, std::back_inserter(nodes)); + return nodes; + } + + vector extract_nodes_reversed(const const_node_iptr& root) { + vector nodes; + extract_nodes_reversed(root, std::back_inserter(nodes)); + return nodes; + } +} diff --git a/sources/enduro2d/high/systems/render_system.cpp b/sources/enduro2d/high/systems/render_system.cpp index b6c313ee..1aa0f657 100644 --- a/sources/enduro2d/high/systems/render_system.cpp +++ b/sources/enduro2d/high/systems/render_system.cpp @@ -19,23 +19,6 @@ namespace using namespace e2d; using namespace e2d::render_system_impl; - template < typename F > - void for_each_by_nodes(const const_node_iptr& root, F&& f) { - static vector temp_nodes; - try { - if ( root ) { - root->extract_all_nodes(std::back_inserter(temp_nodes)); - for ( const const_node_iptr& node : temp_nodes ) { - f(node); - } - } - } catch (...) { - temp_nodes.clear(); - throw; - } - temp_nodes.clear(); - } - template < typename T, typename Comp, typename F > void for_each_by_sorted_components(ecs::registry& owner, Comp&& comp, F&& f) { static vector> temp_components; @@ -67,7 +50,7 @@ namespace const auto func = [&ctx](const ecs::const_entity& scn_e, const scene&) { const actor* scn_a = scn_e.find_component(); if ( scn_a && scn_a->node() ) { - for_each_by_nodes(scn_a->node(), [&ctx](const const_node_iptr& node){ + nodes::for_extracted_nodes(scn_a->node(), [&ctx](const const_node_iptr& node){ ctx.draw(node); }); }