Przeglądaj źródła

entity: fully remove the poly storage support

Michele Caini 4 lat temu
rodzic
commit
00e7ab1db8

+ 0 - 1
CMakeLists.txt

@@ -146,7 +146,6 @@ if(ENTT_INCLUDE_HEADERS)
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/helper.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/observer.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/organizer.hpp>
-            $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/poly_storage.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/registry.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/runtime_view.hpp>
             $<BUILD_INTERFACE:${EnTT_SOURCE_DIR}/src/entt/entity/snapshot.hpp>

+ 2 - 56
docs/md/entity.md

@@ -31,7 +31,6 @@
     * [In-place delete](#in-place-delete)
     * [Hierarchies and the like](#hierarchies-and-the-like)
   * [Making the most of range-destroy](#making-the-most-of-range-destroy)
-  * [Meet the runtime](#meet-the-runtime)
   * [Snapshot: complete vs continuous](#snapshot-complete-vs-continuous)
     * [Snapshot loader](#snapshot-loader)
     * [Continuous loader](#continuous-loader)
@@ -101,8 +100,8 @@ The library provides a default implementation for many things and a mixin model
 that allows users to completely replace or even just enrich the pool dedicated
 to one or more components.<br/>
 The built-in signal support is an example of that: defined as a mixin, it's
-easily disabled if not needed. Similarly, poly storage is another example of how
-everything is customizable down to the smallest detail.
+easily disabled if not needed. Similarly, the storage class has a specialization
+that shows how everything is customizable down to the smallest detail.
 
 ## Pay per use
 
@@ -1140,59 +1139,6 @@ to do the above even after writing millions of lines of code.<br/>
 However, it's good to know how to exploit the `destroy` function to get the best
 out of it.
 
-## Meet the runtime
-
-`EnTT` takes full advantage of what the language offers at compile-time.<br/>
-However, by combining these feature with a tool for static polymorphism, it's
-also possible to have opaque proxies to work with _type-less_ pools at runtime.
-
-These objects are returned by the `storage` member function, which accepts a
-`type_info` object as an argument rather than a compile-time type (the same
-returned by the `visit` member function):
-
-```cpp
-auto storage = registry.storage(info);
-```
-
-By default and to stay true with the philosophy of the library, the API of a
-proxy is minimal and doesn't allow users to do much.<br/>
-However, it's also completely customizable in a generic way and with the
-possibility of defining specific behaviors for given types.
-
-This section won't go into detail on how to define a poly storage to get all the
-possible functionalities out of it. `EnTT` already contains enough snippets to
-get inspiration from, both in the test suite and in the `example` folder.<br/>
-In short, users will have to define their own _concepts_ (see the `entt::poly`
-documentation for this) and register them via the `poly_storage_traits` class
-template, which has been designed as sfinae-friendly for the purpose.
-
-Once the concept that a poly storage must adhere to has been properly defined,
-copying an entity will be as easy as:
-
-```cpp
-registry.visit(entity, [&](const auto info) {
-    auto &&storage = registry.storage(info);
-    storage->emplace(registry, other, storage->get(entity));
-});
-```
-
-Where `other` is the entity to which the elements should be replicated.<br/>
-Similarly, copying entire pools between different registries can look like this:
-
-```cpp
-registry.visit([&](const auto info) {
-    registry.storage(info)->copy_to(other);
-});
-```
-
-Where this time `other` represents the destination registry.
-
-So, all in all, `EnTT` shifts the complexity to the one-time definition of a
-_concept_ that reflects the user's needs, and then leaves room for ease of use
-within the codebase.<br/>
-The possibility of extreme customization is the icing on the cake in this sense,
-allowing users to design this tool around their own requirements.
-
 ## Snapshot: complete vs continuous
 
 The `registry` class offers basic support to serialization.<br/>

+ 0 - 54
src/entt/entity/poly_storage.hpp

@@ -1,54 +0,0 @@
-#ifndef ENTT_ENTITY_POLY_STORAGE_HPP
-#define ENTT_ENTITY_POLY_STORAGE_HPP
-
-#include <cstddef>
-#include <tuple>
-#include "../core/type_info.hpp"
-#include "../core/type_traits.hpp"
-#include "../poly/poly.hpp"
-#include "fwd.hpp"
-
-namespace entt {
-
-/**
- * @brief Basic poly storage implementation.
- * @tparam Entity A valid entity type (see entt_traits for more details).
- */
-template<typename Entity>
-struct Storage: type_list<const type_info &() const ENTT_NOEXCEPT> {
-    /**
-     * @brief Concept definition.
-     * @tparam Base Opaque base class from which to inherit.
-     */
-    template<typename Base>
-    struct type: Base {
-        /**
-         * @brief Returns a type info for the contained objects.
-         * @return The type info for the contained objects.
-         */
-        const type_info &value_type() const ENTT_NOEXCEPT {
-            return poly_call<0>(*this);
-        }
-    };
-
-    /**
-     * @brief Concept implementation.
-     * @tparam Type Type for which to generate an implementation.
-     */
-    template<typename Type>
-    using impl = value_list<&type_id<typename Type::value_type>>;
-};
-
-/**
- * @brief Defines the poly storage type associate with a given entity type.
- * @tparam Entity A valid entity type (see entt_traits for more details).
- */
-template<typename Entity, typename = void>
-struct poly_storage_traits {
-    /*! @brief Poly storage type for the given entity type. */
-    using storage_type = poly<Storage<Entity>>;
-};
-
-} // namespace entt
-
-#endif

+ 23 - 45
src/entt/entity/registry.hpp

@@ -21,7 +21,6 @@
 #include "entity.hpp"
 #include "fwd.hpp"
 #include "group.hpp"
-#include "poly_storage.hpp"
 #include "runtime_view.hpp"
 #include "sparse_set.hpp"
 #include "storage.hpp"
@@ -43,15 +42,14 @@ namespace entt {
 template<typename Entity>
 class basic_registry {
     using entity_traits = entt_traits<Entity>;
-    using poly_storage_type = typename poly_storage_traits<Entity>::storage_type;
     using basic_common_type = basic_sparse_set<Entity>;
 
     template<typename Component>
     using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Component>>::storage_type, Component>;
 
     struct pool_data {
-        poly_storage_type poly;
         std::unique_ptr<basic_common_type> pool{};
+        const entt::type_info *info{};
     };
 
     template<typename...>
@@ -106,16 +104,15 @@ class basic_registry {
     template<typename Component>
     [[nodiscard]] storage_type<Component> *assure() const {
         static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Non-decayed types not allowed");
+        auto &&pdata = pools[type_id<Component>().hash()];
 
-        if(auto &&pdata = pools[type_id<Component>().hash()]; !pdata.pool) {
-            auto *cpool = new storage_type<Component>{};
-            pdata.pool.reset(cpool);
+        if(!pdata.pool) {
+            pdata.pool.reset(new storage_type<Component>{});
             pdata.pool->context(forward_as_any(const_cast<basic_registry &>(*this)));
-            pdata.poly.template emplace<storage_type<Component> &>(*static_cast<storage_type<Component> *>(pdata.pool.get()));
-            return cpool;
-        } else {
-            return static_cast<storage_type<Component> *>(pdata.pool.get());
+            pdata.info = &type_id<Component>();
         }
+
+        return static_cast<storage_type<Component> *>(pdata.pool.get());
     }
 
     template<typename Component>
@@ -151,8 +148,6 @@ public:
     using version_type = typename entity_traits::version_type;
     /*! @brief Unsigned integer type. */
     using size_type = std::size_t;
-    /*! @brief Poly storage type. */
-    using poly_storage = typename poly_storage_traits<Entity>::storage_type;
 
     /*! @brief Default constructor. */
     basic_registry() = default;
@@ -201,23 +196,6 @@ public:
         static_cast<void>(assure<Component>());
     }
 
-    /**
-     * @brief Returns a poly storage for a given type.
-     * @param info The type for which to return a poly storage.
-     * @return A valid poly storage if a pool for the given type exists, an
-     * empty and thus invalid element otherwise.
-     */
-    poly_storage &storage(const type_info &info) {
-        ENTT_ASSERT(pools[info.hash()].poly, "Storage not available");
-        return pools[info.hash()].poly;
-    }
-
-    /*! @copydoc storage */
-    const poly_storage &storage(const type_info &info) const {
-        ENTT_ASSERT(pools[info.hash()].poly, "Storage not available");
-        return pools[info.hash()].poly;
-    }
-
     /**
      * @brief Returns the number of existing components of the given type.
      * @tparam Component Type of component of which to return the size.
@@ -547,8 +525,8 @@ public:
     version_type destroy(const entity_type entity, const version_type version) {
         ENTT_ASSERT(valid(entity), "Invalid entity");
 
-        for(auto &&pdata: pools) {
-            pdata.second.pool->remove(entity);
+        for(auto &&curr: pools) {
+            curr.second.pool->remove(entity);
         }
 
         return release_entity(entity, version);
@@ -570,8 +548,8 @@ public:
                 destroy(*first, entity_traits::to_version(*first) + 1u);
             }
         } else {
-            for(auto &&pdata: pools) {
-                pdata.second.pool->remove(first, last);
+            for(auto &&curr: pools) {
+                curr.second.pool->remove(first, last);
             }
 
             release(first, last);
@@ -801,8 +779,8 @@ public:
     template<typename... Component>
     void compact() {
         if constexpr(sizeof...(Component) == 0) {
-            for(auto &&pdata: pools) {
-                pdata.second.pool->compact();
+            for(auto &&curr: pools) {
+                curr.second.pool->compact();
             }
         } else {
             (assure<Component>()->compact(), ...);
@@ -944,8 +922,8 @@ public:
     template<typename... Component>
     void clear() {
         if constexpr(sizeof...(Component) == 0) {
-            for(auto &&pdata: pools) {
-                pdata.second.pool->clear();
+            for(auto &&curr: pools) {
+                curr.second.pool->clear();
             }
 
             each([this](const auto entity) { release_entity(entity, entity_traits::to_version(entity) + 1u); });
@@ -993,7 +971,7 @@ public:
      */
     [[nodiscard]] bool orphan(const entity_type entity) const {
         ENTT_ASSERT(valid(entity), "Invalid entity");
-        return std::none_of(pools.cbegin(), pools.cend(), [entity](auto &&pdata) { return pdata.second.pool->contains(entity); });
+        return std::none_of(pools.cbegin(), pools.cend(), [entity](auto &&curr) { return curr.second.pool->contains(entity); });
     }
 
     /**
@@ -1173,12 +1151,12 @@ public:
         std::vector<const basic_common_type *> filter(std::distance(from, to));
 
         std::transform(first, last, component.begin(), [this](const auto ctype) {
-            const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.second.poly->value_type().hash() == ctype; });
+            const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&curr) { return curr.second.info->hash() == ctype; });
             return it == pools.cend() ? nullptr : it->second.pool.get();
         });
 
         std::transform(from, to, filter.begin(), [this](const auto ctype) {
-            const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.second.poly->value_type().hash() == ctype; });
+            const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&curr) { return curr.second.info->hash() == ctype; });
             return it == pools.cend() ? nullptr : it->second.pool.get();
         });
 
@@ -1448,9 +1426,9 @@ public:
      */
     template<typename Func>
     void visit(entity_type entity, Func func) const {
-        for(auto &&pdata: pools) {
-            if(pdata.second.pool->contains(entity)) {
-                func(pdata.second.poly->value_type());
+        for(auto &&curr: pools) {
+            if(curr.second.pool->contains(entity)) {
+                func(*curr.second.info);
             }
         }
     }
@@ -1473,8 +1451,8 @@ public:
      */
     template<typename Func>
     void visit(Func func) const {
-        for(auto &&pdata: pools) {
-            func(pdata.second.poly->value_type());
+        for(auto &&curr: pools) {
+            func(*curr.second.info);
         }
     }
 

+ 0 - 1
src/entt/entt.hpp

@@ -23,7 +23,6 @@
 #include "entity/helper.hpp"
 #include "entity/observer.hpp"
 #include "entity/organizer.hpp"
-#include "entity/poly_storage.hpp"
 #include "entity/registry.hpp"
 #include "entity/runtime_view.hpp"
 #include "entity/snapshot.hpp"

+ 0 - 1
test/CMakeLists.txt

@@ -188,7 +188,6 @@ SETUP_BASIC_TEST(group entt/entity/group.cpp)
 SETUP_BASIC_TEST(handle entt/entity/handle.cpp)
 SETUP_BASIC_TEST(helper entt/entity/helper.cpp)
 SETUP_BASIC_TEST(observer entt/entity/observer.cpp)
-SETUP_BASIC_TEST(poly_storage entt/entity/poly_storage.cpp)
 SETUP_BASIC_TEST(organizer entt/entity/organizer.cpp)
 SETUP_BASIC_TEST(registry entt/entity/registry.cpp)
 SETUP_BASIC_TEST(registry_no_eto entt/entity/registry_no_eto.cpp ENTT_NO_ETO)