Răsfoiți Sursa

registry: const ::storage<T>(...) returns a pointer to possibly null storage

Michele Caini 2 ani în urmă
părinte
comite
aa9ffb9eef

+ 9 - 8
src/entt/entity/helper.hpp

@@ -126,14 +126,15 @@ void invoke(Registry &reg, const typename Registry::entity_type entt) {
  */
 template<typename Registry, typename Component>
 typename Registry::entity_type to_entity(const Registry &reg, const Component &instance) {
-    const auto &storage = reg.template storage<Component>();
-    constexpr auto page_size = std::remove_const_t<std::remove_reference_t<decltype(storage)>>::traits_type::page_size;
-    const typename Registry::common_type &base = storage;
-    const auto *addr = std::addressof(instance);
-
-    for(auto it = base.rbegin(), last = base.rend(); it < last; it += page_size) {
-        if(const auto dist = (addr - std::addressof(storage.get(*it))); dist >= 0 && dist < static_cast<decltype(dist)>(page_size)) {
-            return *(it + dist);
+    if(const auto *storage = reg.template storage<Component>(); storage) {
+        constexpr auto page_size = std::remove_const_t<std::remove_pointer_t<decltype(storage)>>::traits_type::page_size;
+        const typename Registry::common_type &base = *storage;
+        const auto *addr = std::addressof(instance);
+
+        for(auto it = base.rbegin(), last = base.rend(); it < last; it += page_size) {
+            if(const auto dist = (addr - std::addressof(storage->get(*it))); dist >= 0 && dist < static_cast<decltype(dist)>(page_size)) {
+                return *(it + dist);
+            }
         }
     }
 

+ 3 - 8
src/entt/entity/registry.hpp

@@ -437,19 +437,14 @@ public:
     }
 
     /**
-     * @brief Returns the storage for a given component type.
-     *
-     * @warning
-     * If a storage for the given component doesn't exist yet, a temporary
-     * placeholder is returned instead.
-     *
+     * @brief Returns the storage for a given component type, if any.
      * @tparam Type Type of component of which to return the storage.
      * @param id Optional name used to map the storage within the registry.
      * @return The storage for the given component type.
      */
     template<typename Type>
-    const storage_for_type<Type> &storage(const id_type id = type_hash<Type>::value()) const {
-        return *assure<Type>(id);
+    const storage_for_type<Type> *storage(const id_type id = type_hash<Type>::value()) const {
+        return assure<Type>(id);
     }
 
     /**

+ 10 - 9
src/entt/entity/snapshot.hpp

@@ -33,23 +33,23 @@ class basic_snapshot {
 
     template<typename Component, typename Archive, typename It>
     void get(Archive &archive, std::size_t sz, It first, It last) const {
-        const auto &storage = reg->template storage<Component>();
+        const auto view = reg->template view<Component>();
         archive(static_cast<typename traits_type::entity_type>(sz));
 
         for(auto it = first; it != last; ++it) {
-            if(storage.contains(*it)) {
-                std::apply(archive, std::tuple_cat(std::make_tuple(*it), storage.get_as_tuple(*it)));
+            if(view.contains(*it)) {
+                std::apply(archive, std::tuple_cat(std::make_tuple(*it), view.get(*it)));
             }
         }
     }
 
     template<typename... Component, typename Archive, typename It, std::size_t... Index>
     void component(Archive &archive, It first, It last, std::index_sequence<Index...>) const {
-        auto storage{std::forward_as_tuple(reg->template storage<Component>()...)};
+        const auto view{std::make_tuple(reg->template view<Component>()...)};
         std::array<std::size_t, sizeof...(Index)> size{};
 
         for(auto it = first; it != last; ++it) {
-            ((std::get<Index>(storage).contains(*it) ? ++size[Index] : 0u), ...);
+            ((std::get<Index>(view).contains(*it) ? ++size[Index] : 0u), ...);
         }
 
         (get<Component>(archive, size[Index], first, last), ...);
@@ -86,12 +86,13 @@ public:
      */
     template<typename Archive>
     const basic_snapshot &entities(Archive &archive) const {
-        const auto &storage = reg->template storage<entity_type>();
+        const auto *storage = reg->template storage<entity_type>();
+        ENTT_ASSERT(storage, "No entity storage available");
 
-        archive(static_cast<typename traits_type::entity_type>(storage.size()));
-        archive(static_cast<typename traits_type::entity_type>(storage.in_use()));
+        archive(static_cast<typename traits_type::entity_type>(storage->size()));
+        archive(static_cast<typename traits_type::entity_type>(storage->in_use()));
 
-        for(auto first = storage.data(), last = first + storage.size(); first != last; ++first) {
+        for(auto first = storage->data(), last = first + storage->size(); first != last; ++first) {
             archive(*first);
         }
 

+ 2 - 2
test/entt/entity/registry.cpp

@@ -2087,7 +2087,7 @@ TEST(Registry, RuntimePools) {
     const auto entity = registry.create();
 
     static_assert(std::is_same_v<decltype(registry.storage<empty_type>()), entt::storage_type_t<empty_type> &>);
-    static_assert(std::is_same_v<decltype(std::as_const(registry).storage<empty_type>()), const entt::storage_type_t<empty_type> &>);
+    static_assert(std::is_same_v<decltype(std::as_const(registry).storage<empty_type>()), const entt::storage_type_t<empty_type> *>);
 
     static_assert(std::is_same_v<decltype(registry.storage("other"_hs)), entt::storage_type_t<empty_type>::base_type *>);
     static_assert(std::is_same_v<decltype(std::as_const(registry).storage("other"_hs)), const entt::storage_type_t<empty_type>::base_type *>);
@@ -2096,7 +2096,7 @@ TEST(Registry, RuntimePools) {
     ASSERT_EQ(std::as_const(registry).storage("rehto"_hs), nullptr);
 
     ASSERT_EQ(&registry.storage<empty_type>("other"_hs), &storage);
-    ASSERT_NE(&std::as_const(registry).storage<empty_type>(), &storage);
+    ASSERT_NE(std::as_const(registry).storage<empty_type>(), &storage);
 
     ASSERT_FALSE(registry.any_of<empty_type>(entity));
     ASSERT_FALSE(storage.contains(entity));