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

storage: batch construct by copy

Michele Caini 6 лет назад
Родитель
Сommit
b34fe3200c
3 измененных файлов с 48 добавлено и 4 удалено
  1. 1 1
      src/entt/entity/sparse_set.hpp
  2. 29 3
      src/entt/entity/storage.hpp
  3. 18 0
      test/entt/entity/storage.cpp

+ 1 - 1
src/entt/entity/sparse_set.hpp

@@ -411,7 +411,7 @@ public:
      * An assertion will abort the execution at runtime in debug mode if the
      * sparse set already contains the given entity.
      *
-     * @tparam It Type of forward iterator.
+     * @tparam It Type of input iterator.
      * @param first An iterator to the first element of the range of entities.
      * @param last An iterator past the last element of the range of entities.
      */

+ 29 - 3
src/entt/entity/storage.hpp

@@ -340,7 +340,7 @@ public:
      * An assertion will abort the execution at runtime in debug mode if the
      * storage already contains the given entity.
      *
-     * @tparam It Type of forward iterator.
+     * @tparam It Type of input iterator.
      * @param first An iterator to the first element of the range of entities.
      * @param last An iterator past the last element of the range of entities.
      */
@@ -348,7 +348,33 @@ public:
     std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, void>
     construct(It first, It last) {
         instances.resize(instances.size() + std::distance(first, last), object_type{});
-        // entity goes after component in case constructor throws
+        // entities go after components in case constructors throw
+        underlying_type::construct(first, last);
+    }
+
+    /**
+     * @brief Assigns one or more entities to a storage and assigns them the
+     * given objects.
+     *
+     * The object type must be at least copy assignable and copy insertable.
+     *
+     * @warning
+     * Attempting to assign an entity that already belongs to the storage
+     * results in undefined behavior.<br/>
+     * An assertion will abort the execution at runtime in debug mode if the
+     * storage already contains the given entity.
+     *
+     * @tparam It Type of input iterator.
+     * @tparam Other Type of input iterator.
+     * @param first An iterator to the first element of the range of entities.
+     * @param last An iterator past the last element of the range of entities.
+     * @param other An iterator to the first element of the range of objects.
+     */
+    template<typename It, typename Other>
+    std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, void>
+    construct(It first, It last, Other other) {
+        instances.insert(instances.cend(), other, other + std::distance(first, last));
+        // entities go after components in case constructors throw
         underlying_type::construct(first, last);
     }
 
@@ -669,7 +695,7 @@ public:
      * An assertion will abort the execution at runtime in debug mode if the
      * storage already contains the given entity.
      *
-     * @tparam It Type of forward iterator.
+     * @tparam It Type of input iterator.
      * @param first An iterator to the first element of the range of entities.
      * @param last An iterator past the last element of the range of entities.
      */

+ 18 - 0
test/entt/entity/storage.cpp

@@ -111,6 +111,24 @@ TEST(Storage, BatchAdd) {
     ASSERT_EQ(pool.get(entities[1]), 0);
 }
 
+TEST(Storage, BatchAddByCopy) {
+    entt::storage<entt::entity, int> pool;
+    entt::entity entities[2];
+    int values[2]{3, 7};
+
+    entities[0] = entt::entity{3};
+    entities[1] = entt::entity{42};
+    pool.construct(std::begin(entities), std::end(entities), std::begin(values));
+
+    ASSERT_TRUE(pool.has(entities[0]));
+    ASSERT_TRUE(pool.has(entities[1]));
+
+    ASSERT_FALSE(pool.empty());
+    ASSERT_EQ(pool.size(), 2u);
+    ASSERT_EQ(pool.get(entities[0]), 3);
+    ASSERT_EQ(pool.get(entities[1]), 7);
+}
+
 TEST(Storage, BatchAddEmptyType) {
     entt::storage<entt::entity, empty_type> pool;
     entt::entity entities[2];