Przeglądaj źródła

view: setup placeholders on view packs - close #1224

Michele Caini 1 rok temu
rodzic
commit
6b95c614bb
2 zmienionych plików z 30 dodań i 3 usunięć
  1. 3 2
      src/entt/entity/view.hpp
  2. 27 1
      test/entt/entity/view.cpp

+ 3 - 2
src/entt/entity/view.hpp

@@ -52,7 +52,8 @@ template<typename Result, typename View, typename Other, std::size_t... GLhs, st
     Result elem{};
     // friend-initialization, avoid multiple calls to refresh
     elem.pools = {view.template storage<GLhs>()..., other.template storage<GRhs>()...};
-    elem.filter = {view.template storage<sizeof...(GLhs) + ELhs>()..., other.template storage<sizeof...(GRhs) + ERhs>()...};
+    auto filter_or_placeholder = [placeholder = elem.placeholder](auto *value) { return (value == nullptr) ? placeholder : value; };
+    elem.filter = {filter_or_placeholder(view.template storage<sizeof...(GLhs) + ELhs>())..., filter_or_placeholder(other.template storage<sizeof...(GRhs) + ERhs>())...};
     elem.refresh();
     return elem;
 }
@@ -255,7 +256,7 @@ class basic_common_view {
 protected:
     /*! @cond TURN_OFF_DOXYGEN */
     basic_common_view() noexcept {
-        for(size_type pos{}; pos < Exclude; ++pos) {
+        for(size_type pos{}, last = filter.size(); pos < last; ++pos) {
             filter[pos] = placeholder;
         }
     }

+ 27 - 1
test/entt/entity/view.cpp

@@ -1393,7 +1393,7 @@ TEST(MultiStorageView, Storage) {
 
 TEST(MultiStorageView, SwapStorage) {
     std::tuple<entt::storage<int>, entt::storage<char>, entt::storage<int>, entt::storage<char>> storage{};
-    entt::basic_view<entt::get_t<entt::storage<int>>, entt::exclude_t<const entt::storage<char>>> view;
+    entt::basic_view<entt::get_t<entt::storage<int>>, entt::exclude_t<const entt::storage<char>>> view{};
     const entt::entity entity{0};
 
     ASSERT_FALSE(view);
@@ -1583,3 +1583,29 @@ TEST(View, Pipe) {
     ASSERT_NE(pack32.storage<const int>(), nullptr);
     ASSERT_NE(pack32.storage<float>(), nullptr);
 }
+
+TEST(View, PipeWithPlaceholder) {
+    entt::storage<void> storage{};
+    const entt::entity entity{0};
+
+    const entt::basic_view view{storage};
+    entt::basic_view<entt::get_t<entt::storage<void>>, entt::exclude_t<entt::storage<int>>> other{};
+
+    other.storage(storage);
+
+    ASSERT_FALSE(view.contains(entity));
+    ASSERT_FALSE(other.contains(entity));
+
+    auto pack = view | other;
+
+    ASSERT_FALSE(pack.contains(entity));
+
+    storage.emplace(entity);
+
+    ASSERT_TRUE(view.contains(entity));
+    ASSERT_TRUE(other.contains(entity));
+
+    pack = view | other;
+
+    ASSERT_TRUE(pack.contains(entity));
+}