Просмотр исходного кода

registry no longer uses named types

Michele Caini 6 лет назад
Родитель
Сommit
c3b0fa6c93
2 измененных файлов с 40 добавлено и 82 удалено
  1. 1 3
      TODO
  2. 39 79
      src/entt/entity/registry.hpp

+ 1 - 3
TODO

@@ -42,9 +42,7 @@
 
 * Mission: get rid of named types
   - make it possible to use custom generators (eg for plugins)
-  - registry::ctx_variable can be removed
-  - dispatcher::wrapper_data can be removed
-  - emitter::handler_data can be removed
+  - registry::assure -> pool_type<T> &
   - registry::group improve, reduce code
   - Make the following parts work across boundaries (define proper macros):
     * dispatcher

+ 39 - 79
src/entt/entity/registry.hpp

@@ -157,7 +157,6 @@ class basic_registry {
         void(* assure)(basic_registry &, const sparse_set<Entity> &);
         void(* remove)(sparse_set<Entity> &, basic_registry &, const Entity);
         void(* stomp)(basic_registry &, const Entity, const sparse_set<Entity> &, const Entity);
-        ENTT_ID_TYPE runtime_type;
     };
 
     struct group_data {
@@ -168,19 +167,19 @@ class basic_registry {
         bool(* exclude)(const component) ENTT_NOEXCEPT;
     };
 
-    struct ctx_variable {
-        std::unique_ptr<void, void(*)(void *)> value;
-        ENTT_ID_TYPE runtime_type;
+    struct basic_variable {
+        virtual ~basic_variable() = default;
     };
 
-    template<typename Type, typename Family>
-    static ENTT_ID_TYPE runtime_type() ENTT_NOEXCEPT {
-        if constexpr(is_named_type_v<Type>) {
-            return named_type_traits_v<Type>;
-        } else {
-            return Family::template type<std::decay_t<Type>>;
-        }
-    }
+    template<typename Type>
+    struct variable_handler: basic_variable {
+        template<typename... Args>
+        variable_handler(Args &&... args)
+            : value{std::forward<Args>(args)...}
+        {}
+
+        Type value;
+    };
 
     auto generate() {
         Entity entt;
@@ -212,50 +211,30 @@ class basic_registry {
     template<typename Component, typename... Args>
     const pool_type<Component> * assure(Args &&... args) const {
         const auto ctype = to_integer(type<Component>());
-        pool_data *pdata = nullptr;
-
-        if constexpr(is_named_type_v<Component>) {
-            const auto it = std::find_if(pools.begin(), pools.end(), [ctype](const auto &candidate) {
-                return candidate.runtime_type == ctype;
-            });
-
-            pdata = (it == pools.cend() ? &pools.emplace_back() : &(*it));
-        } else {
-            if(!(ctype < pools.size())) {
-                pools.resize(ctype+1);
-            } else if(pools[ctype].pool && pools[ctype].runtime_type != ctype) {
-                pools.emplace_back();
-                std::swap(pools[ctype], pools.back());
-            }
-
-            pdata = &pools[ctype];
-        }
 
-        if constexpr(sizeof...(Args) != 0) {
-            ENTT_ASSERT(!pdata->pool || !pdata->pool->size());
-            pdata->pool.reset();
+        if(!(ctype < pools.size())) {
+            pools.resize(ctype+1);
         }
 
-        if(!pdata->pool) {
-            pdata->runtime_type = ctype;
-            pdata->pool = std::make_unique<pool_type<Component>>(std::forward<Args>(args)...);
+        if(!pools[ctype].pool) {
+            pools[ctype].pool = std::make_unique<pool_type<Component>>(std::forward<Args>(args)...);
 
-            pdata->remove = [](sparse_set<Entity> &cpool, basic_registry &owner, const Entity entt) {
+            pools[ctype].remove = [](sparse_set<Entity> &cpool, basic_registry &owner, const Entity entt) {
                 static_cast<pool_type<Component> &>(cpool).remove(owner, entt);
             };
 
             if constexpr(std::is_copy_constructible_v<std::decay_t<Component>>) {
-                pdata->assure = [](basic_registry &other, const sparse_set<Entity> &cpool) {
+                pools[ctype].assure = [](basic_registry &other, const sparse_set<Entity> &cpool) {
                     other.assure<Component>(static_cast<const pool_type<Component> &>(cpool));
                 };
 
-                pdata->stomp = [](basic_registry &other, const Entity dst, const sparse_set<Entity> &cpool, const Entity src) {
+                pools[ctype].stomp = [](basic_registry &other, const Entity dst, const sparse_set<Entity> &cpool, const Entity src) {
                     other.assign_or_replace<Component>(dst, static_cast<const pool_type<Component> &>(cpool).get(src));
                 };
             }
         }
 
-        return static_cast<pool_type<Component> *>(pdata->pool.get());
+        return static_cast<pool_type<Component> *>(pools[ctype].pool.get());
     }
 
     template<typename Component>
@@ -291,7 +270,7 @@ public:
      */
     template<typename Component>
     static component type() ENTT_NOEXCEPT {
-        return component{runtime_type<Component, component_family>()};
+        return component{component_family::template type<std::decay_t<Component>>};
     }
 
     /**
@@ -302,10 +281,7 @@ public:
      */
     template<typename Component, typename... Args>
     void prepare(Args &&... args) {
-        ENTT_ASSERT(std::none_of(pools.cbegin(), pools.cend(), [ctype = to_integer(type<Component>())](auto &&pdata) {
-            return pdata.pool && pdata.runtime_type == ctype;
-        }));
-
+        ENTT_ASSERT(to_integer(type<Component>()) < pools.size() || !pools[to_integer(type<Component>())].pool);
         [[maybe_unused]] auto *cpool = assure<Component>(std::forward<Args>(args)...);
         ENTT_ASSERT(cpool->size() == 0);
     }
@@ -1453,11 +1429,7 @@ public:
         std::vector<const sparse_set<Entity> *> selected(std::distance(first, last));
 
         std::transform(first, last, selected.begin(), [this](const component ctype) {
-            auto it = std::find_if(pools.begin(), pools.end(), [ctype = to_integer(ctype)](const auto &pdata) {
-                return pdata.pool && pdata.runtime_type == ctype;
-            });
-
-            return it != pools.cend() && it->pool ? it->pool.get() : nullptr;
+            return to_integer(ctype) < pools.size() ? pools[to_integer(ctype)].pool.get() : nullptr;
         });
 
         return { std::move(selected) };
@@ -1504,11 +1476,11 @@ public:
         other.entities = entities;
 
         if constexpr(sizeof...(Component) == 0) {
-            std::for_each(pools.cbegin(), pools.cend(), [&other](const auto &pdata) {
-                if(pdata.assure && ((pdata.runtime_type != to_integer(type<Exclude>())) && ...)) {
+            for(size_type pos{}; pos < pools.size(); ++pos) {
+                if(const auto &pdata = pools[pos]; pdata.assure && ((pos != to_integer(type<Exclude>())) && ...)) {
                     pdata.assure(other, *pdata.pool);
                 }
-            });
+            }
         } else {
             static_assert(sizeof...(Exclude) == 0 && std::conjunction_v<std::is_copy_constructible<Component>...>);
             (other.assure<Component>(*assure<Component>()), ...);
@@ -1557,11 +1529,11 @@ public:
     template<typename... Component, typename... Exclude>
     void stomp(const entity_type dst, const basic_registry &other, const entity_type src, exclude_t<Exclude...> = {}) {
         if constexpr(sizeof...(Component) == 0) {
-            std::for_each(other.pools.cbegin(), other.pools.cend(), [this, dst, src](const auto &pdata) {
-                if(pdata.stomp && ((pdata.runtime_type != to_integer(type<Exclude>())) && ...) && pdata.pool->has(src)) {
+            for(size_type pos{}; pos < other.pools.size(); ++pos) {
+                if(const auto &pdata = other.pools[pos]; pdata.stomp && ((pos != to_integer(type<Exclude>())) && ...) && pdata.pool->has(src)) {
                     pdata.stomp(*this, dst, *pdata.pool, src);
                 }
-            });
+            }
         } else {
             static_assert(sizeof...(Exclude) == 0 && std::conjunction_v<std::is_copy_constructible<Component>...>);
             (assign_or_replace<Component>(dst, other.template get<Component>(src)), ...);
@@ -1654,23 +1626,14 @@ public:
      */
     template<typename Type, typename... Args>
     Type & set(Args &&... args) {
-        const auto ctype = runtime_type<Type, context_family>();
-        auto it = std::find_if(vars.begin(), vars.end(), [ctype](const auto &candidate) {
-            return candidate.runtime_type == ctype;
-        });
-
-        if(it == vars.cend()) {
-            vars.push_back({
-                decltype(ctx_variable::value){new Type{std::forward<Args>(args)...}, [](void *ptr) { delete static_cast<Type *>(ptr); }},
-                ctype
-            });
+        const auto vtype = context_family::type<std::decay_t<Type>>;
 
-            it = std::prev(vars.end());
-        } else {
-            it->value.reset(new Type{std::forward<Args>(args)...});
+        if(!(vtype < vars.size())) {
+            vars.resize(vtype+1);
         }
 
-        return *static_cast<Type *>(it->value.get());
+        vars[vtype] = std::make_unique<variable_handler<Type>>(std::forward<Args>(args)...);
+        return static_cast<variable_handler<Type> &>(*vars[vtype]).value;
     }
 
     /**
@@ -1679,9 +1642,9 @@ public:
      */
     template<typename Type>
     void unset() {
-        vars.erase(std::remove_if(vars.begin(), vars.end(), [](auto &var) {
-            return var.runtime_type == runtime_type<Type, context_family>();
-        }), vars.end());
+        if(const auto vtype = context_family::template type<std::decay_t<Type>>; vtype < vars.size()) {
+            vars[vtype].reset();
+        }
     }
 
     /**
@@ -1709,11 +1672,8 @@ public:
      */
     template<typename Type>
     const Type * try_ctx() const {
-        const auto it = std::find_if(vars.begin(), vars.end(), [](const auto &var) {
-            return var.runtime_type == runtime_type<Type, context_family>();
-        });
-
-        return (it == vars.cend()) ? nullptr : static_cast<const Type *>(it->value.get());
+        const auto vtype = context_family::type<std::decay_t<Type>>;
+        return vtype < vars.size() && vars[vtype] ? &static_cast<variable_handler<Type> &>(*vars[vtype]).value : nullptr;
     }
 
     /*! @copydoc try_ctx */
@@ -1750,7 +1710,7 @@ public:
 private:
     mutable std::vector<pool_data> pools{};
     std::vector<group_data> groups{};
-    std::vector<ctx_variable> vars{};
+    std::vector<std::unique_ptr<basic_variable>> vars{};
     std::vector<entity_type> entities{};
     entity_type destroyed{null};
 };