storage/registry: batch add default-constructs the component

This commit is contained in:
Michele Caini
2020-01-15 23:02:16 +01:00
parent b1e54bfd86
commit e7d4077065
3 changed files with 16 additions and 54 deletions

View File

@@ -73,10 +73,10 @@ class basic_registry {
return this->get(entt);
}
template<typename It, typename... Args>
template<typename It>
std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, Entity>, typename storage<Entity, Component>::reverse_iterator_type>
assign(basic_registry &owner, It first, It last, Args &&... args) {
auto it = this->construct(first, last, std::forward<Args>(args)...);
assign(basic_registry &owner, It first, It last) {
auto it = this->construct(first, last);
std::for_each(first, last, [this, &owner](const auto entt) { construction.publish(entt, owner); });
return it;
}
@@ -633,21 +633,21 @@ public:
/**
* @brief Assigns each entity in a range the given component.
*
* The component type must be at least move and default insertable.
*
* @sa assign
*
* @tparam Component Type of component to create.
* @tparam It Type of input iterator.
* @tparam Args Types of arguments to use to construct the components.
* @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 args Parameters to use to initialize the components.
* @return An iterator to the list of components just created.
*/
template<typename Component, typename It, typename... Args>
template<typename Component, typename It>
std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, typename pool_handler<Component>::reverse_iterator_type>
assign(It first, It last, Args &&... args) {
assign(It first, It last) {
ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
return assure<Component>().assign(*this, first, last, std::forward<Args>(args)...);
return assure<Component>().assign(*this, first, last);
}
/**

View File

@@ -332,10 +332,9 @@ public:
/**
* @brief Assigns one or more entities to a storage and default constructs
* or copy constructs their objects.
* their objects.
*
* The object type must be at least move and default insertable if no
* arguments are provided, move and copy insertable otherwise.
* The object type must be at least move and default insertable.
*
* @warning
* Attempting to assign an entity that already belongs to the storage
@@ -344,17 +343,15 @@ public:
* storage already contains the given entity.
*
* @tparam It Type of forward iterator.
* @tparam Args Types of arguments to use to construct the object.
* @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 args Parameters to use to construct an object for the entities.
* @return An iterator to the list of instances just created and sorted the
* same of the entities.
*/
template<typename It, typename... Args>
template<typename It>
std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, reverse_iterator_type>
construct(It first, It last, Args &&... args) {
instances.insert(instances.end(), std::distance(first, last), object_type{std::forward<Args>(args)...});
construct(It first, It last) {
instances.insert(instances.end(), std::distance(first, last), object_type{});
// entity goes after component in case constructor throws
underlying_type::construct(first, last);
return std::make_reverse_iterator(begin() + std::distance(first, last));
@@ -656,8 +653,6 @@ public:
/**
* @brief Assigns an entity to a storage and constructs its object.
*
* The object type must be at least copy constructible.
*
* @warning
* Attempting to use an entity that already belongs to the storage results
* in undefined behavior.<br/>
@@ -666,21 +661,15 @@ public:
*
* @tparam Args Types of arguments to use to construct the object.
* @param entt A valid entity identifier.
* @param args Parameters to use to construct an object for the entity.
*/
template<typename... Args>
void construct(const entity_type entt, Args &&... args) {
[[maybe_unused]] object_type instance{std::forward<Args>(args)...};
// entity goes after component in case constructor throws
void construct(const entity_type entt, Args &&...) {
underlying_type::construct(entt);
}
/**
* @brief Assigns one or more entities to a storage.
*
* The object type must be at least default constructible if no arguments
* are provided.
*
* @warning
* Attempting to assign an entity that already belongs to the storage
* results in undefined behavior.<br/>
@@ -688,18 +677,14 @@ public:
* storage already contains the given entity.
*
* @tparam It Type of forward iterator.
* @tparam Args Types of arguments to use to construct the object.
* @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 args Parameters to use to construct an object for the entities.
* @return An iterator to the list of instances just created and sorted the
* same of the entities.
*/
template<typename It, typename... Args>
template<typename It>
std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, reverse_iterator_type>
construct(It first, It last, Args &&... args) {
[[maybe_unused]] object_type instance{std::forward<Args>(args)...};
// entity goes after component in case constructor throws
construct(It first, It last) {
underlying_type::construct(first, last);
return std::make_reverse_iterator(begin() + std::distance(first, last));
}

View File

@@ -117,29 +117,6 @@ TEST(Storage, BatchAdd) {
ASSERT_EQ(pool.get(entities[1]), 2);
}
TEST(Storage, BatchAddByCopy) {
entt::storage<entt::entity, int> pool;
entt::entity entities[2];
entities[0] = entt::entity{3};
entities[1] = entt::entity{42};
auto it = pool.construct(std::begin(entities), std::end(entities), 3);
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]), 3);
it[0] = 1;
it[1] = 2;
ASSERT_EQ(pool.get(entities[0]), 1);
ASSERT_EQ(pool.get(entities[1]), 2);
}
TEST(Storage, BatchAddEmptyType) {
entt::storage<entt::entity, empty_type> pool;
entt::entity entities[2];