Browse Source

view: return a const reference to the leading storage

Michele Caini 4 years ago
parent
commit
0ab71bc2e7
2 changed files with 69 additions and 0 deletions
  1. 20 0
      src/entt/entity/view.hpp
  2. 49 0
      test/entt/entity/view.cpp

+ 20 - 0
src/entt/entity/view.hpp

@@ -345,6 +345,8 @@ public:
     using reverse_iterator = internal::view_iterator<basic_common_type, typename basic_common_type::reverse_iterator, sizeof...(Component) - 1u, sizeof...(Exclude)>;
     using reverse_iterator = internal::view_iterator<basic_common_type, typename basic_common_type::reverse_iterator, sizeof...(Component) - 1u, sizeof...(Exclude)>;
     /*! @brief Iterable view type. */
     /*! @brief Iterable view type. */
     using iterable_view = iterable;
     using iterable_view = iterable;
+    /*! @brief Common type among all storage types. */
+    using common_type = basic_common_type;
 
 
     /**
     /**
      * @brief Storage type associated with a given component.
      * @brief Storage type associated with a given component.
@@ -381,6 +383,14 @@ public:
         return other;
         return other;
     }
     }
 
 
+    /**
+     * @brief Returns the leading storage of a view.
+     * @return The leading storage of the view.
+     */
+    const common_type &handle() const ENTT_NOEXCEPT {
+        return *view;
+    }
+
     /**
     /**
      * @brief Estimates the number of entities iterated by the view.
      * @brief Estimates the number of entities iterated by the view.
      * @return Estimated number of entities iterated by the view.
      * @return Estimated number of entities iterated by the view.
@@ -691,6 +701,8 @@ public:
     using reverse_iterator = typename basic_common_type::reverse_iterator;
     using reverse_iterator = typename basic_common_type::reverse_iterator;
     /*! @brief Iterable view type. */
     /*! @brief Iterable view type. */
     using iterable_view = internal::iterable_storage<Entity, Component>;
     using iterable_view = internal::iterable_storage<Entity, Component>;
+    /*! @brief Common type among all storage types. */
+    using common_type = basic_common_type;
     /*! @brief Storage type associated with the view component. */
     /*! @brief Storage type associated with the view component. */
     using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Component>>::storage_type, Component>;
     using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Component>>::storage_type, Component>;
 
 
@@ -707,6 +719,14 @@ public:
         : pools{&ref},
         : pools{&ref},
           filter{} {}
           filter{} {}
 
 
+    /**
+     * @brief Returns the leading storage of a view.
+     * @return The leading storage of the view.
+     */
+    const common_type &handle() const ENTT_NOEXCEPT {
+        return *std::get<0>(pools);
+    }
+
     /**
     /**
      * @brief Returns the number of entities that have the given component.
      * @brief Returns the number of entities that have the given component.
      * @return Number of entities that have the given component.
      * @return Number of entities that have the given component.

+ 49 - 0
test/entt/entity/view.cpp

@@ -74,6 +74,24 @@ TEST(SingleComponentView, Functionalities) {
     ASSERT_FALSE(invalid);
     ASSERT_FALSE(invalid);
 }
 }
 
 
+TEST(SingleComponentView, Handle) {
+    entt::registry registry;
+    const auto entity = registry.create();
+
+    auto view = registry.view<int>();
+    auto &&handle = view.handle();
+
+    ASSERT_TRUE(handle.empty());
+    ASSERT_FALSE(handle.contains(entity));
+    ASSERT_EQ(&handle, &view.handle());
+
+    registry.emplace<int>(entity);
+
+    ASSERT_FALSE(handle.empty());
+    ASSERT_TRUE(handle.contains(entity));
+    ASSERT_EQ(&handle, &view.handle());
+}
+
 TEST(SingleComponentView, RawData) {
 TEST(SingleComponentView, RawData) {
     entt::registry registry;
     entt::registry registry;
     auto view = registry.view<int>();
     auto view = registry.view<int>();
@@ -501,6 +519,37 @@ TEST(MultiComponentView, Functionalities) {
     ASSERT_FALSE(invalid);
     ASSERT_FALSE(invalid);
 }
 }
 
 
+TEST(MultiComponentView, Handle) {
+    entt::registry registry;
+    const auto entity = registry.create();
+
+    auto view = registry.view<int, char>();
+    auto &&handle = view.handle();
+
+    ASSERT_TRUE(handle.empty());
+    ASSERT_FALSE(handle.contains(entity));
+    ASSERT_EQ(&handle, &view.handle());
+
+    registry.emplace<int>(entity);
+
+    ASSERT_FALSE(handle.empty());
+    ASSERT_TRUE(handle.contains(entity));
+    ASSERT_EQ(&handle, &view.handle());
+
+    view = registry.view<int, char>();
+    auto &&other = view.handle();
+
+    ASSERT_TRUE(other.empty());
+    ASSERT_FALSE(other.contains(entity));
+    ASSERT_EQ(&other, &view.handle());
+    ASSERT_NE(&handle, &other);
+
+    view = view.use<int>();
+
+    ASSERT_NE(&other, &view.handle());
+    ASSERT_EQ(&handle, &view.handle());
+}
+
 TEST(MultiComponentView, LazyTypesFromConstRegistry) {
 TEST(MultiComponentView, LazyTypesFromConstRegistry) {
     entt::registry registry{};
     entt::registry registry{};
     auto view = std::as_const(registry).view<const empty_type, const int>();
     auto view = std::as_const(registry).view<const empty_type, const int>();