registry/storage: ::insert supports all types of iterators

This commit is contained in:
Michele Caini
2020-03-21 00:49:11 +01:00
parent b888757092
commit 709fd34264
6 changed files with 28 additions and 24 deletions

2
TODO
View File

@@ -17,6 +17,8 @@
- get -> all, exclude -> none
Next:
* registry::assure: open addressing or whatever to get rid of static variables and avoid reindexing in worst cases
* meta, make it possible to reset nodes from meta types
* replace observer class with observer functions
* get(cmp, entity) -> void *, set(cmp, entity, void *)
* review multi component views to reduce instantiations once empty types are gone...

View File

@@ -71,9 +71,9 @@ class basic_registry {
}
}
template<typename It, typename Value>
void insert(basic_registry &owner, It first, It last, Value &&value) {
storage<entity_type, Component>::insert(first, last, std::forward<Value>(value));
template<typename It, typename... Args>
void insert(basic_registry &owner, It first, It last, Args &&... args) {
storage<entity_type, Component>::insert(first, last, std::forward<Args>(args)...);
if(!construction.empty()) {
while(first != last) { construction.publish(owner, *(first++)); }
@@ -648,14 +648,14 @@ public:
*
* @sa emplace
*
* @tparam It Type of input iterator.
* @tparam Component Type of component to create.
* @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.
* @param value An instance of the component to assign.
*/
template<typename It, typename Component>
void insert(It first, It last, const Component &value) {
template<typename Component, typename It>
void insert(It first, It last, const Component &value = {}) {
ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
assure<Component>().insert(*this, first, last, value);
}
@@ -664,7 +664,7 @@ public:
template<typename Component, typename It>
[[deprecated("use ::insert instead")]]
std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, void>
assign(It first, It last, const Component &value) {
assign(It first, It last, const Component &value = {}) {
return insert(std::move(first), std::move(last), value);
}
@@ -678,13 +678,14 @@ public:
* @tparam CIt 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 value An iterator to the first element of the range of components.
* @param from An iterator to the first element of the range of components.
* @param to An iterator past the last element of the range of components.
*/
template<typename Component, typename EIt, typename CIt>
void insert(EIt first, EIt last, CIt value) {
void insert(EIt first, EIt last, CIt from, CIt to) {
static_assert(std::is_constructible_v<Component, typename std::iterator_traits<CIt>::value_type>);
ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
assure<Component>().insert(*this, first, last, value);
assure<Component>().insert(*this, first, last, from, to);
}
/*! @copydoc insert */
@@ -692,7 +693,7 @@ public:
[[deprecated("use ::insert instead")]]
std::enable_if_t<std::is_same_v<typename std::iterator_traits<EIt>::value_type, entity_type>, void>
assign(EIt first, EIt last, CIt value) {
return insert<Component>(std::move(first), std::move(last), std::move(value));
return insert<Component>(std::move(first), std::move(last), value, value + std::distance(first, last));
}
/**

View File

@@ -351,7 +351,7 @@ public:
* @param value An instance of the object to construct.
*/
template<typename It>
void insert(It first, It last, const object_type &value) {
void insert(It first, It last, const object_type &value = {}) {
instances.insert(instances.end(), std::distance(first, last), value);
// entities go after components in case constructors throw
underlying_type::insert(first, last);
@@ -361,7 +361,7 @@ public:
template<typename It>
[[deprecated("use ::insert instead")]]
std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, void>
construct(It first, It last, const object_type &value) {
construct(It first, It last, const object_type &value = {}) {
insert(std::move(first), std::move(last), value);
}
@@ -375,11 +375,12 @@ public:
* @tparam CIt 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 value An iterator to the first element of the range of objects.
* @param from An iterator to the first element of the range of objects.
* @param to An iterator past the last element of the range of objects.
*/
template<typename EIt, typename CIt>
void insert(EIt first, EIt last, CIt value) {
instances.insert(instances.end(), value, value + std::distance(first, last));
void insert(EIt first, EIt last, CIt from, CIt to) {
instances.insert(instances.end(), from, to);
// entities go after components in case constructors throw
underlying_type::insert(first, last);
}
@@ -558,7 +559,7 @@ public:
* @param last An iterator past the last element of the range of entities.
*/
template<typename It>
void insert(It first, It last, const object_type &) {
void insert(It first, It last, const object_type & = {}) {
underlying_type::insert(first, last);
}
@@ -569,7 +570,7 @@ public:
template<typename It>
[[deprecated("use ::insert instead")]]
std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, void>
construct(It first, It last, const object_type &value) {
construct(It first, It last, const object_type &value = {}) {
insert(std::move(first), std::move(last), value);
}
};

View File

@@ -115,8 +115,8 @@ TEST(Benchmark, ConstructManyWithComponents) {
timer timer;
registry.create(entities.begin(), entities.end());
registry.assign(entities.begin(), entities.end(), position{});
registry.assign(entities.begin(), entities.end(), velocity{});
registry.assign<position>(entities.begin(), entities.end());
registry.assign<velocity>(entities.begin(), entities.end());
timer.elapsed();
}

View File

@@ -362,7 +362,7 @@ TEST(Registry, CreateManyEntitiesAtOnceWithListener) {
registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(listener);
registry.create(std::begin(entities), std::end(entities));
registry.assign(std::begin(entities), std::end(entities), 'a');
registry.assign(std::begin(entities), std::end(entities), empty_type{});
registry.assign<empty_type>(std::begin(entities), std::end(entities));
ASSERT_TRUE(registry.has<empty_type>(entities[0]));
ASSERT_EQ(registry.get<char>(entities[2]), 'a');
@@ -815,8 +815,8 @@ TEST(Registry, NestedGroups) {
entt::entity entities[10];
registry.create(std::begin(entities), std::end(entities));
registry.assign(std::begin(entities), std::end(entities), int{});
registry.assign(std::begin(entities), std::end(entities), char{});
registry.assign<int>(std::begin(entities), std::end(entities));
registry.assign<char>(std::begin(entities), std::end(entities));
const auto g1 = registry.group<int>(entt::get<char>, entt::exclude<double>);
ASSERT_TRUE(g1.sortable());

View File

@@ -111,7 +111,7 @@ TEST(Storage, BatchAddEmptyType) {
entities[0] = entt::entity{3};
entities[1] = entt::entity{42};
pool.construct(std::begin(entities), std::end(entities), {});
pool.construct(std::begin(entities), std::end(entities));
ASSERT_TRUE(pool.has(entities[0]));
ASSERT_TRUE(pool.has(entities[1]));