diff --git a/ecs.hpp b/ecs.hpp index b5f048e..0b10a62 100644 --- a/ecs.hpp +++ b/ecs.hpp @@ -665,19 +665,43 @@ namespace ecs_hpp template < typename T > const T* find_component_impl_(const entity& ent) const noexcept; - template < typename... Ts, typename F > - void for_joined_components_impl_(F&& f); - template < typename T, typename... Ts, typename F, typename... Cs > - void for_joined_components_impl_(const entity& e, F&& f, Cs&&... cs); - template < typename F, typename... Cs > - void for_joined_components_impl_(const entity& e, F&& f, Cs&&... cs); + template < typename T, typename... Ts, typename F, std::size_t I, std::size_t... Is > + void for_joined_components_impl_(F&& f, std::index_sequence iseq); + + template < typename T, typename... Ts, typename F, std::size_t I, std::size_t... Is > + void for_joined_components_impl_(F&& f, std::index_sequence iseq) const; + + template < typename T + , typename... Ts + , typename F + , typename S + , typename... Ss + , typename... Cs > + void for_joined_components_impl_( + const entity& e, + const F& f, + detail::component_storage* s, + detail::component_storage*... ss, + Cs&... cs); + + template < typename T + , typename... Ts + , typename F + , typename S + , typename... Ss + , typename... Cs > + void for_joined_components_impl_( + const entity& e, + const F& f, + const detail::component_storage* s, + const detail::component_storage*... ss, + const Cs&... cs) const; - template < typename... Ts, typename F > - void for_joined_components_impl_(F&& f) const; - template < typename T, typename... Ts, typename F, typename... Cs > - void for_joined_components_impl_(const entity& e, F&& f, Cs&&... cs) const; template < typename F, typename... Cs > - void for_joined_components_impl_(const entity& e, F&& f, Cs&&... cs) const; + void for_joined_components_impl_(const entity& e, const F& f, Cs&... cs); + + template < typename F, typename... Cs > + void for_joined_components_impl_(const entity& e, const F& f, const Cs&... cs) const; private: entity_id last_entity_id_{0u}; std::vector free_entity_ids_; @@ -931,12 +955,16 @@ namespace ecs_hpp template < typename... Ts, typename F > void registry::for_joined_components(F&& f) { - for_joined_components_impl_(std::forward(f)); + for_joined_components_impl_( + std::forward(f), + std::make_index_sequence()); } template < typename... Ts, typename F > void registry::for_joined_components(F&& f) const { - for_joined_components_impl_(std::forward(f)); + for_joined_components_impl_( + std::forward(f), + std::make_index_sequence()); } template < typename T, typename... Args > @@ -1016,51 +1044,93 @@ namespace ecs_hpp : nullptr; } - template < typename... Ts, typename F > - void registry::for_joined_components_impl_(F&& f) { - for ( const auto id : entity_ids_ ) { - for_joined_components_impl_(entity(*this, id), std::forward(f)); - } + template < typename T, typename... Ts, typename F, std::size_t I, std::size_t... Is > + void registry::for_joined_components_impl_(F&& f, std::index_sequence iseq) { + (void)iseq; + for_each_component([ + this, + f = std::forward(f), + storages = std::make_tuple(find_storage_()...) + ](const entity& e, T& t) mutable { + for_joined_components_impl_( + e, + f, + std::get(storages)..., + t); + }); } - template < typename T, typename... Ts, typename F, typename... Cs > - void registry::for_joined_components_impl_(const entity& e, F&& f, Cs&&... cs) { - T* c = find_component_impl_(e); + template < typename T, typename... Ts, typename F, std::size_t I, std::size_t... Is > + void registry::for_joined_components_impl_(F&& f, std::index_sequence iseq) const { + (void)iseq; + for_each_component([ + this, + f = std::forward(f), + storages = std::make_tuple(find_storage_()...) + ](const entity& e, const T& t) mutable { + for_joined_components_impl_( + e, + f, + std::get(storages)..., + t); + }); + } + + template < typename T + , typename... Ts + , typename F + , typename S + , typename... Ss + , typename... Cs > + void registry::for_joined_components_impl_( + const entity& e, + const F& f, + detail::component_storage* s, + detail::component_storage*... ss, + Cs&... cs) + { + T* c = s->find(e.id()); if ( c ) { for_joined_components_impl_( e, - std::forward(f), - std::forward(cs)..., + f, + std::forward(ss)..., + cs..., + *c); + } + } + + template < typename T + , typename... Ts + , typename F + , typename S + , typename... Ss + , typename... Cs > + void registry::for_joined_components_impl_( + const entity& e, + const F& f, + const detail::component_storage* s, + const detail::component_storage*... ss, + const Cs&... cs) const + { + const T* c = s->find(e.id()); + if ( c ) { + for_joined_components_impl_( + e, + f, + std::forward(ss)..., + cs..., *c); } } template < typename F, typename... Cs > - void registry::for_joined_components_impl_(const entity& e, F&& f, Cs&&... cs) { - f(e, std::forward(cs)...); - } - - template < typename... Ts, typename F > - void registry::for_joined_components_impl_(F&& f) const { - for ( const auto id : entity_ids_ ) { - for_joined_components_impl_(entity(const_cast(*this), id), std::forward(f)); - } - } - - template < typename T, typename... Ts, typename F, typename... Cs > - void registry::for_joined_components_impl_(const entity& e, F&& f, Cs&&... cs) const { - const T* c = find_component_impl_(e); - if ( c ) { - for_joined_components_impl_( - e, - std::forward(f), - std::forward(cs)..., - *c); - } + void registry::for_joined_components_impl_(const entity& e, const F& f, Cs&... cs) { + f(e, cs...); } template < typename F, typename... Cs > - void registry::for_joined_components_impl_(const entity& e, F&& f, Cs&&... cs) const { - f(e, std::forward(cs)...); + void registry::for_joined_components_impl_(const entity& e, const F& f, const Cs&... cs) const { + f(e, cs...); } } diff --git a/ecs_tests.cpp b/ecs_tests.cpp index b3be859..d166053 100644 --- a/ecs_tests.cpp +++ b/ecs_tests.cpp @@ -530,7 +530,7 @@ TEST_CASE("registry") { public: void process(ecs::registry& owner) override { owner.for_joined_components([]( - ecs::entity e, position_c& p, const velocity_c& v) + ecs::entity, position_c& p, const velocity_c& v) { p.x += v.x; p.y += v.y;