Jelajahi Sumber

registry: added discard to free explicitly a pool

Michele Caini 6 tahun lalu
induk
melakukan
d9884917fb

+ 0 - 1
TODO

@@ -25,6 +25,5 @@
   - ::group improve, reduce code
 
 * Mission: get rid of named types
-  - add discard pool functionality (+ test)
   - update doc: dispatcher, emitter, registry, meta, across boundaries
   - review and suppress warnings, if any

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

@@ -147,7 +147,7 @@ class basic_registry {
     };
 
     struct pool_data {
-        ENTT_ID_TYPE id;
+        ENTT_ID_TYPE type_id;
         std::unique_ptr<sparse_set<Entity>> pool;
         void(* assure)(basic_registry &, const sparse_set<Entity> &);
         void(* remove)(sparse_set<Entity> &, basic_registry &, const Entity);
@@ -213,15 +213,15 @@ class basic_registry {
         static_assert(std::is_same_v<Component, std::decay_t<Component>>);
         static std::size_t index{pools.size()};
 
-        if(!(index < pools.size()) || pools[index].id != type_id_v<Component>) {
+        if(!(index < pools.size()) || pools[index].type_id != type_id_v<Component>) {
             index = std::find_if(pools.cbegin(), pools.cend(), [](auto &&cpool) {
-                return cpool.id == type_id_v<Component>;
+                return cpool.type_id == type_id_v<Component>;
             }) - pools.cbegin();
 
             if(index == pools.size()) {
                 auto &&pdata = pools.emplace_back();
 
-                pdata.id = type_id_v<Component>;
+                pdata.type_id = type_id_v<Component>;
                 pdata.pool = std::make_unique<pool_type<Component>>(std::forward<Args>(args)...);
 
                 pdata.remove = [](sparse_set<Entity> &cpool, basic_registry &owner, const Entity entt) {
@@ -273,10 +273,21 @@ public:
      */
     template<typename Component, typename... Args>
     void prepare(Args &&... args) {
-        ENTT_ASSERT(std::none_of(pools.cbegin(), pools.cend(), [](auto &&pdata) { return pdata.id == type_id_v<Component>; }));
+        ENTT_ASSERT(std::none_of(pools.cbegin(), pools.cend(), [](auto &&pdata) { return pdata.type_id == type_id_v<Component>; }));
         assure<Component>(std::forward<Args>(args)...);
     }
 
+    /**
+     * @brief Discards the pools for the given components.
+     * @tparam Component Types of components for which to discard the pools.
+     */
+    template<typename... Component>
+    void discard() {
+        pools.erase(std::remove_if(pools.begin(), pools.end(), [](auto &&pdata) {
+            return ((pdata.type_id == type_id_v<Component>) || ...);
+        }), pools.end());
+    }
+
     /**
      * @brief Returns the number of existing components of the given type.
      * @tparam Component Type of component of which to return the size.
@@ -1425,7 +1436,7 @@ public:
 
         std::transform(first, last, selected.begin(), [this](const auto ctype) {
             const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) {
-                return pdata.id == ctype;
+                return pdata.type_id == ctype;
             });
 
             return it == pools.cend() ? nullptr : it->pool.get();
@@ -1476,7 +1487,7 @@ public:
 
         if constexpr(sizeof...(Component) == 0) {
             for(size_type pos{}; pos < pools.size(); ++pos) {
-                if(const auto &pdata = pools[pos]; pdata.assure && ((pdata.id != type_id_v<Exclude>) && ...)) {
+                if(const auto &pdata = pools[pos]; pdata.assure && ((pdata.type_id != type_id_v<Exclude>) && ...)) {
                     pdata.assure(other, *pdata.pool);
                 }
             }
@@ -1529,7 +1540,7 @@ public:
     void stomp(const entity_type dst, const basic_registry &other, const entity_type src, exclude_t<Exclude...> = {}) {
         if constexpr(sizeof...(Component) == 0) {
             for(size_type pos{}; pos < other.pools.size(); ++pos) {
-                if(const auto &pdata = other.pools[pos]; pdata.stomp && ((pdata.id != type_id_v<Exclude>) && ...) && pdata.pool->has(src)) {
+                if(const auto &pdata = other.pools[pos]; pdata.stomp && ((pdata.type_id != type_id_v<Exclude>) && ...) && pdata.pool->has(src)) {
                     pdata.stomp(*this, dst, *pdata.pool, src);
                 }
             }

+ 2 - 2
src/entt/signal/dispatcher.hpp

@@ -99,8 +99,8 @@ class dispatcher {
 
 public:
     /**
-     * @brief Discards the pool for the given event.
-     * @tparam Event Type of event for which to discard the pool.
+     * @brief Discards the pools for the given events.
+     * @tparam Event Types of events for which to discard the pools.
      */
     template<typename... Event>
     void discard() {

+ 2 - 2
src/entt/signal/emitter.hpp

@@ -187,8 +187,8 @@ public:
     emitter & operator=(emitter &&) = default;
 
     /**
-     * @brief Discards the pool for the given event.
-     * @tparam Event Type of event for which to discard the pool.
+     * @brief Discards the pools for the given events.
+     * @tparam Event Types of events for which to discard the pools.
      */
     template<typename... Event>
     void discard() {

+ 6 - 6
test/lib/registry/lib.cpp

@@ -2,15 +2,15 @@
 #include <entt/entity/registry.hpp>
 #include "types.h"
 
-ENTT_API void update_position(int delta, entt::registry &registry) {
-    registry.view<position, velocity>().each([delta](auto &pos, auto &vel) {
-        pos.x += delta * vel.dx;
-        pos.y += delta * vel.dy;
+ENTT_API void update_position(entt::registry &registry) {
+    registry.view<position, velocity>().each([](auto &pos, auto &vel) {
+        pos.x += 16 * vel.dx;
+        pos.y += 16 * vel.dy;
     });
 }
 
-ENTT_API void assign_velocity(int vel, entt::registry &registry) {
+ENTT_API void assign_velocity(entt::registry &registry) {
     for(auto entity: registry.view<position>()) {
-        registry.assign<velocity>(entity, vel, vel);
+        registry.assign<velocity>(entity, 1., 1.);
     }
 }

+ 8 - 10
test/lib/registry/main.cpp

@@ -4,26 +4,24 @@
 #include <entt/entity/registry.hpp>
 #include "types.h"
 
-ENTT_API void update_position(int, entt::registry &);
-ENTT_API void assign_velocity(int, entt::registry &);
+ENTT_API void update_position(entt::registry &);
+ENTT_API void assign_velocity(entt::registry &);
 
 TEST(Lib, Registry) {
     entt::registry registry;
 
     for(auto i = 0; i < 3; ++i) {
         const auto entity = registry.create();
-        registry.assign<position>(entity, i, i+1);
+        registry.assign<position>(entity, i, i);
     }
 
-    assign_velocity(2, registry);
+    assign_velocity(registry);
+    update_position(registry);
 
-    ASSERT_EQ(registry.size<position>(), 3u);
-    ASSERT_EQ(registry.size<velocity>(), 3u);
-
-    update_position(1, registry);
+    ASSERT_EQ(registry.size<position>(), registry.size<velocity>());
 
     registry.view<position>().each([](auto entity, auto &position) {
-        ASSERT_EQ(position.x, entt::to_integral(entity) + 2);
-        ASSERT_EQ(position.y, entt::to_integral(entity) + 3);
+        ASSERT_EQ(position.x, entt::to_integral(entity) + 16);
+        ASSERT_EQ(position.y, entt::to_integral(entity) + 16);
     });
 }

+ 2 - 2
test/lib/registry/types.h

@@ -9,8 +9,8 @@ struct ENTT_API position {
 };
 
 struct ENTT_API velocity {
-    int dx;
-    int dy;
+    double dx;
+    double dy;
 };
 
 #endif // ENTT_LIB_REGISTRY_TYPES_H

+ 4 - 8
test/plugin/registry/main.cpp

@@ -10,23 +10,19 @@ TEST(Lib, Registry) {
 
     for(auto i = 0; i < 3; ++i) {
         const auto entity = registry.create();
-        registry.assign<position>(entity, i, i+1);
+        registry.assign<position>(entity, i, i);
     }
 
-    ASSERT_FALSE(registry.empty<position>());
-    ASSERT_TRUE(registry.empty<velocity>());
-
     cr_plugin ctx;
     ctx.userdata = &registry;
     cr_plugin_load(ctx, PLUGIN);
     cr_plugin_update(ctx);
 
-    ASSERT_FALSE(registry.empty<position>());
-    ASSERT_FALSE(registry.empty<velocity>());
+    ASSERT_EQ(registry.size<position>(), registry.size<velocity>());
 
     registry.view<position>().each([](auto entity, auto &position) {
-        ASSERT_EQ(position.x, entt::to_integral(entity) + 2);
-        ASSERT_EQ(position.y, entt::to_integral(entity) + 3);
+        ASSERT_EQ(position.x, entt::to_integral(entity) + 16);
+        ASSERT_EQ(position.y, entt::to_integral(entity) + 16);
     });
 
     cr_plugin_close(ctx);

+ 6 - 5
test/plugin/registry/plugin.cpp

@@ -7,21 +7,22 @@ CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {
     case CR_STEP:
         [ctx]() {
             auto *registry = static_cast<entt::registry *>(ctx->userdata);
-            registry->reset<velocity>();
 
             for(auto entity: registry->view<position>()) {
-                registry->assign<velocity>(entity, 1, 1);
+                registry->assign<velocity>(entity, 1., 1.);
             }
 
             registry->view<position, velocity>().each([](auto &pos, auto &vel) {
-                pos.x += 2 * vel.dx;
-                pos.y += 2 * vel.dy;
+                pos.x += 16 * vel.dx;
+                pos.y += 16 * vel.dy;
             });
         }();
         break;
+    case CR_CLOSE:
+        static_cast<entt::registry *>(ctx->userdata)->discard<velocity>();
+        break;
     case CR_LOAD:
     case CR_UNLOAD:
-    case CR_CLOSE:
         // nothing to do here, this is only a test.
         break;
     }

+ 2 - 2
test/plugin/registry/types.h

@@ -7,8 +7,8 @@ struct position {
 };
 
 struct velocity {
-    int dx;
-    int dy;
+    double dx;
+    double dy;
 };
 
 #endif // ENTT_PLUGIN_REGISTRY_TYPES_H