Quellcode durchsuchen

view_pack: ::each allows to remove the entity from the callback

Michele Caini vor 5 Jahren
Ursprung
Commit
10da82a331
2 geänderte Dateien mit 21 neuen und 4 gelöschten Zeilen
  1. 11 4
      src/entt/entity/view_pack.hpp
  2. 10 0
      test/entt/entity/view_pack.cpp

+ 11 - 4
src/entt/entity/view_pack.hpp

@@ -5,6 +5,7 @@
 #include <tuple>
 #include <type_traits>
 #include <utility>
+#include "../core/type_traits.hpp"
 #include "fwd.hpp"
 #include "utility.hpp"
 
@@ -18,8 +19,9 @@ namespace entt {
  * The view pack allows users to combine multiple views into a single iterable
  * object, while also giving them full control over which view should lead the
  * iteration.<br/>
- * Its intended primary use is for custom storage and views, but it can also be
- * very convenient in everyday use.
+ * This class returns all and only the entities present in all views. Its
+ * intended primary use is for custom storage and views, but it can also be very
+ * convenient in everyday use.
  *
  * @tparam View Type of the leading view of the pack.
  * @tparam Other Types of all other views of the pack.
@@ -235,11 +237,16 @@ public:
      */
     template<typename Func>
     void each(Func func) const {
-        for(auto value: std::get<View>(pack).each()) {
+        for(const auto value: std::get<View>(pack).each()) {
             const auto entity = std::get<0>(value);
 
             if((std::get<Other>(pack).contains(entity) && ...)) {
-                std::apply(func, std::tuple_cat(value, std::get<Other>(pack).get(entity)...));
+                if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(value, std::get<Other>(pack).get(entity)...))>) {
+                    std::apply(func, std::tuple_cat(value, std::get<Other>(pack).get(entity)...));
+                } else {
+                    const auto args = std::apply([](const auto entity, auto &&... component) { return std::forward_as_tuple(component...); }, value);
+                    std::apply(func, std::tuple_cat(args, std::get<Other>(pack).get(entity)...));
+                }
             }
         }
     }

+ 10 - 0
test/entt/entity/view_pack.cpp

@@ -70,6 +70,11 @@ TEST(ViewPack, ShortestPool) {
         ASSERT_EQ(&iv, registry.try_get<int>(entt));
     });
 
+    pack.each([](auto &&cv, auto &&iv) {
+        static_assert(std::is_same_v<decltype(cv), char &>);
+        static_assert(std::is_same_v<decltype(iv), const int &>);
+    });
+
     auto eit = pack.each().begin();
 
     ASSERT_EQ(std::get<0>(*eit++), entities[1u]);
@@ -130,6 +135,11 @@ TEST(ViewPack, LongestPool) {
         ASSERT_EQ(&cv, registry.try_get<char>(entt));
     });
 
+    pack.each([](auto &&iv, auto &&cv) {
+        static_assert(std::is_same_v<decltype(iv), int &>);
+        static_assert(std::is_same_v<decltype(cv), const char &>);
+    });
+
     auto eit = pack.each().begin();
 
     ASSERT_EQ(std::get<0>(*eit++), entities[2u]);